Merge "ResourceLoaderLessVarFileModule: Add parameter 'lessMessages'"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Wed, 30 May 2018 12:06:17 +0000 (12:06 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Wed, 30 May 2018 12:06:17 +0000 (12:06 +0000)
912 files changed:
.phpcs.xml
Gruntfile.js
INSTALL
README [deleted file]
README.md [new file with mode: 0644]
README.mediawiki [deleted symlink]
RELEASE-NOTES-1.31
RELEASE-NOTES-1.32
autoload.php
composer.json
docs/extension.schema.v1.json
docs/extension.schema.v2.json
docs/hooks.txt
docs/skin.txt
includes/AjaxDispatcher.php
includes/AutoLoader.php
includes/Block.php
includes/ContentSecurityPolicy.php [new file with mode: 0644]
includes/DefaultSettings.php
includes/Defines.php
includes/EditPage.php
includes/GlobalFunctions.php
includes/Hooks.php
includes/Html.php
includes/Linker.php
includes/MediaWiki.php
includes/OutputPage.php
includes/PHPVersionCheck.php
includes/Preferences.php
includes/Setup.php
includes/Title.php
includes/WebRequest.php
includes/Xml.php
includes/actions/FormAction.php
includes/actions/InfoAction.php
includes/actions/RawAction.php
includes/actions/WatchAction.php
includes/api/ApiBase.php
includes/api/ApiCSPReport.php
includes/api/ApiHelp.php
includes/api/ApiMain.php
includes/api/ApiMessage.php
includes/api/ApiMessageTrait.php [new file with mode: 0644]
includes/api/ApiParamInfo.php
includes/api/ApiQuery.php
includes/api/ApiQueryRecentChanges.php
includes/api/ApiQueryUserContribs.php [new file with mode: 0644]
includes/api/ApiQueryUserContributions.php [deleted file]
includes/api/ApiRawMessage.php [new file with mode: 0644]
includes/api/ApiUsageException.php
includes/api/IApiMessage.php [new file with mode: 0644]
includes/api/UsageException.php [new file with mode: 0644]
includes/api/i18n/ar.json
includes/api/i18n/cs.json
includes/api/i18n/de.json
includes/api/i18n/en.json
includes/api/i18n/es.json
includes/api/i18n/fr.json
includes/api/i18n/gl.json
includes/api/i18n/he.json
includes/api/i18n/it.json
includes/api/i18n/ko.json
includes/api/i18n/pl.json
includes/api/i18n/pt-br.json
includes/api/i18n/pt.json
includes/api/i18n/qqq.json
includes/api/i18n/ru.json
includes/api/i18n/uk.json
includes/api/i18n/zh-hans.json
includes/api/i18n/zh-hant.json
includes/auth/Throttler.php
includes/cache/CacheHelper.php
includes/changes/RCCacheEntryFactory.php
includes/collation/Collation.php
includes/collation/CollationFa.php [deleted file]
includes/collation/IcuCollation.php
includes/compat/Timestamp.php [deleted file]
includes/compat/normal/UtfNormal.php
includes/compat/normal/UtfNormalDefines.php [deleted file]
includes/compat/normal/UtfNormalUtil.php [deleted file]
includes/composer/ComposerHookHandler.php
includes/composer/ComposerPackageModifier.php
includes/composer/ComposerVersionNormalizer.php
includes/dao/DBAccessBase.php
includes/debug/MWDebug.php
includes/deferred/LinksUpdate.php
includes/filerepo/file/LocalFile.php
includes/htmlform/HTMLForm.php
includes/htmlform/HTMLFormField.php
includes/htmlform/OOUIHTMLForm.php
includes/http/CurlHttpRequest.php
includes/http/Http.php
includes/http/HttpRequestFactory.php
includes/http/PhpHttpRequest.php
includes/import/ImportableUploadRevisionImporter.php
includes/installer/DatabaseUpdater.php
includes/installer/Installer.php
includes/installer/MssqlUpdater.php
includes/installer/MysqlUpdater.php
includes/installer/OracleUpdater.php
includes/installer/PostgresUpdater.php
includes/installer/SqliteUpdater.php
includes/installer/WebInstallerLanguage.php
includes/installer/WebInstallerName.php
includes/installer/i18n/ar.json
includes/installer/i18n/ast.json
includes/installer/i18n/ba.json
includes/installer/i18n/be-tarask.json
includes/installer/i18n/bg.json
includes/installer/i18n/bn.json
includes/installer/i18n/br.json
includes/installer/i18n/bs.json
includes/installer/i18n/ca.json
includes/installer/i18n/ckb.json
includes/installer/i18n/cs.json
includes/installer/i18n/csb.json
includes/installer/i18n/de.json
includes/installer/i18n/el.json
includes/installer/i18n/en.json
includes/installer/i18n/eo.json
includes/installer/i18n/es.json
includes/installer/i18n/eu.json
includes/installer/i18n/fa.json
includes/installer/i18n/fi.json
includes/installer/i18n/fr.json
includes/installer/i18n/frp.json
includes/installer/i18n/gl.json
includes/installer/i18n/gsw.json
includes/installer/i18n/he.json
includes/installer/i18n/hi.json
includes/installer/i18n/hrx.json
includes/installer/i18n/hsb.json
includes/installer/i18n/hu.json
includes/installer/i18n/ia.json
includes/installer/i18n/id.json
includes/installer/i18n/is.json
includes/installer/i18n/it.json
includes/installer/i18n/ja.json
includes/installer/i18n/ka.json
includes/installer/i18n/ko.json
includes/installer/i18n/ksh.json
includes/installer/i18n/ku-latn.json
includes/installer/i18n/lb.json
includes/installer/i18n/lij.json
includes/installer/i18n/lt.json
includes/installer/i18n/lv.json
includes/installer/i18n/mk.json
includes/installer/i18n/ml.json
includes/installer/i18n/mr.json
includes/installer/i18n/ms.json
includes/installer/i18n/mzn.json
includes/installer/i18n/nap.json
includes/installer/i18n/nb.json
includes/installer/i18n/nl-informal.json
includes/installer/i18n/nl.json
includes/installer/i18n/oc.json
includes/installer/i18n/pl.json
includes/installer/i18n/pms.json
includes/installer/i18n/ps.json
includes/installer/i18n/pt-br.json
includes/installer/i18n/pt.json
includes/installer/i18n/ro.json
includes/installer/i18n/ru.json
includes/installer/i18n/sco.json
includes/installer/i18n/sl.json
includes/installer/i18n/sr-ec.json
includes/installer/i18n/sv.json
includes/installer/i18n/te.json
includes/installer/i18n/th.json
includes/installer/i18n/tl.json
includes/installer/i18n/tr.json
includes/installer/i18n/tt-cyrl.json
includes/installer/i18n/uk.json
includes/installer/i18n/vi.json
includes/installer/i18n/war.json
includes/installer/i18n/yi.json
includes/installer/i18n/zh-hans.json
includes/installer/i18n/zh-hant.json
includes/interwiki/InterwikiLookupAdapter.php
includes/jobqueue/Job.php
includes/jobqueue/JobQueue.php
includes/jobqueue/JobQueueDB.php
includes/libs/CSSMin.php
includes/libs/CryptHKDF.php
includes/libs/GenericArrayObject.php
includes/libs/IP.php
includes/libs/JavaScriptMinifier.php
includes/libs/MultiHttpClient.php
includes/libs/ReplacementArray.php
includes/libs/filebackend/FSFileBackend.php
includes/libs/filebackend/SwiftFileBackend.php
includes/libs/objectcache/BagOStuff.php
includes/libs/rdbms/ChronologyProtector.php
includes/libs/rdbms/connectionmanager/ConnectionManager.php
includes/libs/rdbms/database/DBConnRef.php
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/database/DatabaseMssql.php
includes/libs/rdbms/database/DatabaseMysqlBase.php
includes/libs/rdbms/database/DatabaseMysqli.php
includes/libs/rdbms/database/DatabasePostgres.php
includes/libs/rdbms/database/DatabaseSqlite.php
includes/libs/rdbms/database/IDatabase.php
includes/libs/rdbms/database/resultwrapper/FakeResultWrapper.php
includes/libs/rdbms/database/resultwrapper/ResultWrapper.php
includes/libs/rdbms/encasing/Blob.php
includes/libs/rdbms/exception/DBAccessError.php
includes/libs/rdbms/exception/DBConnectionError.php
includes/libs/rdbms/exception/DBError.php
includes/libs/rdbms/exception/DBExpectedError.php
includes/libs/rdbms/exception/DBQueryError.php
includes/libs/rdbms/exception/DBReadOnlyError.php
includes/libs/rdbms/exception/DBReplicationWaitError.php
includes/libs/rdbms/exception/DBTransactionError.php
includes/libs/rdbms/exception/DBTransactionSizeError.php
includes/libs/rdbms/exception/DBUnexpectedError.php
includes/libs/rdbms/field/Field.php
includes/libs/rdbms/lbfactory/ILBFactory.php
includes/libs/rdbms/lbfactory/LBFactory.php
includes/libs/rdbms/loadbalancer/ILoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancerSingle.php
includes/linkeddata/PageDataRequestHandler.php
includes/logging/BlockLogFormatter.php
includes/logging/DeleteLogFormatter.php
includes/logging/ImportLogFormatter.php
includes/logging/LogEntry.php
includes/logging/LogEventsList.php
includes/logging/LogFormatter.php
includes/logging/LogPage.php
includes/logging/LogPager.php
includes/logging/MergeLogFormatter.php
includes/logging/MoveLogFormatter.php
includes/logging/NewUsersLogFormatter.php
includes/logging/PageLangLogFormatter.php
includes/logging/PatrolLogFormatter.php
includes/logging/ProtectLogFormatter.php
includes/logging/RightsLogFormatter.php
includes/logging/UploadLogFormatter.php
includes/logging/WikitextLogFormatter.php
includes/mail/UserMailer.php
includes/media/Exif.php
includes/media/FormatMetadata.php
includes/media/SVGMetadataExtractor.php
includes/parser/Parser.php
includes/parser/ParserOptions.php
includes/parser/ParserOutput.php
includes/password/UserPasswordPolicy.php
includes/preferences/DefaultPreferencesFactory.php
includes/preferences/PreferencesFactory.php
includes/registration/ExtensionJsonValidator.php
includes/registration/ExtensionProcessor.php
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderClientHtml.php
includes/resourceloader/ResourceLoaderFileModule.php
includes/resourceloader/ResourceLoaderModule.php
includes/resourceloader/ResourceLoaderStartUpModule.php
includes/resourceloader/ResourceLoaderUserModule.php
includes/search/SearchEngine.php
includes/search/SearchMssql.php
includes/search/SearchMySQL.php
includes/search/SearchOracle.php
includes/search/SearchPostgres.php
includes/search/SearchResultSet.php
includes/search/SearchSqlite.php
includes/shell/Command.php
includes/site/CachingSiteStore.php
includes/site/DBSiteStore.php
includes/site/FileBasedSiteLookup.php
includes/site/MediaWikiPageNameNormalizer.php
includes/site/MediaWikiSite.php
includes/site/Site.php
includes/site/SiteExporter.php
includes/site/SiteImporter.php
includes/site/SiteList.php
includes/site/SiteLookup.php
includes/site/SiteSQLStore.php
includes/site/SiteStore.php
includes/site/SitesCacheFileBuilder.php
includes/skins/BaseTemplate.php
includes/skins/Skin.php
includes/skins/SkinTemplate.php
includes/specialpage/ChangesListSpecialPage.php
includes/specialpage/SpecialPageFactory.php
includes/specials/SpecialAllPages.php
includes/specials/SpecialApiSandbox.php
includes/specials/SpecialBotPasswords.php
includes/specials/SpecialComparePages.php
includes/specials/SpecialCreateAccount.php
includes/specials/SpecialEditTags.php
includes/specials/SpecialMovepage.php
includes/specials/SpecialPageLanguage.php
includes/specials/SpecialPagesWithProp.php
includes/specials/SpecialPasswordPolicies.php [new file with mode: 0644]
includes/specials/SpecialPreferences.php
includes/specials/SpecialPrefixindex.php
includes/specials/SpecialTrackingCategories.php
includes/specials/SpecialUpload.php
includes/specials/SpecialVersion.php
includes/specials/SpecialWatchlist.php
includes/specials/SpecialWhatlinkshere.php
includes/specials/forms/PreferencesForm.php [deleted file]
includes/specials/forms/PreferencesFormLegacy.php
includes/specials/forms/PreferencesFormOOUI.php
includes/specials/forms/UploadForm.php
includes/specials/helpers/License.php
includes/specials/pagers/UsersPager.php
includes/title/MediaWikiTitleCodec.php
includes/user/User.php
includes/user/UserGroupMembership.php
includes/utils/AutoloadGenerator.php
includes/utils/ExecutableFinder.php
includes/utils/MWCryptHKDF.php
includes/watcheditem/WatchedItemQueryService.php
includes/watcheditem/WatchedItemQueryServiceExtension.php
includes/widget/SizeFilterWidget.php
jsduck.json
languages/Language.php
languages/LanguageConverter.php
languages/classes/LanguageAr.php
languages/classes/LanguageBe_tarask.php
languages/classes/LanguageCrh.php
languages/classes/LanguageKsh.php
languages/classes/LanguageMl.php
languages/data/CrhExceptions.php
languages/data/Names.php
languages/data/normalize-ar.php [new file with mode: 0644]
languages/data/normalize-ml.php [new file with mode: 0644]
languages/data/plurals.xml
languages/i18n/abs.json
languages/i18n/ace.json
languages/i18n/ady-cyrl.json
languages/i18n/aeb-arab.json
languages/i18n/af.json
languages/i18n/ais.json
languages/i18n/aln.json
languages/i18n/am.json
languages/i18n/an.json
languages/i18n/ang.json
languages/i18n/anp.json
languages/i18n/ar.json
languages/i18n/arc.json
languages/i18n/arn.json
languages/i18n/arq.json
languages/i18n/ary.json
languages/i18n/arz.json
languages/i18n/as.json
languages/i18n/ast.json
languages/i18n/atj.json
languages/i18n/avk.json
languages/i18n/awa.json
languages/i18n/az.json
languages/i18n/azb.json
languages/i18n/ba.json
languages/i18n/bar.json
languages/i18n/bcc.json
languages/i18n/bcl.json
languages/i18n/be-tarask.json
languages/i18n/be.json
languages/i18n/bg.json
languages/i18n/bgn.json
languages/i18n/bho.json
languages/i18n/bjn.json
languages/i18n/bn.json
languages/i18n/bo.json
languages/i18n/bpy.json
languages/i18n/bqi.json
languages/i18n/br.json
languages/i18n/bs.json
languages/i18n/btm.json [new file with mode: 0644]
languages/i18n/ca.json
languages/i18n/cdo.json
languages/i18n/ce.json
languages/i18n/ceb.json
languages/i18n/ch.json
languages/i18n/ckb.json
languages/i18n/co.json
languages/i18n/cps.json
languages/i18n/crh-cyrl.json
languages/i18n/crh-latn.json
languages/i18n/cs.json
languages/i18n/csb.json
languages/i18n/cu.json
languages/i18n/cv.json
languages/i18n/cy.json
languages/i18n/da.json
languages/i18n/de-ch.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/dsb.json
languages/i18n/dtp.json
languages/i18n/dty.json
languages/i18n/egl.json
languages/i18n/el.json
languages/i18n/en-gb.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/eu.json
languages/i18n/ext.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fo.json
languages/i18n/fr.json
languages/i18n/frp.json
languages/i18n/frr.json
languages/i18n/fur.json
languages/i18n/fy.json
languages/i18n/ga.json
languages/i18n/gag.json
languages/i18n/gan-hans.json
languages/i18n/gan-hant.json
languages/i18n/gcr.json
languages/i18n/gd.json
languages/i18n/gl.json
languages/i18n/glk.json
languages/i18n/gom-deva.json
languages/i18n/gom-latn.json
languages/i18n/gor.json
languages/i18n/got.json
languages/i18n/grc.json
languages/i18n/gsw.json
languages/i18n/gu.json
languages/i18n/gv.json
languages/i18n/ha.json
languages/i18n/hak.json
languages/i18n/haw.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hif-latn.json
languages/i18n/hil.json
languages/i18n/hr.json
languages/i18n/hrx.json
languages/i18n/hsb.json
languages/i18n/ht.json
languages/i18n/hu.json
languages/i18n/hy.json
languages/i18n/ia.json
languages/i18n/id.json
languages/i18n/ie.json
languages/i18n/ig.json
languages/i18n/ilo.json
languages/i18n/inh.json
languages/i18n/io.json
languages/i18n/is.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/jam.json
languages/i18n/jut.json
languages/i18n/jv.json
languages/i18n/ka.json
languages/i18n/kaa.json
languages/i18n/kab.json
languages/i18n/kbd-cyrl.json
languages/i18n/kbp.json
languages/i18n/khw.json
languages/i18n/kiu.json
languages/i18n/kk-arab.json
languages/i18n/kk-cyrl.json
languages/i18n/kk-latn.json
languages/i18n/km.json
languages/i18n/kn.json
languages/i18n/ko.json
languages/i18n/krc.json
languages/i18n/krl.json
languages/i18n/ksh.json
languages/i18n/ku-latn.json
languages/i18n/kum.json
languages/i18n/kw.json
languages/i18n/ky.json
languages/i18n/la.json
languages/i18n/lad.json
languages/i18n/lb.json
languages/i18n/lez.json
languages/i18n/lfn.json
languages/i18n/lg.json
languages/i18n/li.json
languages/i18n/lij.json
languages/i18n/lki.json
languages/i18n/lmo.json
languages/i18n/lo.json
languages/i18n/loz.json
languages/i18n/lrc.json
languages/i18n/lt.json
languages/i18n/ltg.json
languages/i18n/lus.json
languages/i18n/luz.json
languages/i18n/lv.json
languages/i18n/lzh.json
languages/i18n/lzz.json
languages/i18n/mai.json
languages/i18n/map-bms.json
languages/i18n/mdf.json
languages/i18n/mg.json
languages/i18n/mhr.json
languages/i18n/min.json
languages/i18n/mk.json
languages/i18n/ml.json
languages/i18n/mn.json
languages/i18n/mr.json
languages/i18n/ms.json
languages/i18n/mt.json
languages/i18n/mwl.json
languages/i18n/my.json
languages/i18n/myv.json
languages/i18n/mzn.json
languages/i18n/nah.json
languages/i18n/nan.json
languages/i18n/nap.json
languages/i18n/nb.json
languages/i18n/nds-nl.json
languages/i18n/nds.json
languages/i18n/ne.json
languages/i18n/nl.json
languages/i18n/nn.json
languages/i18n/nso.json
languages/i18n/nys.json
languages/i18n/oc.json
languages/i18n/olo.json
languages/i18n/or.json
languages/i18n/os.json
languages/i18n/pa.json
languages/i18n/pam.json
languages/i18n/pcd.json
languages/i18n/pfl.json
languages/i18n/pl.json
languages/i18n/pms.json
languages/i18n/pnb.json
languages/i18n/pnt.json
languages/i18n/prg.json
languages/i18n/ps.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/qu.json
languages/i18n/qug.json
languages/i18n/rif.json
languages/i18n/rm.json
languages/i18n/ro.json
languages/i18n/roa-tara.json
languages/i18n/ru.json
languages/i18n/rue.json
languages/i18n/sa.json
languages/i18n/sah.json
languages/i18n/sat.json
languages/i18n/sc.json
languages/i18n/scn.json
languages/i18n/sco.json
languages/i18n/sd.json
languages/i18n/sdc.json
languages/i18n/sdh.json
languages/i18n/se.json
languages/i18n/ses.json
languages/i18n/sgs.json
languages/i18n/sh.json
languages/i18n/shi.json
languages/i18n/shn.json
languages/i18n/si.json
languages/i18n/sk.json
languages/i18n/skr-arab.json
languages/i18n/sl.json
languages/i18n/sli.json
languages/i18n/so.json
languages/i18n/sq.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/srn.json
languages/i18n/stq.json
languages/i18n/sty.json
languages/i18n/su.json
languages/i18n/sv.json
languages/i18n/sw.json
languages/i18n/szl.json
languages/i18n/ta.json
languages/i18n/tay.json
languages/i18n/tcy.json
languages/i18n/te.json
languages/i18n/tet.json
languages/i18n/tg-cyrl.json
languages/i18n/tg-latn.json
languages/i18n/th.json
languages/i18n/tk.json
languages/i18n/tl.json
languages/i18n/tly.json
languages/i18n/to.json
languages/i18n/tr.json
languages/i18n/tru.json
languages/i18n/ts.json
languages/i18n/tt-cyrl.json
languages/i18n/tt-latn.json
languages/i18n/tyv.json
languages/i18n/udm.json
languages/i18n/ug-arab.json
languages/i18n/uk.json
languages/i18n/ur.json
languages/i18n/uz.json
languages/i18n/vec.json
languages/i18n/vep.json
languages/i18n/vi.json
languages/i18n/vmf.json
languages/i18n/vo.json
languages/i18n/vot.json
languages/i18n/vro.json
languages/i18n/wa.json
languages/i18n/war.json
languages/i18n/wo.json
languages/i18n/wuu.json
languages/i18n/xal.json
languages/i18n/xmf.json
languages/i18n/yi.json
languages/i18n/yo.json
languages/i18n/yue.json
languages/i18n/zea.json
languages/i18n/zgh.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
languages/i18n/zh-hk.json
languages/messages/MessagesEn.php
languages/messages/MessagesEs.php
languages/messages/MessagesGor.php
languages/messages/MessagesLv.php
languages/messages/MessagesNn.php
languages/messages/MessagesShy_latn.php [new file with mode: 0644]
languages/messages/MessagesTet.php
maintenance/addRFCandPMIDInterwiki.php
maintenance/addSite.php
maintenance/archives/patch-change_tag-tag_id.sql [new file with mode: 0644]
maintenance/archives/patch-externallinks-el_index_60-drop-default.sql [new file with mode: 0644]
maintenance/categoryChangesAsRdf.php [new file with mode: 0644]
maintenance/cleanupCaps.php
maintenance/cleanupImages.php
maintenance/cleanupTitles.php
maintenance/cleanupUploadStash.php
maintenance/cleanupWatchlist.php
maintenance/createCommonPasswordCdb.php
maintenance/deduplicateArchiveRevId.php [new file with mode: 0644]
maintenance/deleteAutoPatrolLogs.php
maintenance/dumpUploads.php
maintenance/exportSites.php
maintenance/fileOpPerfTest.php
maintenance/fixExtLinksProtocolRelative.php
maintenance/formatInstallDoc.php
maintenance/getReplicaServer.php
maintenance/importSites.php
maintenance/language/generateCollationData.php
maintenance/language/generateNormalizerDataAr.php
maintenance/language/generateNormalizerDataMl.php
maintenance/language/zhtable/Makefile.py
maintenance/mssql/archives/patch-change_tag-tag_id.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-externallinks-el_index_60-drop-default.sql [new file with mode: 0644]
maintenance/mssql/tables.sql
maintenance/namespaceDupes.php
maintenance/oracle/archives/patch-change_tag-tag_id.sql [new file with mode: 0644]
maintenance/oracle/tables.sql
maintenance/parse.php
maintenance/populateArchiveRevId.php
maintenance/populateExternallinksIndex60.php [new file with mode: 0644]
maintenance/postgres/tables.sql
maintenance/reassignEdits.php
maintenance/resources/update-ooui.sh
maintenance/runBatchedQuery.php
maintenance/showSiteStats.php
maintenance/sqlite/archives/patch-externallinks-el_index_60-drop-default.sql [new file with mode: 0644]
maintenance/storage/compressOld.php
maintenance/tables.sql
mw-config/config.js
opensearch_desc.php
package.json
resources/Resources.php
resources/src/jquery.spinner/images/spinner-large.gif [new file with mode: 0644]
resources/src/jquery.spinner/images/spinner.gif [new file with mode: 0644]
resources/src/jquery.spinner/spinner.css [new file with mode: 0644]
resources/src/jquery.spinner/spinner.js [new file with mode: 0644]
resources/src/jquery/images/marker.png [deleted file]
resources/src/jquery/images/mask.png [deleted file]
resources/src/jquery/images/spinner-large.gif [deleted file]
resources/src/jquery/images/spinner.gif [deleted file]
resources/src/jquery/images/wheel.png [deleted file]
resources/src/jquery/jquery.farbtastic.css [deleted file]
resources/src/jquery/jquery.farbtastic.js [deleted file]
resources/src/jquery/jquery.footHovzer.css [deleted file]
resources/src/jquery/jquery.footHovzer.js [deleted file]
resources/src/jquery/jquery.makeCollapsible.js
resources/src/jquery/jquery.spinner.css [deleted file]
resources/src/jquery/jquery.spinner.js [deleted file]
resources/src/jquery/jquery.tablesorter.styles.less
resources/src/mediawiki.Title/Title.js
resources/src/mediawiki.Uri/Uri.js
resources/src/mediawiki.action/mediawiki.action.edit.stash.js
resources/src/mediawiki.action/mediawiki.action.edit.styles.less
resources/src/mediawiki.api.category.js [deleted file]
resources/src/mediawiki.api.edit.js [deleted file]
resources/src/mediawiki.api.js [deleted file]
resources/src/mediawiki.api.login.js [deleted file]
resources/src/mediawiki.api.messages.js [deleted file]
resources/src/mediawiki.api.options.js [deleted file]
resources/src/mediawiki.api.parse.js [deleted file]
resources/src/mediawiki.api.rollback.js [deleted file]
resources/src/mediawiki.api.upload.js [deleted file]
resources/src/mediawiki.api.user.js [deleted file]
resources/src/mediawiki.api.watch.js [deleted file]
resources/src/mediawiki.api/category.js [new file with mode: 0644]
resources/src/mediawiki.api/edit.js [new file with mode: 0644]
resources/src/mediawiki.api/index.js [new file with mode: 0644]
resources/src/mediawiki.api/login.js [new file with mode: 0644]
resources/src/mediawiki.api/messages.js [new file with mode: 0644]
resources/src/mediawiki.api/options.js [new file with mode: 0644]
resources/src/mediawiki.api/parse.js [new file with mode: 0644]
resources/src/mediawiki.api/rollback.js [new file with mode: 0644]
resources/src/mediawiki.api/upload.js [new file with mode: 0644]
resources/src/mediawiki.api/user.js [new file with mode: 0644]
resources/src/mediawiki.api/watch.js [new file with mode: 0644]
resources/src/mediawiki.debug/debug.js
resources/src/mediawiki.debug/jquery.footHovzer.css [new file with mode: 0644]
resources/src/mediawiki.debug/jquery.footHovzer.js [new file with mode: 0644]
resources/src/mediawiki.htmlform.ooui.styles.less
resources/src/mediawiki.language/mediawiki.language.init.js
resources/src/mediawiki.language/mediawiki.language.numbers.js
resources/src/mediawiki.legacy/oldshared.css
resources/src/mediawiki.less/mediawiki.mixins.less
resources/src/mediawiki.page.gallery.js
resources/src/mediawiki.page.image.pagination.js
resources/src/mediawiki.skinning/content.externallinks.css [deleted file]
resources/src/mediawiki.skinning/content.externallinks.less [new file with mode: 0644]
resources/src/mediawiki.skinning/content.parsoid.less
resources/src/mediawiki.special.apisandbox/apisandbox.css [new file with mode: 0644]
resources/src/mediawiki.special.apisandbox/apisandbox.js [new file with mode: 0644]
resources/src/mediawiki.special.block.js [new file with mode: 0644]
resources/src/mediawiki.special.changecredentials.js [new file with mode: 0644]
resources/src/mediawiki.special.changeslist.css [new file with mode: 0644]
resources/src/mediawiki.special.changeslist.enhanced.css [new file with mode: 0644]
resources/src/mediawiki.special.changeslist.legend.css [new file with mode: 0644]
resources/src/mediawiki.special.changeslist.legend.js [new file with mode: 0644]
resources/src/mediawiki.special.contributions.js [new file with mode: 0644]
resources/src/mediawiki.special.edittags.js [new file with mode: 0644]
resources/src/mediawiki.special.import.js [new file with mode: 0644]
resources/src/mediawiki.special.movePage.js [new file with mode: 0644]
resources/src/mediawiki.special.pageLanguage.js [new file with mode: 0644]
resources/src/mediawiki.special.preferences.ooui/editfont.js [new file with mode: 0644]
resources/src/mediawiki.special.preferences.ooui/tabs.js [new file with mode: 0644]
resources/src/mediawiki.special.preferences.styles.css [new file with mode: 0644]
resources/src/mediawiki.special.preferences.styles.ooui.css [new file with mode: 0644]
resources/src/mediawiki.special.preferences/confirmClose.js [new file with mode: 0644]
resources/src/mediawiki.special.preferences/convertmessagebox.js [new file with mode: 0644]
resources/src/mediawiki.special.preferences/personalEmail.js [new file with mode: 0644]
resources/src/mediawiki.special.preferences/tabs.legacy.js [new file with mode: 0644]
resources/src/mediawiki.special.preferences/timezone.js [new file with mode: 0644]
resources/src/mediawiki.special.recentchanges.js [new file with mode: 0644]
resources/src/mediawiki.special.revisionDelete.js [new file with mode: 0644]
resources/src/mediawiki.special.search.commonsInterwikiWidget.js [new file with mode: 0644]
resources/src/mediawiki.special.search.interwikiwidget.styles.less [new file with mode: 0644]
resources/src/mediawiki.special.search.styles.css [new file with mode: 0644]
resources/src/mediawiki.special.search/search.css [new file with mode: 0644]
resources/src/mediawiki.special.search/search.js [new file with mode: 0644]
resources/src/mediawiki.special.undelete.js [new file with mode: 0644]
resources/src/mediawiki.special.unwatchedPages/unwatchedPages.css [new file with mode: 0644]
resources/src/mediawiki.special.unwatchedPages/unwatchedPages.js [new file with mode: 0644]
resources/src/mediawiki.special.upload/templates/thumbnail.html [new file with mode: 0644]
resources/src/mediawiki.special.upload/upload.js [new file with mode: 0644]
resources/src/mediawiki.special.userlogin.common.styles/images/icon-lock.png [new file with mode: 0644]
resources/src/mediawiki.special.userlogin.common.styles/userlogin.css [new file with mode: 0644]
resources/src/mediawiki.special.userlogin.login.styles/images/glyph-people-large.png [new file with mode: 0644]
resources/src/mediawiki.special.userlogin.login.styles/login.css [new file with mode: 0644]
resources/src/mediawiki.special.userlogin.signup.js [new file with mode: 0644]
resources/src/mediawiki.special.userlogin.signup.styles/images/icon-contributors.png [new file with mode: 0644]
resources/src/mediawiki.special.userlogin.signup.styles/images/icon-edits.png [new file with mode: 0644]
resources/src/mediawiki.special.userlogin.signup.styles/images/icon-pages.png [new file with mode: 0644]
resources/src/mediawiki.special.userlogin.signup.styles/signup.css [new file with mode: 0644]
resources/src/mediawiki.special.userrights.js [new file with mode: 0644]
resources/src/mediawiki.special.version.css [new file with mode: 0644]
resources/src/mediawiki.special.watchlist/visitedstatus.js [new file with mode: 0644]
resources/src/mediawiki.special.watchlist/watchlist.js [new file with mode: 0644]
resources/src/mediawiki.special/apisandbox.css [new file with mode: 0644]
resources/src/mediawiki.special/comparepages.less [new file with mode: 0644]
resources/src/mediawiki.special/edittags.css [new file with mode: 0644]
resources/src/mediawiki.special/images/glyph-people-large.png [deleted file]
resources/src/mediawiki.special/images/icon-contributors.png [deleted file]
resources/src/mediawiki.special/images/icon-edits.png [deleted file]
resources/src/mediawiki.special/images/icon-lock.png [deleted file]
resources/src/mediawiki.special/images/icon-pages.png [deleted file]
resources/src/mediawiki.special/mediawiki.special.apisandbox.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.apisandbox.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.apisandbox.top.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.block.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.changecredentials.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.changeslist.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.changeslist.enhanced.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.changeslist.legend.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.changeslist.legend.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.changeslist.visitedstatus.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.comparepages.styles.less [deleted file]
resources/src/mediawiki.special/mediawiki.special.contributions.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.edittags.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.edittags.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.import.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.movePage.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.movePage.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.pageLanguage.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.pagesWithProp.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.preferences.confirmClose.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.preferences.convertmessagebox.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.preferences.editfont.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.preferences.personalEmail.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.preferences.styles.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.preferences.styles.legacy.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.preferences.tabs.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.preferences.tabs.legacy.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.preferences.timezone.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.recentchanges.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.revisionDelete.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.search.commonsInterwikiWidget.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.search.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.search.interwikiwidget.styles.less [deleted file]
resources/src/mediawiki.special/mediawiki.special.search.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.search.styles.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.undelete.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.unwatchedPages.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.unwatchedPages.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.upload.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.upload.styles.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.userlogin.common.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.userlogin.login.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.userlogin.signup.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.userlogin.signup.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.userrights.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.userrights.js [deleted file]
resources/src/mediawiki.special/mediawiki.special.version.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.watchlist.css [deleted file]
resources/src/mediawiki.special/mediawiki.special.watchlist.js [deleted file]
resources/src/mediawiki.special/movePage.css [new file with mode: 0644]
resources/src/mediawiki.special/pagesWithProp.css [new file with mode: 0644]
resources/src/mediawiki.special/special.css [new file with mode: 0644]
resources/src/mediawiki.special/templates/thumbnail.html [deleted file]
resources/src/mediawiki.special/upload.css [new file with mode: 0644]
resources/src/mediawiki.special/userrights.css [new file with mode: 0644]
resources/src/mediawiki.special/watchlist.css [new file with mode: 0644]
resources/src/mediawiki.widgets.datetime/DateTimeInputWidget.js
resources/src/mediawiki/mediawiki.js
serialized/.gitignore
serialized/Makefile
serialized/normalize-ar.ser [deleted file]
serialized/normalize-ml.ser [deleted file]
tests/parser/ParserTestRunner.php
tests/parser/parserTests.txt
tests/phan/config.php
tests/phpunit/ResourceLoaderTestCase.php
tests/phpunit/data/autoloader/psr4/TestFooBar.php [new file with mode: 0644]
tests/phpunit/data/categoriesrdf/change.sparql [new file with mode: 0644]
tests/phpunit/data/categoriesrdf/delete.sparql [new file with mode: 0644]
tests/phpunit/data/categoriesrdf/move.sparql [new file with mode: 0644]
tests/phpunit/data/categoriesrdf/new.sparql [new file with mode: 0644]
tests/phpunit/data/categoriesrdf/restore.sparql [new file with mode: 0644]
tests/phpunit/data/categoriesrdf/updatets.txt [new file with mode: 0644]
tests/phpunit/data/less/module/dependency.less
tests/phpunit/data/less/module/use-import-dir.less [new file with mode: 0644]
tests/phpunit/data/registration/bad_url.json [new file with mode: 0644]
tests/phpunit/data/registration/bad_url2.json [new file with mode: 0644]
tests/phpunit/data/registration/good.json
tests/phpunit/includes/AutoLoaderTest.php [new file with mode: 0644]
tests/phpunit/includes/ContentSecurityPolicyTest.php [new file with mode: 0644]
tests/phpunit/includes/HooksTest.php
tests/phpunit/includes/OutputPageTest.php
tests/phpunit/includes/TestLogger.php
tests/phpunit/includes/XmlTest.php
tests/phpunit/includes/actions/ActionTest.php
tests/phpunit/includes/actions/WatchActionTest.php [new file with mode: 0644]
tests/phpunit/includes/api/ApiBaseTest.php
tests/phpunit/includes/api/ApiQueryRecentChangesIntegrationTest.php
tests/phpunit/includes/api/format/ApiFormatXmlTest.php
tests/phpunit/includes/api/query/ApiQueryUserContribsTest.php [new file with mode: 0644]
tests/phpunit/includes/api/query/ApiQueryUserContributionsTest.php [deleted file]
tests/phpunit/includes/auth/ThrottlerTest.php
tests/phpunit/includes/collation/CollationFaTest.php [deleted file]
tests/phpunit/includes/db/LBFactoryTest.php
tests/phpunit/includes/htmlform/HTMLFormTest.php
tests/phpunit/includes/http/HttpTest.php
tests/phpunit/includes/jobqueue/JobQueueMemoryTest.php
tests/phpunit/includes/jobqueue/jobs/CategoryMembershipChangeJobTest.php
tests/phpunit/includes/jobqueue/jobs/ClearUserWatchlistJobTest.php
tests/phpunit/includes/libs/CSSMinTest.php
tests/phpunit/includes/libs/IPTest.php
tests/phpunit/includes/media/IPTCTest.php
tests/phpunit/includes/parser/ParserOptionsTest.php
tests/phpunit/includes/password/PasswordPolicyChecksTest.php
tests/phpunit/includes/preferences/DefaultPreferencesFactoryTest.php
tests/phpunit/includes/registration/ExtensionJsonValidatorTest.php
tests/phpunit/includes/registration/ExtensionRegistryTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderClientHtmlTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderLessVarFileModuleTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderStartUpModuleTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderTest.php
tests/phpunit/includes/specials/SpecialBlankPageTest.php
tests/phpunit/includes/specials/SpecialPageTestBase.php
tests/phpunit/includes/specials/SpecialShortpagesTest.php
tests/phpunit/includes/title/MediaWikiTitleCodecTest.php
tests/phpunit/includes/user/UserTest.php
tests/phpunit/languages/classes/LanguageCrhTest.php
tests/phpunit/languages/classes/LanguageSrTest.php
tests/phpunit/maintenance/categoryChangesRdfTest.php [new file with mode: 0644]
tests/phpunit/maintenance/deleteAutoPatrolLogsTest.php
tests/phpunit/structure/ApiStructureTest.php
tests/phpunit/structure/AutoLoaderStructureTest.php [new file with mode: 0644]
tests/phpunit/structure/AutoLoaderTest.php [deleted file]
tests/qunit/QUnitTestResources.php
tests/qunit/data/load.mock.php
tests/qunit/data/styleTest.css.php
tests/qunit/suites/resources/jquery/jquery.makeCollapsible.test.js
tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.test.js
thumb.php

index d43a281..14bb494 100644 (file)
                <exclude name="MediaWiki.Commenting.FunctionComment.WrongStyle" />
                <exclude name="MediaWiki.Commenting.IllegalSingleLineComment.IllegalSingleLineCommentStart" />
                <exclude name="MediaWiki.Commenting.IllegalSingleLineComment.IllegalSingleLineCommentEnd" />
-               <exclude name="MediaWiki.Commenting.LicenseComment.InvalidLicenseTag" />
                <exclude name="MediaWiki.ControlStructures.AssignmentInControlStructures.AssignmentInControlStructures" />
                <exclude name="MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName" />
                <exclude name="MediaWiki.WhiteSpace.SpaceBeforeSingleLineComment.NewLineComment" />
                <exclude name="MediaWiki.WhiteSpace.SpaceBeforeSingleLineComment.SingleSpaceBeforeSingleLineComment" />
                <exclude name="MediaWiki.Usage.DbrQueryUsage.DbrQueryFound" />
                <exclude name="MediaWiki.Usage.ExtendClassUsage.FunctionVarUsage" />
-               <exclude name="MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals" />
-               <exclude name="MediaWiki.Files.ClassMatchesFilename.WrongCase" />
-               <exclude name="MediaWiki.Files.ClassMatchesFilename.NotMatch" />
-               <exclude name="Generic.Files.OneObjectStructurePerFile.MultipleFound" />
                <exclude name="MediaWiki.VariableAnalysis.ForbiddenGlobalVariables.ForbiddenGlobal$wgTitle" />
-               <exclude name="MediaWiki.Commenting.FunctionComment.SpacingDocStar" />
-               <exclude name="MediaWiki.Commenting.FunctionComment.SpacingDocTag" />
                <exclude name="Squiz.Scope.MethodScope.Missing" />
                <exclude name="Squiz.Scope.MemberVarScope.Missing" />
                <exclude name="MediaWiki.Commenting.MissingCovers.MissingCovers" />
-               <exclude name="MediaWiki.Usage.AssignmentInReturn.AssignmentInReturn" />
        </rule>
        <rule ref="MediaWiki.NamingConventions.PrefixedGlobalFunctions">
                <properties>
        <rule ref="Generic.Files.LineLength">
                <exclude-pattern>*/languages/messages/Messages*\.php</exclude-pattern>
        </rule>
+       <rule ref="MediaWiki.Files.ClassMatchesFilename.NotMatch">
+               <!--
+                       Whitelist existing violations, but enable the sniff to prevent
+                       any new occurrences.
+               -->
+               <exclude-pattern>*/includes/media/XCF\.php</exclude-pattern>
+               <exclude-pattern>*/includes/Feed\.php</exclude-pattern>
+               <exclude-pattern>*/includes/libs/xmp/XMP\.php</exclude-pattern>
+               <exclude-pattern>*/includes/jobqueue/JobSpecification\.php</exclude-pattern>
+               <exclude-pattern>*/includes/RevisionList\.php</exclude-pattern>
+               <exclude-pattern>*/includes/installer/PhpBugTests\.php</exclude-pattern>
+               <exclude-pattern>*/includes/exception/LocalizedException\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMostinterwikis\.php</exclude-pattern>
+               <exclude-pattern>*/includes/cache/CacheDependency\.php</exclude-pattern>
+               <exclude-pattern>*/includes/cache/CacheHelper\.php</exclude-pattern>
+               <exclude-pattern>*/includes/diff/DairikiDiff\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialAncientpages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialBrokenRedirects\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialConfirmemail\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialDeadendpages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialDeletedContributions\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialDoubleRedirects\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialEmailInvalidate\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialFewestrevisions\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialFileDuplicateSearch\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialLinkSearch\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialListDuplicatedFiles\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialListredirects\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialLonelypages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialLongpages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMIMEsearch\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMediaStatistics\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMostcategories\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMostimages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMostlinked\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMostlinkedcategories\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMostlinkedtemplates\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMostrevisions\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMovepage\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMyRedirectPages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialNewimages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialRandompage\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialShortpages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialUncategorizedcategories\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialUncategorizedimages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialUncategorizedpages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialUncategorizedtemplates\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialUnusedcategories\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialUnusedimages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialUnusedtemplates\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialUnwatchedpages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialUserrights\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialWantedcategories\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialWantedfiles\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialWantedpages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialWantedtemplates\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialWithoutinterwiki\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/7zip.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/CodeCleanerGlobalsPass.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/archives/upgradeLogging\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/backup.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/benchmarks/bench_HTTP_HTTPS\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/benchmarks/bench_Wikimedia_base_convert\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/benchmarks/bench_delete_truncate\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/benchmarks/bench_if_switch\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/benchmarks/bench_strtr_str_replace\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/benchmarks/bench_utf8_title_check\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/benchmarks/bench_wfIsWindows\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/cleanupTable.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/cleanupTitles\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/commandLine.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/dumpTextPass\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/edit\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/findDeprecated\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/getText\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/hhvm/makeRepo\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/importDump\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/install\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/invalidateUserSessions\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/jsparse\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/lag\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/language/StatOutputs\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/language/checkLanguage.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/language/date-formats\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/language/languages.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/minify\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/parse\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/preprocessorFuzzTest\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/rebuildImages\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/renderDump\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/shell\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/sql\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/sqlite.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/sqlite\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/term/MWTerm\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/update\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/userDupes.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/userOptions\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/view\.php</exclude-pattern>
+               <exclude-pattern>*/profileinfo\.php</exclude-pattern>
+               <!-- Language converters use the pattern of 2 classes in one file -->
+               <exclude-pattern>*/languages/*\.php</exclude-pattern>
+               <!-- We don't care that much about violations in tests -->
+               <exclude-pattern>*/tests/*\.php</exclude-pattern>
+       </rule>
+       <rule ref="MediaWiki.Files.ClassMatchesFilename.WrongCase">
+               <!--
+                       Whitelist existing violations, but enable the sniff to prevent
+                       any new occurrences.
+               -->
+               <exclude-pattern>*/includes/specials/SpecialActiveusers\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialBooksources\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialEmailuser\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialListfiles\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialListgrants\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialListgrouprights\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialListusers.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialRecentchanges\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialRecentchangeslinked\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialRevisiondelete\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialWhatlinkshere\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/language/alltrans\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/language/digit2html\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/language/langmemusage\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/mctest\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/mergeMessageFileList\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/mwdocgen\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/rebuildall\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/rebuildmessages\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/rebuildrecentchanges\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/rebuildtextindex\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/storage/checkStorage\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/storage/recompressTracked\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/storage/trackBlobs\.php</exclude-pattern>
+               <!-- We don't care that much about violations in tests -->
+               <exclude-pattern>*/tests/*\.php</exclude-pattern>
+       </rule>
+
+       <rule ref="Generic.Files.OneObjectStructurePerFile.MultipleFound">
+               <!--
+                       Whitelist existing violations, but enable the sniff to prevent
+                       any new occurrences.
+               -->
+               <exclude-pattern>*/includes/actions/HistoryAction\.php</exclude-pattern>
+               <exclude-pattern>*/includes/api/ApiErrorFormatter\.php</exclude-pattern>
+               <exclude-pattern>*/includes/api/ApiImport\.php</exclude-pattern>
+               <exclude-pattern>*/includes/api/ApiMessage\.php</exclude-pattern>
+               <exclude-pattern>*/includes/api/ApiOpenSearch\.php</exclude-pattern>
+               <exclude-pattern>*/includes/api/ApiRsd\.php</exclude-pattern>
+               <exclude-pattern>*/includes/api/ApiUsageException\.php</exclude-pattern>
+               <exclude-pattern>*/includes/auth/AuthManagerAuthPlugin\.php</exclude-pattern>
+               <exclude-pattern>*/includes/AuthPlugin\.php</exclude-pattern>
+               <exclude-pattern>*/includes/cache/CacheDependency\.php</exclude-pattern>
+               <exclude-pattern>*/includes/cache/CacheHelper\.php</exclude-pattern>
+               <exclude-pattern>*/includes/deferred/CdnCacheUpdate\.php</exclude-pattern>
+               <exclude-pattern>*/includes/diff/DairikiDiff\.php</exclude-pattern>
+               <exclude-pattern>*/includes/diff/DiffEngine\.php</exclude-pattern>
+               <exclude-pattern>*/includes/exception/LocalizedException\.php</exclude-pattern>
+               <exclude-pattern>*/includes/Feed\.php</exclude-pattern>
+               <exclude-pattern>*/includes/filerepo/file/LocalFile\.php</exclude-pattern>
+               <exclude-pattern>*/includes/gallery/PackedOverlayImageGallery\.php</exclude-pattern>
+               <exclude-pattern>*/includes/HistoryBlob\.php</exclude-pattern>
+               <exclude-pattern>*/includes/htmlform/HTMLFormElement\.php</exclude-pattern>
+               <exclude-pattern>*/includes/jobqueue/aggregator/JobQueueAggregator\.php</exclude-pattern>
+               <exclude-pattern>*/includes/jobqueue/JobQueue\.php</exclude-pattern>
+               <exclude-pattern>*/includes/jobqueue/JobSpecification\.php</exclude-pattern>
+               <exclude-pattern>*/includes/libs/filebackend/FileBackendStore\.php</exclude-pattern>
+               <exclude-pattern>*/includes/libs/filebackend/FSFileBackend\.php</exclude-pattern>
+               <exclude-pattern>*/includes/libs/filebackend/SwiftFileBackend\.php</exclude-pattern>
+               <exclude-pattern>*/includes/logging/LogEntry\.php</exclude-pattern>
+               <exclude-pattern>*/includes/logging/LogFormatter\.php</exclude-pattern>
+               <exclude-pattern>*/includes/media/MediaTransformOutput\.php</exclude-pattern>
+               <exclude-pattern>*/includes/media/SVGMetadataExtractor\.php</exclude-pattern>
+               <exclude-pattern>*/includes/parser/Preprocessor_DOM\.php</exclude-pattern>
+               <exclude-pattern>*/includes/parser/Preprocessor_Hash\.php</exclude-pattern>
+               <exclude-pattern>*/includes/parser/Preprocessor\.php</exclude-pattern>
+               <exclude-pattern>*/includes/PathRouter\.php</exclude-pattern>
+               <exclude-pattern>*/includes/poolcounter/PoolCounter\.php</exclude-pattern>
+               <exclude-pattern>*/includes/PrefixSearch\.php</exclude-pattern>
+               <exclude-pattern>*/includes/profiler/SectionProfiler\.php</exclude-pattern>
+               <exclude-pattern>*/includes/RevisionList\.php</exclude-pattern>
+               <exclude-pattern>*/includes/search/SearchEngine\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specialpage/LoginSignupSpecialPage\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specialpage/RedirectSpecialPage\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/forms/PreferencesFormLegacy\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialListusers\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMyRedirectPages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialUploadStash\.php</exclude-pattern>
+               <exclude-pattern>*/includes/StubObject\.php</exclude-pattern>
+               <exclude-pattern>*/includes/upload/UploadFromChunks\.php</exclude-pattern>
+               <exclude-pattern>*/includes/upload/UploadStash\.php</exclude-pattern>
+               <exclude-pattern>*/includes/utils/AutoloadGenerator\.php</exclude-pattern>
+               <exclude-pattern>*/includes/WebResponse\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/dumpIterator\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/Maintenance\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/findDeprecated\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/storage/recompressTracked\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/preprocessorFuzzTest\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/language/languages.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/language/StatOutputs\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/language/checkLanguage.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/language/generateCollationData\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/term/MWTerm\.php</exclude-pattern>
+               <!-- Language converters use the pattern of 2 classes in one file -->
+               <exclude-pattern>*/languages/*\.php</exclude-pattern>
+               <!-- We don't care that much about violations in tests -->
+               <exclude-pattern>*/tests/*\.php</exclude-pattern>
+       </rule>
        <rule ref="PSR2.Methods.MethodDeclaration.Underscore">
                <exclude-pattern>*/includes/StubObject\.php</exclude-pattern>
        </rule>
+       <rule ref="MediaWiki.Usage.AssignmentInReturn.AssignmentInReturn">
+               <exclude-pattern>*/tests/phpunit/*\.php</exclude-pattern>
+       </rule>
        <file>.</file>
        <arg name="encoding" value="UTF-8"/>
        <arg name="extensions" value="php,php5,inc,sample"/>
index 3687d28..8018212 100644 (file)
@@ -27,7 +27,6 @@ module.exports = function ( grunt ) {
                                '!node_modules/**',
                                '!resources/lib/**',
                                '!resources/src/jquery.tipsy/**',
-                               '!resources/src/jquery/jquery.farbtastic.js',
                                '!resources/src/mediawiki.libs.jpegmeta/**',
                                // Third-party code of PHPUnit coverage report
                                '!tests/coverage/**',
diff --git a/INSTALL b/INSTALL
index 3b93505..91dcbea 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -6,7 +6,7 @@ Starting with MediaWiki 1.2.0, it's possible to install and configure the wiki
 "in-place", as long as you have the necessary prerequisites available.
 
 Required software:
-* Web server with PHP 5.5.9 or higher.
+* Web server with PHP 7.0.0 or HHVM 3.18.5 or higher.
 * A SQL server, the following types are supported
 ** MySQL 5.5.8 or higher
 ** PostgreSQL 9.2 or higher
@@ -56,7 +56,7 @@ ie. /wiki/index.php/Article.
   |  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: https://www.mediawiki.org/wiki/Manual:Short_URL                  |
+  |  See: https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Short_URL |
   +--------------------------------------------------------------------------+
 
 Hop into your browser and surf into the wiki directory. It'll direct you into
diff --git a/README b/README
deleted file mode 100644 (file)
index ad9b9d9..0000000
--- a/README
+++ /dev/null
@@ -1,33 +0,0 @@
-== MediaWiki ==
-
-MediaWiki is a free and open-source wiki software package written in PHP. It
-serves as the platform for Wikipedia and the other Wikimedia projects, used
-by hundreds of millions of people each month. MediaWiki is localised in over
-350 languages and its reliability and robust feature set have earned it a large
-and vibrant community of third-party users and developers.
-
-MediaWiki is:
-
-* feature-rich and extensible, both on-wiki and with hundreds of extensions;
-* scalable and suitable for both small and large sites;
-* simple to install, working on most hardware/software combinations; and
-* available in your language.
-
-For system requirements, installation, and upgrade details, see the files
-RELEASE-NOTES, INSTALL, and UPGRADE.
-
-* Ready to get started?
-** https://www.mediawiki.org/wiki/Special:MyLanguage/Download
-* Looking for the technical manual?
-** https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents
-* Seeking help from a person?
-** https://www.mediawiki.org/wiki/Special:MyLanguage/Communication
-* Looking to file a bug report or a feature request?
-** https://bugs.mediawiki.org/
-* Interested in helping out?
-** https://www.mediawiki.org/wiki/Special:MyLanguage/How_to_contribute
-
-MediaWiki is the result of global collaboration and cooperation. The CREDITS
-file lists technical contributors to the project. The COPYING file explains
-MediaWiki's copyright and license (GNU General Public License, version 2 or
-later). Many thanks to the Wikimedia community for testing and suggestions.
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..ca703db
--- /dev/null
+++ b/README.md
@@ -0,0 +1,34 @@
+MediaWiki
+===========
+
+MediaWiki is a free and open-source wiki software package written in PHP. It
+serves as the platform for Wikipedia and the other Wikimedia projects, used
+by hundreds of millions of people each month. MediaWiki is localised in over
+350 languages and its reliability and robust feature set have earned it a large
+and vibrant community of third-party users and developers.
+
+MediaWiki is:
+
+* feature-rich and extensible, both on-wiki and with hundreds of extensions;
+* scalable and suitable for both small and large sites;
+* simple to install, working on most hardware/software combinations; and
+* available in your language.
+
+For system requirements, installation, and upgrade details, see the files
+RELEASE-NOTES, INSTALL, and UPGRADE.
+
+* Ready to get started?
+** https://www.mediawiki.org/wiki/Special:MyLanguage/Download
+* Looking for the technical manual?
+** https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents
+* Seeking help from a person?
+** https://www.mediawiki.org/wiki/Special:MyLanguage/Communication
+* Looking to file a bug report or a feature request?
+** https://bugs.mediawiki.org/
+* Interested in helping out?
+** https://www.mediawiki.org/wiki/Special:MyLanguage/How_to_contribute
+
+MediaWiki is the result of global collaboration and cooperation. The CREDITS
+file lists technical contributors to the project. The COPYING file explains
+MediaWiki's copyright and license (GNU General Public License, version 2 or
+later). Many thanks to the Wikimedia community for testing and suggestions.
diff --git a/README.mediawiki b/README.mediawiki
deleted file mode 120000 (symlink)
index 100b938..0000000
+++ /dev/null
@@ -1 +0,0 @@
-README
\ No newline at end of file
index a702451..bf038a7 100644 (file)
@@ -101,6 +101,9 @@ production.
   discussion pages) now have a tooltip to indicate state, not just colour.
 
 === External library changes in 1.31 ===
+* pear/mail, pear/mail_mime and pear/mail_mime-decode have been moved from
+  suggested to required. These packages now must be installed via composer
+  and not via PEAR itself.
 
 ==== Upgraded external libraries ====
 * Updated jquery.chosen from v0.9.14 to v1.8.2.
@@ -380,6 +383,9 @@ changes to languages because of Phabricator reports.
   used instead.
 * The function wfShellWikiCmd() has been deprecated, use
   MediaWiki\Shell::makeScriptCommand().
+* In the future, the hooks 'PreferencesFormPreSave' and 'PreferencesGetLegend'
+  will be allowed to provide any HTMLForm object rather than PreferencesForm.
+
 === Other changes in 1.31 ===
 * Browser support for Internet Explorer 10 was lowered from Grade A to Grade C.
 * Browser support for Opera 12 and older was dropped entirely. Opera 15+
index 9fd3161..3d193d4 100644 (file)
@@ -17,11 +17,22 @@ production.
   'html5-legacy' value for $wgFragmentMode is no longer accepted.
 * The experimental Html5Internal and Html5Depurate tidy drivers were removed.
   RemexHtml, which is the default, should be used instead.
+* (T135963) You can now define a Content Security Policy for your wiki. This
+  adds a defense-in-depth feature to stop an attacker who has found a bug in
+  the parser allowing them to insert malicious attributes. Disabled by default,
+  you can configure this via $wgCSPHeader and $wgCSPReportOnlyHeader.
+* New configuration variable has been added: $wgCookieSetOnIpBlock.
+  This determines whether to set a cookie when an IP user is blocked. Doing so means
+  that a blocked user, even after moving to a new IP address, will still be blocked.
 
 === New features in 1.32 ===
 * (T112474) Generalized the ResourceLoader mechanism for overriding modules
   using a particular page during edit previews.
 * Added 'ApiParseMakeOutputPage' hook.
+* (T174313) Added checkbox on Special:ListUsers to display only users in
+  temporary user groups.
+* (T152462) A cookie can now be set when an IP user is blocked to track that user if
+  they move to a new IP address. This is disabled by default.
 
 === External library changes in 1.32 ===
 * …
@@ -39,10 +50,22 @@ production.
 * …
 
 === Action API changes in 1.32 ===
-* …
+* Added templated parameters.
+  * A module can define a templated parameter like "{fruit}-quantity", where
+    the actual parameters recognized correspond to the values of a multi-valued
+    parameter. Then clients can make requests like
+    "fruits=apples|bananas&apples-quantity=1&bananas-quantity=5".
+  * action=paraminfo will return templated parameter definitions separately
+    from normal parameters. All parameter definitions now include an "index"
+    key to allow clients to maintain parameter ordering when merging normal and
+    templated parameters.
+* It is now an error to submit too many values for a multi-valued parameter.
+  This has generated a warning since MediaWiki 1.14.
 
 === Action API internal changes in 1.32 ===
 * Added 'ApiParseMakeOutputPage' hook.
+* Parameter names may no longer contain '{' or '}', as these are now used for
+  templated parameters.
 
 === Languages updated in 1.32 ===
 MediaWiki supports over 350 languages. Many localisations are updated regularly.
@@ -50,6 +73,7 @@ Below only new and removed languages are listed, as well as changes to languages
 because of Phabricator reports.
 
 * (T193566) Added language support for Ambonese Malay (abs).
+* (T194047) Added language support for Shawiya, Latin script (shy-latn).
 
 === Breaking changes in 1.32 ===
 * $wgRequestTime, deprecated in 1.25, was removed. Use
@@ -78,9 +102,30 @@ because of Phabricator reports.
 * mw.util.updateTooltipAccessKeys(), deprecated in 1.24, was removed. Use
   jquery.accessKeyLabel instead.
 * The SqlDataUpdate class, deprecated in 1.28, has been removed.
-* The Html5Internal and Html5Depurate tidy driver classes were removed, along with the
-  Balancer tidy implementation. Both implementations were experimental, and were replaced
-  by RemexHtml.
+* The Html5Internal and Html5Depurate tidy driver classes were removed, along
+  with the Balancer tidy implementation. Both implementations were experimental,
+  and were replaced by RemexHtml.
+* (T179624) Job::insert() and ::batchInsert(), deprecated in 1.21, were both
+  removed. Use JobQueueGroup::singleton()->push() instead.
+* The jquery.footHovzer module, for mediawiki.debug, was removed.
+* The es5-shim module, empty and deprecated since 1.29, was removed.
+* The mediawiki.widgets.visibleByteLimit module alias, deprecated in 1.32, was
+  removed. Use mediawiki.widgets.visibleLengthLimit instead.
+* The jquery.farbtastic module, unused since 1.18, was removed.
+* (T181318) The $wgStyleVersion setting and its appendage to various script and
+  style URLs in OutputPage, deprecated in 1.31, was removed.
+* The hooks 'PreferencesFormPreSave' and 'PreferencesGetLegend' may provide
+  any HTMLForm object rather than PreferencesForm.
+* The non namespaced TimestampException class, deprecated in 1.29, was removed.
+  Use Wikimedia\Timestamp\TimestampException instead.
+* The global functions codepointToUtf8, hexSequenceToUtf8, utf8ToHexSequence,
+  utf8ToCodepoint, and escapeSingleString (deprecated in 1.25) were removed.
+  The UtfNormal\Utils class from the utfnormal library should be used instead.
+* The deprecated UTF8_ and UNICODE_ constants were removed. The class constants
+  from the UtfNormal\Constants class from the utfnormal library should be used
+* (T140807) The wgResourceLoaderLESSImportPaths configuration option was removed
+  from ResourceLoader. Instead, use `@import` statements in LESS to import
+  files directly from nearby directories within the same project.
 
 === Deprecations in 1.32 ===
 * Use of a StartProfiler.php file is deprecated in favour of placing
@@ -92,13 +137,34 @@ because of Phabricator reports.
   of queueing style modules as well.
 * OutputPage::addModuleScripts() and ParserOutput::addModuleScripts are
   deprecated. Use addModules() instead.
+* Overriding SearchEngine::{searchText,searchTitle,searchArchiveTitle}
+  in extending classes is deprecated.  Extend related doSearch* methods
+  instead.
+* CollationFa has been removed completely as it's not needed anymore
+* The following 'mediawiki.api' plugin modules were merged into mediawiki.api
+  and deprecated: mediawiki.api.category, mediawiki.api.edit,
+  mediawiki.api.login, mediawiki.api.options, mediawiki.api.parse,
+  mediawiki.api.upload, mediawiki.api.user, mediawiki.api.watch,
+  mediawiki.api.messages, and mediawiki.api.rollback.
+* ApiBase::truncateArray() is deprecated. No replacement, as nothing is known
+  to use it.
+* WatchAction::getUnwatchToken is deprecated. Use WatchAction::getWatchToken
+  with the 'unwatch' action parameter instead.
+* IcuCollation::getICUVersion() is deprecated, as you can just use the PHP
+  constant INTL_ICU_VERSION directly in all versions that MediaWiki supports.
+* Parser::fetchFile() is deprecated. Use ::fetchFileAndTitle() instead.
+* The ApiQueryContributions class has been renamed to ApiQueryUserContribs.
 
 === Other changes in 1.32 ===
+* Soft hyphens (U+00AD) are now automatically removed from titles; these
+  characters can accidentally end up in copy-and-pasted titles.
+* Strip Unicode 6.3.0 directional formatting characters (U+061C, U+2066,
+  U+2067, U+2068, U+2069) from the title.
 * …
 
 == Compatibility ==
-MediaWiki 1.32 requires PHP 5.5.9 or later. Although HHVM 3.18.5 or later is
-supported, it is generally advised to use PHP 5.5.9 or later for long term
+MediaWiki 1.32 requires PHP 7.0.0 or later. Although HHVM 3.18.5 or later is
+supported, it is generally advised to use PHP 7.0.0 or later for long term
 support.
 
 MySQL/MariaDB is the recommended DBMS. PostgreSQL or SQLite can also be used,
index ec0d59f..77144df 100644 (file)
@@ -12,7 +12,7 @@ $wgAutoloadLocalClasses = [
        'ActiveUsersPager' => __DIR__ . '/includes/specials/pagers/ActiveUsersPager.php',
        'ActivityUpdateJob' => __DIR__ . '/includes/jobqueue/jobs/ActivityUpdateJob.php',
        'ActorMigration' => __DIR__ . '/includes/ActorMigration.php',
-       'AddRFCAndPMIDInterwiki' => __DIR__ . '/maintenance/addRFCandPMIDInterwiki.php',
+       'AddRFCandPMIDInterwiki' => __DIR__ . '/maintenance/addRFCandPMIDInterwiki.php',
        'AddSite' => __DIR__ . '/maintenance/addSite.php',
        'AjaxDispatcher' => __DIR__ . '/includes/AjaxDispatcher.php',
        'AjaxResponse' => __DIR__ . '/includes/AjaxResponse.php',
@@ -64,7 +64,7 @@ $wgAutoloadLocalClasses = [
        'ApiManageTags' => __DIR__ . '/includes/api/ApiManageTags.php',
        'ApiMergeHistory' => __DIR__ . '/includes/api/ApiMergeHistory.php',
        'ApiMessage' => __DIR__ . '/includes/api/ApiMessage.php',
-       'ApiMessageTrait' => __DIR__ . '/includes/api/ApiMessage.php',
+       'ApiMessageTrait' => __DIR__ . '/includes/api/ApiMessageTrait.php',
        'ApiModuleManager' => __DIR__ . '/includes/api/ApiModuleManager.php',
        'ApiMove' => __DIR__ . '/includes/api/ApiMove.php',
        'ApiOpenSearch' => __DIR__ . '/includes/api/ApiOpenSearch.php',
@@ -93,7 +93,7 @@ $wgAutoloadLocalClasses = [
        'ApiQueryCategories' => __DIR__ . '/includes/api/ApiQueryCategories.php',
        'ApiQueryCategoryInfo' => __DIR__ . '/includes/api/ApiQueryCategoryInfo.php',
        'ApiQueryCategoryMembers' => __DIR__ . '/includes/api/ApiQueryCategoryMembers.php',
-       'ApiQueryContributions' => __DIR__ . '/includes/api/ApiQueryUserContributions.php',
+       'ApiQueryContributions' => __DIR__ . '/includes/api/ApiQueryUserContribs.php',
        'ApiQueryContributors' => __DIR__ . '/includes/api/ApiQueryContributors.php',
        'ApiQueryDeletedRevisions' => __DIR__ . '/includes/api/ApiQueryDeletedRevisions.php',
        'ApiQueryDeletedrevs' => __DIR__ . '/includes/api/ApiQueryDeletedrevs.php',
@@ -129,11 +129,12 @@ $wgAutoloadLocalClasses = [
        'ApiQueryStashImageInfo' => __DIR__ . '/includes/api/ApiQueryStashImageInfo.php',
        'ApiQueryTags' => __DIR__ . '/includes/api/ApiQueryTags.php',
        'ApiQueryTokens' => __DIR__ . '/includes/api/ApiQueryTokens.php',
+       'ApiQueryUserContribs' => __DIR__ . '/includes/api/ApiQueryUserContribs.php',
        'ApiQueryUserInfo' => __DIR__ . '/includes/api/ApiQueryUserInfo.php',
        'ApiQueryUsers' => __DIR__ . '/includes/api/ApiQueryUsers.php',
        'ApiQueryWatchlist' => __DIR__ . '/includes/api/ApiQueryWatchlist.php',
        'ApiQueryWatchlistRaw' => __DIR__ . '/includes/api/ApiQueryWatchlistRaw.php',
-       'ApiRawMessage' => __DIR__ . '/includes/api/ApiMessage.php',
+       'ApiRawMessage' => __DIR__ . '/includes/api/ApiRawMessage.php',
        'ApiRemoveAuthenticationData' => __DIR__ . '/includes/api/ApiRemoveAuthenticationData.php',
        'ApiResetPassword' => __DIR__ . '/includes/api/ApiResetPassword.php',
        'ApiResult' => __DIR__ . '/includes/api/ApiResult.php',
@@ -183,7 +184,6 @@ $wgAutoloadLocalClasses = [
        'BatchRowIterator' => __DIR__ . '/includes/utils/BatchRowIterator.php',
        'BatchRowUpdate' => __DIR__ . '/includes/utils/BatchRowUpdate.php',
        'BatchRowWriter' => __DIR__ . '/includes/utils/BatchRowWriter.php',
-       'BatchedQueryRunner' => __DIR__ . '/maintenance/runBatchedQuery.php',
        'BcryptPassword' => __DIR__ . '/includes/password/BcryptPassword.php',
        'BenchHttpHttps' => __DIR__ . '/maintenance/benchmarks/bench_HTTP_HTTPS.php',
        'BenchIfSwitch' => __DIR__ . '/maintenance/benchmarks/bench_if_switch.php',
@@ -222,9 +222,9 @@ $wgAutoloadLocalClasses = [
        'CachedBagOStuff' => __DIR__ . '/includes/libs/objectcache/CachedBagOStuff.php',
        'CachingSiteStore' => __DIR__ . '/includes/site/CachingSiteStore.php',
        'CannotCreateActorException' => __DIR__ . '/includes/exception/CannotCreateActorException.php',
-       'CapsCleanup' => __DIR__ . '/maintenance/cleanupCaps.php',
        'CategoriesRdf' => __DIR__ . '/includes/CategoriesRdf.php',
        'Category' => __DIR__ . '/includes/Category.php',
+       'CategoryChangesAsRdf' => __DIR__ . '/maintenance/categoryChangesAsRdf.php',
        'CategoryFinder' => __DIR__ . '/includes/CategoryFinder.php',
        'CategoryMembershipChange' => __DIR__ . '/includes/changes/CategoryMembershipChange.php',
        'CategoryMembershipChangeJob' => __DIR__ . '/includes/jobqueue/jobs/CategoryMembershipChangeJob.php',
@@ -263,12 +263,16 @@ $wgAutoloadLocalClasses = [
        'ClassCollector' => __DIR__ . '/includes/utils/AutoloadGenerator.php',
        'CleanupAncientTables' => __DIR__ . '/maintenance/cleanupAncientTables.php',
        'CleanupBlocks' => __DIR__ . '/maintenance/cleanupBlocks.php',
+       'CleanupCaps' => __DIR__ . '/maintenance/cleanupCaps.php',
        'CleanupEmptyCategories' => __DIR__ . '/maintenance/cleanupEmptyCategories.php',
+       'CleanupImages' => __DIR__ . '/maintenance/cleanupImages.php',
        'CleanupInvalidDbKeys' => __DIR__ . '/maintenance/cleanupInvalidDbKeys.php',
        'CleanupPreferences' => __DIR__ . '/maintenance/cleanupPreferences.php',
        'CleanupRemovedModules' => __DIR__ . '/maintenance/cleanupRemovedModules.php',
        'CleanupSpam' => __DIR__ . '/maintenance/cleanupSpam.php',
+       'CleanupUploadStash' => __DIR__ . '/maintenance/cleanupUploadStash.php',
        'CleanupUsersWithNoId' => __DIR__ . '/maintenance/cleanupUsersWithNoId.php',
+       'CleanupWatchlist' => __DIR__ . '/maintenance/cleanupWatchlist.php',
        'ClearInterwikiCache' => __DIR__ . '/maintenance/clearInterwikiCache.php',
        'ClearUserWatchlistJob' => __DIR__ . '/includes/jobqueue/jobs/ClearUserWatchlistJob.php',
        'ClearWatchlistNotificationsJob' => __DIR__ . '/includes/jobqueue/jobs/ClearWatchlistNotificationsJob.php',
@@ -279,7 +283,6 @@ $wgAutoloadLocalClasses = [
        'Collation' => __DIR__ . '/includes/collation/Collation.php',
        'CollationCkb' => __DIR__ . '/includes/collation/CollationCkb.php',
        'CollationEt' => __DIR__ . '/includes/collation/CollationEt.php',
-       'CollationFa' => __DIR__ . '/includes/collation/CollationFa.php',
        'CommandLineInc' => __DIR__ . '/maintenance/commandLine.inc',
        'CommandLineInstaller' => __DIR__ . '/maintenance/install.php',
        'CommentStore' => __DIR__ . '/includes/CommentStore.php',
@@ -303,6 +306,7 @@ $wgAutoloadLocalClasses = [
        'Content' => __DIR__ . '/includes/content/Content.php',
        'ContentHandler' => __DIR__ . '/includes/content/ContentHandler.php',
        'ContentModelLogFormatter' => __DIR__ . '/includes/logging/ContentModelLogFormatter.php',
+       'ContentSecurityPolicy' => __DIR__ . '/includes/ContentSecurityPolicy.php',
        'ContextSource' => __DIR__ . '/includes/context/ContextSource.php',
        'ContribsPager' => __DIR__ . '/includes/specials/pagers/ContribsPager.php',
        'ConvertExtensionToRegistration' => __DIR__ . '/maintenance/convertExtensionToRegistration.php',
@@ -317,6 +321,7 @@ $wgAutoloadLocalClasses = [
        'CoreParserFunctions' => __DIR__ . '/includes/parser/CoreParserFunctions.php',
        'CoreTagHooks' => __DIR__ . '/includes/parser/CoreTagHooks.php',
        'CreateAndPromote' => __DIR__ . '/maintenance/createAndPromote.php',
+       'CreateCommonPasswordCdb' => __DIR__ . '/maintenance/createCommonPasswordCdb.php',
        'CreateFileOp' => __DIR__ . '/includes/libs/filebackend/fileop/CreateFileOp.php',
        'CreditsAction' => __DIR__ . '/includes/actions/CreditsAction.php',
        'CrhConverter' => __DIR__ . '/languages/classes/LanguageCrh.php',
@@ -359,6 +364,7 @@ $wgAutoloadLocalClasses = [
        'DateFormats' => __DIR__ . '/maintenance/language/date-formats.php',
        'DateFormatter' => __DIR__ . '/includes/parser/DateFormatter.php',
        'DeadendPagesPage' => __DIR__ . '/includes/specials/SpecialDeadendpages.php',
+       'DeduplicateArchiveRevId' => __DIR__ . '/maintenance/deduplicateArchiveRevId.php',
        'DeferrableCallback' => __DIR__ . '/includes/deferred/DeferrableCallback.php',
        'DeferrableUpdate' => __DIR__ . '/includes/deferred/DeferrableUpdate.php',
        'DeferredStringifier' => __DIR__ . '/includes/libs/DeferredStringifier.php',
@@ -425,6 +431,7 @@ $wgAutoloadLocalClasses = [
        'DumpRenderer' => __DIR__ . '/maintenance/renderDump.php',
        'DumpRev' => __DIR__ . '/maintenance/storage/dumpRev.php',
        'DumpStringOutput' => __DIR__ . '/includes/export/DumpStringOutput.php',
+       'DumpUploads' => __DIR__ . '/maintenance/dumpUploads.php',
        'DuplicateJob' => __DIR__ . '/includes/jobqueue/jobs/DuplicateJob.php',
        'EditAction' => __DIR__ . '/includes/actions/EditAction.php',
        'EditCLI' => __DIR__ . '/maintenance/edit.php',
@@ -510,6 +517,7 @@ $wgAutoloadLocalClasses = [
        'FileJournal' => __DIR__ . '/includes/libs/filebackend/filejournal/FileJournal.php',
        'FileOp' => __DIR__ . '/includes/libs/filebackend/fileop/FileOp.php',
        'FileOpBatch' => __DIR__ . '/includes/libs/filebackend/FileOpBatch.php',
+       'FileOpPerfTest' => __DIR__ . '/maintenance/fileOpPerfTest.php',
        'FileRepo' => __DIR__ . '/includes/filerepo/FileRepo.php',
        'FileRepoStatus' => __DIR__ . '/includes/filerepo/FileRepoStatus.php',
        'FindDeprecated' => __DIR__ . '/maintenance/findDeprecated.php',
@@ -533,6 +541,7 @@ $wgAutoloadLocalClasses = [
        'FormAction' => __DIR__ . '/includes/actions/FormAction.php',
        'FormOptions' => __DIR__ . '/includes/FormOptions.php',
        'FormSpecialPage' => __DIR__ . '/includes/specialpage/FormSpecialPage.php',
+       'FormatInstallDoc' => __DIR__ . '/maintenance/formatInstallDoc.php',
        'FormatJson' => __DIR__ . '/includes/json/FormatJson.php',
        'FormatMetadata' => __DIR__ . '/includes/media/FormatMetadata.php',
        'FormattedRCFeed' => __DIR__ . '/includes/rcfeed/FormattedRCFeed.php',
@@ -542,7 +551,6 @@ $wgAutoloadLocalClasses = [
        'GanConverter' => __DIR__ . '/languages/classes/LanguageGan.php',
        'GenderCache' => __DIR__ . '/includes/cache/GenderCache.php',
        'GenerateCollationData' => __DIR__ . '/maintenance/language/generateCollationData.php',
-       'GenerateCommonPassword' => __DIR__ . '/maintenance/createCommonPasswordCdb.php',
        'GenerateJsonI18n' => __DIR__ . '/maintenance/generateJsonI18n.php',
        'GenerateNormalizerDataAr' => __DIR__ . '/maintenance/language/generateNormalizerDataAr.php',
        'GenerateNormalizerDataMl' => __DIR__ . '/maintenance/language/generateNormalizerDataMl.php',
@@ -550,7 +558,7 @@ $wgAutoloadLocalClasses = [
        'GenericArrayObject' => __DIR__ . '/includes/libs/GenericArrayObject.php',
        'GetConfiguration' => __DIR__ . '/maintenance/getConfiguration.php',
        'GetLagTimes' => __DIR__ . '/maintenance/getLagTimes.php',
-       'GetSlaveServer' => __DIR__ . '/maintenance/getReplicaServer.php',
+       'GetReplicaServer' => __DIR__ . '/maintenance/getReplicaServer.php',
        'GetTextMaint' => __DIR__ . '/maintenance/getText.php',
        'GitInfo' => __DIR__ . '/includes/GitInfo.php',
        'GlobalDependency' => __DIR__ . '/includes/cache/CacheDependency.php',
@@ -617,7 +625,7 @@ $wgAutoloadLocalClasses = [
        'Http' => __DIR__ . '/includes/http/Http.php',
        'HttpError' => __DIR__ . '/includes/exception/HttpError.php',
        'HttpStatus' => __DIR__ . '/includes/libs/HttpStatus.php',
-       'IApiMessage' => __DIR__ . '/includes/api/ApiMessage.php',
+       'IApiMessage' => __DIR__ . '/includes/api/IApiMessage.php',
        'IBufferingStatsdDataFactory' => __DIR__ . '/includes/libs/stats/IBufferingStatsdDataFactory.php',
        'ICacheHelper' => __DIR__ . '/includes/cache/CacheHelper.php',
        'IContextSource' => __DIR__ . '/includes/context/IContextSource.php',
@@ -635,7 +643,6 @@ $wgAutoloadLocalClasses = [
        'IcuCollation' => __DIR__ . '/includes/collation/IcuCollation.php',
        'IdentityCollation' => __DIR__ . '/includes/collation/IdentityCollation.php',
        'ImageBuilder' => __DIR__ . '/maintenance/rebuildImages.php',
-       'ImageCleanup' => __DIR__ . '/maintenance/cleanupImages.php',
        'ImageGalleryBase' => __DIR__ . '/includes/gallery/ImageGalleryBase.php',
        'ImageHandler' => __DIR__ . '/includes/media/ImageHandler.php',
        'ImageHistoryList' => __DIR__ . '/includes/page/ImageHistoryList.php',
@@ -828,7 +835,6 @@ $wgAutoloadLocalClasses = [
        'MainConfigDependency' => __DIR__ . '/includes/cache/CacheDependency.php',
        'MaintainableDBConnRef' => __DIR__ . '/includes/libs/rdbms/database/MaintainableDBConnRef.php',
        'Maintenance' => __DIR__ . '/maintenance/Maintenance.php',
-       'MaintenanceFormatInstallDoc' => __DIR__ . '/maintenance/formatInstallDoc.php',
        'MakeTestEdits' => __DIR__ . '/maintenance/makeTestEdits.php',
        'MalformedTitleException' => __DIR__ . '/includes/title/MalformedTitleException.php',
        'ManageJobs' => __DIR__ . '/maintenance/manageJobs.php',
@@ -885,9 +891,6 @@ $wgAutoloadLocalClasses = [
        'MediaWiki\\Auth\\UsernameAuthenticationRequest' => __DIR__ . '/includes/auth/UsernameAuthenticationRequest.php',
        'MediaWiki\\Diff\\ComplexityException' => __DIR__ . '/includes/diff/ComplexityException.php',
        'MediaWiki\\Diff\\WordAccumulator' => __DIR__ . '/includes/diff/WordAccumulator.php',
-       'MediaWiki\\EditPage\\TextConflictHelper' => __DIR__ . '/includes/editpage/TextConflictHelper.php',
-       'MediaWiki\\EditPage\\TextboxBuilder' => __DIR__ . '/includes/editpage/TextboxBuilder.php',
-       'MediaWiki\\Edit\\PreparedEdit' => __DIR__ . '/includes/edit/PreparedEdit.php',
        'MediaWiki\\HeaderCallback' => __DIR__ . '/includes/HeaderCallback.php',
        'MediaWiki\\Http\\HttpRequestFactory' => __DIR__ . '/includes/http/HttpRequestFactory.php',
        'MediaWiki\\Interwiki\\ClassicInterwikiLookup' => __DIR__ . '/includes/interwiki/ClassicInterwikiLookup.php',
@@ -915,72 +918,10 @@ $wgAutoloadLocalClasses = [
        'MediaWiki\\Logger\\Spi' => __DIR__ . '/includes/debug/logger/Spi.php',
        'MediaWiki\\MediaWikiServices' => __DIR__ . '/includes/MediaWikiServices.php',
        'MediaWiki\\OutputHandler' => __DIR__ . '/includes/OutputHandler.php',
-       'MediaWiki\\Preferences\\DefaultPreferencesFactory' => __DIR__ . '/includes/preferences/DefaultPreferencesFactory.php',
-       'MediaWiki\\Preferences\\PreferencesFactory' => __DIR__ . '/includes/preferences/PreferencesFactory.php',
        'MediaWiki\\ProcOpenError' => __DIR__ . '/includes/exception/ProcOpenError.php',
        'MediaWiki\\Search\\ParserOutputSearchDataExtractor' => __DIR__ . '/includes/search/ParserOutputSearchDataExtractor.php',
-       'MediaWiki\\Services\\CannotReplaceActiveServiceException' => __DIR__ . '/includes/services/CannotReplaceActiveServiceException.php',
-       'MediaWiki\\Services\\ContainerDisabledException' => __DIR__ . '/includes/services/ContainerDisabledException.php',
-       'MediaWiki\\Services\\DestructibleService' => __DIR__ . '/includes/services/DestructibleService.php',
-       'MediaWiki\\Services\\NoSuchServiceException' => __DIR__ . '/includes/services/NoSuchServiceException.php',
-       'MediaWiki\\Services\\SalvageableService' => __DIR__ . '/includes/services/SalvageableService.php',
-       'MediaWiki\\Services\\ServiceAlreadyDefinedException' => __DIR__ . '/includes/services/ServiceAlreadyDefinedException.php',
-       'MediaWiki\\Services\\ServiceContainer' => __DIR__ . '/includes/services/ServiceContainer.php',
-       'MediaWiki\\Services\\ServiceDisabledException' => __DIR__ . '/includes/services/ServiceDisabledException.php',
-       'MediaWiki\\Session\\BotPasswordSessionProvider' => __DIR__ . '/includes/session/BotPasswordSessionProvider.php',
-       'MediaWiki\\Session\\CookieSessionProvider' => __DIR__ . '/includes/session/CookieSessionProvider.php',
-       'MediaWiki\\Session\\ImmutableSessionProviderWithCookie' => __DIR__ . '/includes/session/ImmutableSessionProviderWithCookie.php',
-       'MediaWiki\\Session\\MetadataMergeException' => __DIR__ . '/includes/session/MetadataMergeException.php',
-       'MediaWiki\\Session\\PHPSessionHandler' => __DIR__ . '/includes/session/PHPSessionHandler.php',
-       'MediaWiki\\Session\\Session' => __DIR__ . '/includes/session/Session.php',
-       'MediaWiki\\Session\\SessionBackend' => __DIR__ . '/includes/session/SessionBackend.php',
-       'MediaWiki\\Session\\SessionId' => __DIR__ . '/includes/session/SessionId.php',
-       'MediaWiki\\Session\\SessionInfo' => __DIR__ . '/includes/session/SessionInfo.php',
-       'MediaWiki\\Session\\SessionManager' => __DIR__ . '/includes/session/SessionManager.php',
-       'MediaWiki\\Session\\SessionManagerInterface' => __DIR__ . '/includes/session/SessionManagerInterface.php',
-       'MediaWiki\\Session\\SessionProvider' => __DIR__ . '/includes/session/SessionProvider.php',
-       'MediaWiki\\Session\\SessionProviderInterface' => __DIR__ . '/includes/session/SessionProviderInterface.php',
-       'MediaWiki\\Session\\Token' => __DIR__ . '/includes/session/Token.php',
-       'MediaWiki\\Session\\UserInfo' => __DIR__ . '/includes/session/UserInfo.php',
        'MediaWiki\\ShellDisabledError' => __DIR__ . '/includes/exception/ShellDisabledError.php',
-       'MediaWiki\\Shell\\Command' => __DIR__ . '/includes/shell/Command.php',
-       'MediaWiki\\Shell\\CommandFactory' => __DIR__ . '/includes/shell/CommandFactory.php',
-       'MediaWiki\\Shell\\FirejailCommand' => __DIR__ . '/includes/shell/FirejailCommand.php',
-       'MediaWiki\\Shell\\Result' => __DIR__ . '/includes/shell/Result.php',
-       'MediaWiki\\Shell\\Shell' => __DIR__ . '/includes/shell/Shell.php',
        'MediaWiki\\Site\\MediaWikiPageNameNormalizer' => __DIR__ . '/includes/site/MediaWikiPageNameNormalizer.php',
-       'MediaWiki\\Sparql\\SparqlClient' => __DIR__ . '/includes/sparql/SparqlClient.php',
-       'MediaWiki\\Sparql\\SparqlException' => __DIR__ . '/includes/sparql/SparqlException.php',
-       'MediaWiki\\Storage\\BlobAccessException' => __DIR__ . '/includes/Storage/BlobAccessException.php',
-       'MediaWiki\\Storage\\BlobStore' => __DIR__ . '/includes/Storage/BlobStore.php',
-       'MediaWiki\\Storage\\BlobStoreFactory' => __DIR__ . '/includes/Storage/BlobStoreFactory.php',
-       'MediaWiki\\Storage\\IncompleteRevisionException' => __DIR__ . '/includes/Storage/IncompleteRevisionException.php',
-       'MediaWiki\\Storage\\MutableRevisionRecord' => __DIR__ . '/includes/Storage/MutableRevisionRecord.php',
-       'MediaWiki\\Storage\\MutableRevisionSlots' => __DIR__ . '/includes/Storage/MutableRevisionSlots.php',
-       'MediaWiki\\Storage\\NameTableAccessException' => __DIR__ . '/includes/Storage/NameTableAccessException.php',
-       'MediaWiki\\Storage\\NameTableStore' => __DIR__ . '/includes/Storage/NameTableStore.php',
-       'MediaWiki\\Storage\\RevisionAccessException' => __DIR__ . '/includes/Storage/RevisionAccessException.php',
-       'MediaWiki\\Storage\\RevisionArchiveRecord' => __DIR__ . '/includes/Storage/RevisionArchiveRecord.php',
-       'MediaWiki\\Storage\\RevisionFactory' => __DIR__ . '/includes/Storage/RevisionFactory.php',
-       'MediaWiki\\Storage\\RevisionLookup' => __DIR__ . '/includes/Storage/RevisionLookup.php',
-       'MediaWiki\\Storage\\RevisionRecord' => __DIR__ . '/includes/Storage/RevisionRecord.php',
-       'MediaWiki\\Storage\\RevisionSlots' => __DIR__ . '/includes/Storage/RevisionSlots.php',
-       'MediaWiki\\Storage\\RevisionSlotsUpdate' => __DIR__ . '/includes/Storage/RevisionSlotsUpdate.php',
-       'MediaWiki\\Storage\\RevisionStore' => __DIR__ . '/includes/Storage/RevisionStore.php',
-       'MediaWiki\\Storage\\RevisionStoreRecord' => __DIR__ . '/includes/Storage/RevisionStoreRecord.php',
-       'MediaWiki\\Storage\\SlotRecord' => __DIR__ . '/includes/Storage/SlotRecord.php',
-       'MediaWiki\\Storage\\SqlBlobStore' => __DIR__ . '/includes/Storage/SqlBlobStore.php',
-       'MediaWiki\\Storage\\SuppressedDataException' => __DIR__ . '/includes/Storage/SuppressedDataException.php',
-       'MediaWiki\\Tidy\\RaggettBase' => __DIR__ . '/includes/tidy/RaggettBase.php',
-       'MediaWiki\\Tidy\\RaggettExternal' => __DIR__ . '/includes/tidy/RaggettExternal.php',
-       'MediaWiki\\Tidy\\RaggettInternalHHVM' => __DIR__ . '/includes/tidy/RaggettInternalHHVM.php',
-       'MediaWiki\\Tidy\\RaggettInternalPHP' => __DIR__ . '/includes/tidy/RaggettInternalPHP.php',
-       'MediaWiki\\Tidy\\RaggettWrapper' => __DIR__ . '/includes/tidy/RaggettWrapper.php',
-       'MediaWiki\\Tidy\\RemexCompatFormatter' => __DIR__ . '/includes/tidy/RemexCompatFormatter.php',
-       'MediaWiki\\Tidy\\RemexCompatMunger' => __DIR__ . '/includes/tidy/RemexCompatMunger.php',
-       'MediaWiki\\Tidy\\RemexDriver' => __DIR__ . '/includes/tidy/RemexDriver.php',
-       'MediaWiki\\Tidy\\RemexMungerData' => __DIR__ . '/includes/tidy/RemexMungerData.php',
-       'MediaWiki\\Tidy\\TidyDriverBase' => __DIR__ . '/includes/tidy/TidyDriverBase.php',
        'MediaWiki\\User\\UserIdentity' => __DIR__ . '/includes/user/UserIdentity.php',
        'MediaWiki\\User\\UserIdentityValue' => __DIR__ . '/includes/user/UserIdentityValue.php',
        'MediaWiki\\Widget\\ComplexNamespaceInputWidget' => __DIR__ . '/includes/widget/ComplexNamespaceInputWidget.php',
@@ -1057,7 +998,7 @@ $wgAutoloadLocalClasses = [
        'NaiveForeignTitleFactory' => __DIR__ . '/includes/title/NaiveForeignTitleFactory.php',
        'NaiveImportTitleFactory' => __DIR__ . '/includes/title/NaiveImportTitleFactory.php',
        'NamespaceAwareForeignTitleFactory' => __DIR__ . '/includes/title/NamespaceAwareForeignTitleFactory.php',
-       'NamespaceConflictChecker' => __DIR__ . '/maintenance/namespaceDupes.php',
+       'NamespaceDupes' => __DIR__ . '/maintenance/namespaceDupes.php',
        'NamespaceImportTitleFactory' => __DIR__ . '/includes/title/NamespaceImportTitleFactory.php',
        'NewFilesPager' => __DIR__ . '/includes/specials/pagers/NewFilesPager.php',
        'NewPagesPager' => __DIR__ . '/includes/specials/pagers/NewPagesPager.php',
@@ -1159,6 +1100,7 @@ $wgAutoloadLocalClasses = [
        'PopulateBacklinkNamespace' => __DIR__ . '/maintenance/populateBacklinkNamespace.php',
        'PopulateCategory' => __DIR__ . '/maintenance/populateCategory.php',
        'PopulateContentModel' => __DIR__ . '/maintenance/populateContentModel.php',
+       'PopulateExternallinksIndex60' => __DIR__ . '/maintenance/populateExternallinksIndex60.php',
        'PopulateFilearchiveSha1' => __DIR__ . '/maintenance/populateFilearchiveSha1.php',
        'PopulateImageSha1' => __DIR__ . '/maintenance/populateImageSha1.php',
        'PopulateInterwiki' => __DIR__ . '/maintenance/populateInterwiki.php',
@@ -1174,7 +1116,7 @@ $wgAutoloadLocalClasses = [
        'PostgresInstaller' => __DIR__ . '/includes/installer/PostgresInstaller.php',
        'PostgresUpdater' => __DIR__ . '/includes/installer/PostgresUpdater.php',
        'Preferences' => __DIR__ . '/includes/Preferences.php',
-       'PreferencesForm' => __DIR__ . '/includes/specials/forms/PreferencesForm.php',
+       'PreferencesForm' => __DIR__ . '/includes/specials/forms/PreferencesFormLegacy.php',
        'PreferencesFormLegacy' => __DIR__ . '/includes/specials/forms/PreferencesFormLegacy.php',
        'PreferencesFormOOUI' => __DIR__ . '/includes/specials/forms/PreferencesFormOOUI.php',
        'PrefixSearch' => __DIR__ . '/includes/PrefixSearch.php',
@@ -1330,6 +1272,7 @@ $wgAutoloadLocalClasses = [
        'RollbackAction' => __DIR__ . '/includes/actions/RollbackAction.php',
        'RollbackEdits' => __DIR__ . '/maintenance/rollbackEdits.php',
        'RowUpdateGenerator' => __DIR__ . '/includes/utils/RowUpdateGenerator.php',
+       'RunBatchedQuery' => __DIR__ . '/maintenance/runBatchedQuery.php',
        'RunJobs' => __DIR__ . '/maintenance/runJobs.php',
        'SVGMetadataExtractor' => __DIR__ . '/includes/media/SVGMetadataExtractor.php',
        'SVGReader' => __DIR__ . '/includes/media/SVGMetadataExtractor.php',
@@ -1442,6 +1385,7 @@ $wgAutoloadLocalClasses = [
        'SpecialPageFactory' => __DIR__ . '/includes/specialpage/SpecialPageFactory.php',
        'SpecialPageLanguage' => __DIR__ . '/includes/specials/SpecialPageLanguage.php',
        'SpecialPagesWithProp' => __DIR__ . '/includes/specials/SpecialPagesWithProp.php',
+       'SpecialPasswordPolicies' => __DIR__ . '/includes/specials/SpecialPasswordPolicies.php',
        'SpecialPasswordReset' => __DIR__ . '/includes/specials/SpecialPasswordReset.php',
        'SpecialPermanentLink' => __DIR__ . '/includes/specials/SpecialPermanentLink.php',
        'SpecialPreferences' => __DIR__ . '/includes/specials/SpecialPreferences.php',
@@ -1516,7 +1460,6 @@ $wgAutoloadLocalClasses = [
        'TempFileRepo' => __DIR__ . '/includes/filerepo/TempFileRepo.php',
        'TemplateParser' => __DIR__ . '/includes/TemplateParser.php',
        'TemplatesOnThisPageFormatter' => __DIR__ . '/includes/TemplatesOnThisPageFormatter.php',
-       'TestFileOpPerformance' => __DIR__ . '/maintenance/fileOpPerfTest.php',
        'TextContent' => __DIR__ . '/includes/content/TextContent.php',
        'TextContentHandler' => __DIR__ . '/includes/content/TextContentHandler.php',
        'TextPassDumper' => __DIR__ . '/maintenance/dumpTextPass.php',
@@ -1574,7 +1517,6 @@ $wgAutoloadLocalClasses = [
        'UploadChunkFileException' => __DIR__ . '/includes/upload/UploadFromChunks.php',
        'UploadChunkVerificationException' => __DIR__ . '/includes/upload/UploadFromChunks.php',
        'UploadChunkZeroLengthFileException' => __DIR__ . '/includes/upload/UploadFromChunks.php',
-       'UploadDumper' => __DIR__ . '/maintenance/dumpUploads.php',
        'UploadForm' => __DIR__ . '/includes/specials/forms/UploadForm.php',
        'UploadFromChunks' => __DIR__ . '/includes/upload/UploadFromChunks.php',
        'UploadFromFile' => __DIR__ . '/includes/upload/UploadFromFile.php',
@@ -1586,7 +1528,6 @@ $wgAutoloadLocalClasses = [
        'UploadSourceField' => __DIR__ . '/includes/specials/formfields/UploadSourceField.php',
        'UploadStash' => __DIR__ . '/includes/upload/UploadStash.php',
        'UploadStashBadPathException' => __DIR__ . '/includes/upload/UploadStash.php',
-       'UploadStashCleanup' => __DIR__ . '/maintenance/cleanupUploadStash.php',
        'UploadStashException' => __DIR__ . '/includes/upload/UploadStash.php',
        'UploadStashFile' => __DIR__ . '/includes/upload/UploadStash.php',
        'UploadStashFileException' => __DIR__ . '/includes/upload/UploadStash.php',
@@ -1596,7 +1537,7 @@ $wgAutoloadLocalClasses = [
        'UploadStashWrongOwnerException' => __DIR__ . '/includes/upload/UploadStash.php',
        'UploadStashZeroLengthFileException' => __DIR__ . '/includes/upload/UploadStash.php',
        'UppercaseCollation' => __DIR__ . '/includes/collation/UppercaseCollation.php',
-       'UsageException' => __DIR__ . '/includes/api/ApiUsageException.php',
+       'UsageException' => __DIR__ . '/includes/api/UsageException.php',
        'User' => __DIR__ . '/includes/user/User.php',
        'UserArray' => __DIR__ . '/includes/user/UserArray.php',
        'UserArrayFromResult' => __DIR__ . '/includes/user/UserArrayFromResult.php',
@@ -1636,7 +1577,6 @@ $wgAutoloadLocalClasses = [
        'WatchedItemQueryServiceExtension' => __DIR__ . '/includes/watcheditem/WatchedItemQueryServiceExtension.php',
        'WatchedItemStore' => __DIR__ . '/includes/watcheditem/WatchedItemStore.php',
        'WatchedItemStoreInterface' => __DIR__ . '/includes/watcheditem/WatchedItemStoreInterface.php',
-       'WatchlistCleanup' => __DIR__ . '/maintenance/cleanupWatchlist.php',
        'WebInstaller' => __DIR__ . '/includes/installer/WebInstaller.php',
        'WebInstallerComplete' => __DIR__ . '/includes/installer/WebInstallerComplete.php',
        'WebInstallerCopying' => __DIR__ . '/includes/installer/WebInstallerCopying.php',
index 8de4025..ce137d1 100644 (file)
@@ -1,6 +1,7 @@
 {
        "name": "mediawiki/core",
        "description": "Free software wiki application developed by the Wikimedia Foundation and others",
+       "type": "mediawiki-core",
        "keywords": ["mediawiki", "wiki"],
        "homepage": "https://www.mediawiki.org/",
        "authors": [
                "liuggio/statsd-php-client": "1.0.18",
                "oojs/oojs-ui": "0.27.0",
                "oyejorge/less.php": "1.7.0.14",
-               "php": ">=5.5.9",
+               "pear/mail": "1.4.1",
+               "pear/mail_mime": "1.10.2",
+               "pear/mail_mime-decode": "1.5.5.2",
+               "php": ">=5.6.99",
                "psr/log": "1.0.2",
                "wikimedia/assert": "0.2.2",
                "wikimedia/at-ease": "1.2.0",
@@ -46,7 +50,7 @@
                "wikimedia/utfnormal": "2.0.0",
                "wikimedia/timestamp": "1.0.0",
                "wikimedia/wait-condition-loop": "1.0.1",
-               "wikimedia/wrappedstring": "2.3.0",
+               "wikimedia/wrappedstring": "3.0.0",
                "zordius/lightncandy": "0.23"
        },
        "require-dev": {
@@ -55,7 +59,7 @@
                "jakub-onderka/php-parallel-lint": "0.9.2",
                "jetbrains/phpstorm-stubs": "dev-master#1b9906084d6635456fcf3f3a01f0d7d5b99a578a",
                "justinrainbow/json-schema": "~5.2",
-               "mediawiki/mediawiki-codesniffer": "17.0.0",
+               "mediawiki/mediawiki-codesniffer": "18.0.0",
                "monolog/monolog": "~1.22.1",
                "nikic/php-parser": "3.1.3",
                "nmred/kafka-php": "0.1.5",
                "ext-wikidiff2": "Diff accelerator",
                "monolog/monolog": "Flexible debug logging system",
                "nmred/kafka-php": "Send debug log events to kafka",
-               "pear/mail": "Mail sending support",
-               "pear/mail_mime": "Mail sending support",
-               "pear/mail_mime-decode": "Mail sending support",
                "wikimedia/avro": "Binary serialization format used with kafka"
        },
        "autoload": {
                "psr-0": {
                        "ComposerHookHandler": "includes/composer",
                        "ComposerVendorHtaccessCreator": "includes/composer"
-               },
-               "files": [
-                       "includes/compat/Timestamp.php"
-               ]
+               }
        },
        "autoload-dev": {
                "files": [
index 0763e7d..bcfd2aa 100644 (file)
                },
                "AutoloadNamespaces": {
                        "type": "object",
-                       "description": "Mapping of PSR-4 compliant namespace to directory for autoloading"
+                       "description": "Mapping of PSR-4 compliant namespace to directory for autoloading",
+                       "patternProperties": {
+                               "^[A-Za-z0-9\\\\]+\\\\$": {
+                                       "type": "string"
+                               }
+                       },
+                       "additionalProperties": false
                },
                "AutoloadClasses": {
                        "type": "object"
index e13129b..31edbd0 100644 (file)
                },
                "AutoloadNamespaces": {
                        "type": "object",
-                       "description": "Mapping of PSR-4 compliant namespace to directory for autoloading"
+                       "description": "Mapping of PSR-4 compliant namespace to directory for autoloading",
+                       "patternProperties": {
+                               "^[A-Za-z0-9\\\\]+\\\\$": {
+                                       "type": "string"
+                               }
+                       },
+                       "additionalProperties": false
                },
                "AutoloadClasses": {
                        "type": "object"
index b38bd66..349cd4b 100644 (file)
@@ -1186,6 +1186,31 @@ $lossy:   boolean indicating whether lossy conversion is allowed.
   converted Content object. Note that $result->getContentModel() must return
   $toModel.
 
+'ContentSecurityPolicyDefaultSource': Modify the allowed CSP load sources. This affects all
+directives except for the script directive. If you want to add a script
+source, see ContentSecurityPolicyScriptSource hook.
+&$defaultSrc: Array of Content-Security-Policy allowed sources
+$policyConfig: Current configuration for the Content-Security-Policy header
+$mode: ContentSecurityPolicy::REPORT_ONLY_MODE or ContentSecurityPolicy::FULL_MODE
+  depending on type of header
+
+'ContentSecurityPolicyDirectives': Modify the content security policy directives.
+Use this only if ContentSecurityPolicyDefaultSource and
+ContentSecurityPolicyScriptSource do not meet your needs.
+&$directives: Array of CSP directives
+$policyConfig: Current configuration for the CSP header
+$mode: ContentSecurityPolicy::REPORT_ONLY_MODE or
+  ContentSecurityPolicy::FULL_MODE depending on type of header
+
+'ContentSecurityPolicyScriptSource': Modify the allowed CSP script sources.
+Note that you also have to use ContentSecurityPolicyDefaultSource if you
+want non-script sources to be loaded from
+whatever you add.
+&$scriptSrc: Array of CSP directives
+$policyConfig: Current configuration for the CSP header
+$mode: ContentSecurityPolicy::REPORT_ONLY_MODE or ContentSecurityPolicy::FULL_MODE
+  depending on type of header
+
 'CustomEditor': When invoking the page editor
 Return true to allow the normal editor to be used, or false if implementing
 a custom editor, e.g. for a special namespace, etc.
@@ -2691,14 +2716,14 @@ Occurs after signing up or logging in, allows for interception of redirect.
 
 'PreferencesFormPreSave': Override preferences being saved
 $formData: array of user submitted data
-$form: PreferencesForm object, also a ContextSource
+$form: HTMLForm object, also a ContextSource
 $user: User object with preferences to be saved set
 &$result: boolean indicating success
 $oldUserOptions: array with user old options (before save)
 
 'PreferencesGetLegend': Override the text used for the <legend> of a
 preferences section.
-$form: the PreferencesForm object. This is a ContextSource as well
+$form: the HTMLForm object. This is a ContextSource as well
 $key: the section name
 &$legend: the legend text. Defaults to wfMessage( "prefs-$key" )->text() but may
   be overridden
index 0b4e0bd..8dff602 100644 (file)
@@ -58,7 +58,7 @@ These can also be customised on a per-user basis, by editing
 
 Several custom skins are available as of 2014.
 
-https://www.mediawiki.org/wiki/Category:All_skins
+https://www.mediawiki.org/wiki/Special:MyLanguage/Category:All_skins
 
 Installing a skin requires adding its files in a subdirectory under skins/ and
 adding an appropriate require_once line to LocalSettings.php, similarly to how
index 75fcff3..35b556d 100644 (file)
@@ -23,6 +23,9 @@
 
 use MediaWiki\MediaWikiServices;
 
+// Use superglobals, but since it's deprecated, it's not worth fixing
+// phpcs:disable MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals
+
 /**
  * @defgroup Ajax Ajax
  */
index 52410fe..9fc063a 100644 (file)
@@ -82,7 +82,7 @@ class AutoLoader {
                                if ( isset( self::$psr4Namespaces[$prefix] ) ) {
                                        $relativeClass = substr( $className, $pos + 1 );
                                        // Build the expected filename, and see if it exists
-                                       $file = self::$psr4Namespaces[$prefix] .
+                                       $file = self::$psr4Namespaces[$prefix] . '/' .
                                                str_replace( '\\', '/', $relativeClass ) . '.php';
                                        if ( file_exists( $file ) ) {
                                                $filename = $file;
@@ -123,12 +123,22 @@ class AutoLoader {
         *
         * @see <http://www.php-fig.org/psr/psr-4/>
         * @private Only public for usage in AutoloadGenerator
+        * @codeCoverageIgnore
         * @since 1.31
         * @return string[]
         */
        public static function getAutoloadNamespaces() {
                return [
-                       'MediaWiki\\Linker\\' => __DIR__ .'/linker/'
+                       'MediaWiki\\Edit\\' => __DIR__ . '/edit/',
+                       'MediaWiki\\EditPage\\' => __DIR__ . '/editpage/',
+                       'MediaWiki\\Linker\\' => __DIR__ .'/linker/',
+                       'MediaWiki\\Preferences\\' => __DIR__ .'/preferences/',
+                       'MediaWiki\\Services\\' => __DIR__ .'/services/',
+                       'MediaWiki\\Session\\' => __DIR__ .'/session/',
+                       'MediaWiki\\Shell\\' => __DIR__ .'/shell/',
+                       'MediaWiki\\Sparql\\' => __DIR__ .'/sparql/',
+                       'MediaWiki\\Storage\\' => __DIR__ .'/Storage/',
+                       'MediaWiki\\Tidy\\' => __DIR__ .'/tidy/',
                ];
        }
 }
index 2bae13b..2ce1f3e 100644 (file)
@@ -521,7 +521,7 @@ class Block {
         *
         * @param IDatabase $dbw If you have one available
         * @return bool|array False on failure, assoc array on success:
-        *      ('id' => block ID, 'autoIds' => array of autoblock IDs)
+        *      ('id' => block ID, 'autoIds' => array of autoblock IDs)
         */
        public function insert( $dbw = null ) {
                global $wgBlockDisablesLogin;
diff --git a/includes/ContentSecurityPolicy.php b/includes/ContentSecurityPolicy.php
new file mode 100644 (file)
index 0000000..66a3535
--- /dev/null
@@ -0,0 +1,530 @@
+<?php
+/**
+ * Handle sending Content-Security-Policy headers
+ *
+ * @see https://www.w3.org/TR/CSP2/
+ *
+ * Copyright © 2015–2018 Brian Wolff
+ *
+ * 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.32
+ * @file
+ */
+class ContentSecurityPolicy {
+       const REPORT_ONLY_MODE = 1;
+       const FULL_MODE = 2;
+       /** Used for meta tag. Does not include report urls or nonce sources */
+       const FULL_MODE_RESTRICTED = 3;
+
+       /** @var string The nonce to use for inline scripts (from OutputPage) */
+       private $nonce;
+       /** @var Config The site configuration object */
+       private $mwConfig;
+       /** @var WebResponse */
+       private $response;
+
+       /**
+        * @param string $nonce
+        * @param WebResponse $response
+        * @param Config $mwConfig
+        */
+       public function __construct( $nonce, WebResponse $response, Config $mwConfig ) {
+               $this->nonce = $nonce;
+               $this->response = $response;
+               $this->mwConfig = $mwConfig;
+       }
+
+       /**
+        * Send a single CSP header based on a given policy config.
+        *
+        * @note Most callers will probably want ContentSecurityPolicy::sendHeaders() instead.
+        * @param array $csp ContentSecurityPolicy configuration
+        * @param int $reportOnly self::*_MODE constant
+        */
+       public function sendCSPHeader( $csp, $reportOnly ) {
+               $policy = $this->makeCSPDirectives( $csp, $reportOnly );
+               $headerName = $this->getHeaderName( $reportOnly );
+               if ( $policy ) {
+                       $this->response->header(
+                               "$headerName: $policy"
+                       );
+               }
+       }
+
+       /**
+        * Return the meta header to use for after load restricted mode
+        *
+        * This should restrict browsers that don't support nonce-sources.
+        * Idea stolen from
+        * https://blogs.dropbox.com/tech/2015/09/unsafe-inline-and-nonce-deployment/
+        *
+        * @param array $csp CSP configuration
+        * @return string Content for meta tag
+        */
+       public function getMetaHeader( $csp ) {
+               return $this->makeCSPDirectives( $csp, self::FULL_MODE_RESTRICTED );
+       }
+
+       /**
+        * Send CSP headers based on wiki config
+        *
+        * Main method that callers are expected to use
+        * @param IContextSource $context A context object, the associated OutputPage
+        *  object must be the one that the page in question was generated with.
+        */
+       public static function sendHeaders( IContextSource $context ) {
+               $out = $context->getOutput();
+               $csp = new ContentSecurityPolicy(
+                       $out->getCSPNonce(),
+                       $context->getRequest()->response(),
+                       $context->getConfig()
+               );
+
+               $cspConfig = $context->getConfig()->get( 'CSPHeader' );
+               $cspConfigReportOnly = $context->getConfig()->get( 'CSPReportOnlyHeader' );
+
+               $csp->sendCSPHeader( $cspConfig, self::FULL_MODE );
+               $csp->sendCSPHeader( $cspConfigReportOnly, self::REPORT_ONLY_MODE );
+
+               // Include <meta> header which increases security level after initial load.
+               // This helps mitigate attacks on browsers not supporting CSP2. It also
+               // helps mitigate attacks due to the shared nonce that non-logged in users
+               // get due to varnish cache.
+               // Unclear if this is the best place to insert the meta tag, or if
+               // it should be in a RL module. I figure its best to do this as early
+               // as possible.
+               // FIXME: Needs testing to see if this actually works properly
+               $metaHeader = $csp->getMetaHeader( $cspConfig );
+               if ( $metaHeader ) {
+                       $context->getOutput()->addScript(
+                               ResourceLoader::makeInlineScript(
+                                       $csp->makeMetaInsertScript(
+                                               $metaHeader
+                                       ),
+                                       $out->getCSPNonce()
+                               )
+                       );
+               }
+       }
+
+       /**
+        * Makes javascript to insert a meta CSP header after page load
+        *
+        * @see https://blogs.dropbox.com/tech/2015/09/unsafe-inline-and-nonce-deployment/
+        * @param string $metaContents content of meta tag
+        * @return string JS for including in page
+        */
+       private function makeMetaInsertScript( $metaContents ) {
+               return "$('\\x3Cmeta http-equiv=\"Content-Security-Policy\"\\x3E')" .
+                       '.attr("content",' .
+                       Xml::encodeJsVar( $metaContents ) .
+                       ').prependTo($("head"))';
+       }
+
+       /**
+        * Get the name of the HTTP header to use.
+        *
+        * @param int $reportOnly Either self::REPORT_ONLY_MODE or self::FULL_MODE
+        * @return string Name of http header
+        * @throws UnexpectedValueException if you feed it self::FULL_MODE_RESTRICTED.
+        */
+       private function getHeaderName( $reportOnly ) {
+               if ( $reportOnly === self::REPORT_ONLY_MODE ) {
+                       return 'Content-Security-Policy-Report-Only';
+               } elseif ( $reportOnly === self::FULL_MODE ) {
+                       return 'Content-Security-Policy';
+               }
+               throw new UnexpectedValueException( $reportOnly );
+       }
+
+       /**
+        * Determine what CSP policies to set for this page
+        *
+        * @param array|bool $config Policy configuration (Either $wgCSPHeader or $wgCSPReportOnlyHeader)
+        * @param int $mode self::REPORT_ONLY_MODE, self::FULL_MODE or Self::FULL_MODE_RESTRICTED
+        * @return string Policy directives, or empty string for no policy.
+        */
+       private function makeCSPDirectives( $policyConfig, $mode ) {
+               if ( $policyConfig === false ) {
+                       // CSP is disabled
+                       return '';
+               }
+               if ( $policyConfig === true ) {
+                       $policyConfig = [];
+               }
+
+               $mwConfig = $this->mwConfig;
+
+               $additionalSelfUrls = $this->getAdditionalSelfUrls();
+               $additionalSelfUrlsScript = $this->getAdditionalSelfUrlsScript();
+               $nonceSrc = "'nonce-" . $this->nonce . "'";
+
+               // If no default-src is sent at all, it
+               // seems browsers (or at least some), interpret
+               // that as allow anything, but the spec seems
+               // to imply that data: and blob: should be
+               // blocked.
+               $defaultSrc = [ '*', 'data:', 'blob:' ];
+
+               $cssSrc = false;
+               $imgSrc = false;
+               $scriptSrc = [ "'unsafe-eval'", "'self'" ];
+               if ( $mode !== self::FULL_MODE_RESTRICTED ) {
+                       $scriptSrc[] = $nonceSrc;
+               }
+               $scriptSrc = array_merge( $scriptSrc, $additionalSelfUrlsScript );
+               if ( isset( $policyConfig['script-src'] )
+                       && is_array( $policyConfig['script-src'] )
+               ) {
+                       foreach ( $policyConfig['script-src'] as $src ) {
+                               $scriptSrc[] = $this->escapeUrlForCSP( $src );
+                       }
+               }
+               // Note: default on if unspecified.
+               if ( ( !isset( $policyConfig['unsafeFallback'] )
+                       || $policyConfig['unsafeFallback'] )
+                       && $mode !== self::FULL_MODE_RESTRICTED
+               ) {
+                       // unsafe-inline should be ignored on browsers
+                       // that support 'nonce-foo' sources.
+                       // Some older versions of firefox don't follow this
+                       // rule, but new browsers do. (Should be for at least
+                       // firefox 40+).
+                       $scriptSrc[] = "'unsafe-inline'";
+               }
+               // If default source option set to true or
+               // an array of urls, set a restrictive default-src.
+               // If set to false, we send a lenient default-src,
+               // see the code above where $defaultSrc is set initially.
+               if ( isset( $policyConfig['default-src'] )
+                       && $policyConfig['default-src'] !== false
+               ) {
+                       $defaultSrc = array_merge(
+                               [ "'self'", 'data:', 'blob:' ],
+                               $additionalSelfUrls
+                       );
+                       if ( is_array( $policyConfig['default-src'] ) ) {
+                               foreach ( $policyConfig['default-src'] as $src ) {
+                                       $defaultSrc[] = $this->escapeUrlForCSP( $src );
+                               }
+                       }
+               }
+
+               if ( !isset( $policyConfig['includeCORS'] ) || $policyConfig['includeCORS'] ) {
+                       $CORSUrls = $this->getCORSSources();
+                       if ( !in_array( '*', $defaultSrc ) ) {
+                               $defaultSrc = array_merge( $defaultSrc, $CORSUrls );
+                       }
+                       // Unlikely to have * in scriptSrc, but doesn't
+                       // hurt to check.
+                       if ( !in_array( '*', $scriptSrc ) ) {
+                               $scriptSrc = array_merge( $scriptSrc, $CORSUrls );
+                       }
+               }
+
+               Hooks::run( 'ContentSecurityPolicyDefaultSource', [ &$defaultSrc, $policyConfig, $mode ] );
+               Hooks::run( 'ContentSecurityPolicyScriptSource', [ &$scriptSrc, $policyConfig, $mode ] );
+
+               // Check if array just in case the hook made it false
+               if ( is_array( $defaultSrc ) ) {
+                       $cssSrc = array_merge( $defaultSrc, [ "'unsafe-inline'" ] );
+               }
+
+               if ( $mode === self::FULL_MODE_RESTRICTED ) {
+                       // report-uri disallowed in <meta> tags.
+                       $reportUri = false;
+               } elseif ( isset( $policyConfig['report-uri'] ) && $policyConfig['report-uri'] !== true ) {
+                       if ( $policyConfig['report-uri'] === false ) {
+                               $reportUri = false;
+                       } else {
+                               $reportUri = $this->escapeUrlForCSP( $policyConfig['report-uri'] );
+                       }
+               } else {
+                       $reportUri = $this->getReportUri( $mode );
+               }
+
+               // Only send an img-src, if we're sending a restricitve default.
+               if ( !is_array( $defaultSrc )
+                       || !in_array( '*', $defaultSrc )
+                       || !in_array( 'data:', $defaultSrc )
+                       || !in_array( 'blob:', $defaultSrc )
+               ) {
+                       // A future todo might be to make the whitelist options only
+                       // add all the whitelisted sites to the header, instead of
+                       // allowing all (Assuming there is a small number of sites).
+                       // For now, the external image feature disables the limits
+                       // CSP puts on external images.
+                       if ( $mwConfig->get( 'AllowExternalImages' )
+                               || $mwConfig->get( 'AllowExternalImagesFrom' )
+                               || $mwConfig->get( 'AllowImageTag' )
+                       ) {
+                               $imgSrc = [ '*', 'data:', 'blob:' ];
+                       } elseif ( $mwConfig->get( 'EnableImageWhitelist' ) ) {
+                               $whitelist = wfMessage( 'external_image_whitelist' )
+                                       ->inContentLanguage()
+                                       ->plain();
+                               if ( preg_match( '/^\s*[^\s#]/m', $whitelist ) ) {
+                                       $imgSrc = [ '*', 'data:', 'blob:' ];
+                               }
+                       }
+               }
+
+               $directives = [];
+               if ( $scriptSrc ) {
+                       $directives[] = 'script-src ' . implode( ' ', $scriptSrc );
+               }
+               if ( $defaultSrc ) {
+                       $directives[] = 'default-src ' . implode( ' ', $defaultSrc );
+               }
+               if ( $cssSrc ) {
+                       $directives[] = 'style-src ' . implode( ' ', $cssSrc );
+               }
+               if ( $imgSrc ) {
+                       $directives[] = 'img-src ' . implode( ' ', $imgSrc );
+               }
+               if ( $reportUri ) {
+                       $directives[] = 'report-uri ' . $reportUri;
+               }
+
+               Hooks::run( 'ContentSecurityPolicyDirectives', [ &$directives, $policyConfig, $mode ] );
+
+               return implode( '; ', $directives );
+       }
+
+       /**
+        * Get the default report uri.
+        *
+        * @param int $mode self::*_MODE constant. Do not use with self::FULL_MODE_RESTRICTED
+        * @return string The URI to send reports to.
+        * @throws UnexpectedValueException if given invalid mode.
+        */
+       private function getReportUri( $mode ) {
+               if ( $mode === self::FULL_MODE_RESTRICTED ) {
+                       throw new UnexpectedValueException( $mode );
+               }
+               $apiArguments = [
+                       'action' => 'cspreport',
+                       'format' => 'json'
+               ];
+               if ( $mode === self::REPORT_ONLY_MODE ) {
+                       $apiArguments['reportonly'] = '1';
+               }
+               $reportUri = wfAppendQuery( wfScript( 'api' ), $apiArguments );
+
+               // Per spec, ';' and ',' must be hex-escaped in report uri
+               // Also add an & at the end of url to work around bug in hhvm
+               // with handling of POST parameters when always_decode_post_data
+               // is set to true. See https://github.com/facebook/hhvm/issues/6676
+               $reportUri = $this->escapeUrlForCSP( $reportUri ) . '&';
+               return $reportUri;
+       }
+
+       /**
+        * Given a url, convert to form needed for CSP.
+        *
+        * Currently this does either scheme + host, or
+        * if protocol relative, just the host. Future versions
+        * could potentially preserve some of the path, if its determined
+        * that that would be a good idea.
+        *
+        * @note This does the extra escaping for CSP, but assumes the url
+        *   has already had normal url escaping applied.
+        * @note This discards urls same as server name, as 'self' directive
+        *   takes care of that.
+        * @param string $url
+        * @return string|bool Converted url or false on failure
+        */
+       private function prepareUrlForCSP( $url ) {
+               $result = false;
+               if ( preg_match( '/^[a-z][a-z0-9+.-]*:$/i', $url ) ) {
+                       // A schema source (e.g. blob: or data:)
+                       return $url;
+               }
+               $bits = wfParseUrl( $url );
+               if ( !$bits && strpos( $url, '/' ) === false ) {
+                       // probably something like example.com.
+                       // try again protocol-relative.
+                       $url = '//' . $url;
+                       $bits = wfParseUrl( $url );
+               }
+               if ( $bits && isset( $bits['host'] )
+                       && $bits['host'] !== $this->mwConfig->get( 'ServerName' )
+               ) {
+                       $result = $bits['host'];
+                       if ( $bits['scheme'] !== '' ) {
+                               $result = $bits['scheme'] . $bits['delimiter'] . $result;
+                       }
+                       if ( isset( $bits['port'] ) ) {
+                               $result .= ':' . $bits['port'];
+                       }
+                       $result = $this->escapeUrlForCSP( $result );
+               }
+               return $result;
+       }
+
+       /**
+        * Get additional script sources
+        *
+        * @return array Additional sources for loading scripts from
+        */
+       private function getAdditionalSelfUrlsScript() {
+               $additionalUrls = [];
+               // wgExtensionAssetsPath for ?debug=true mode
+               $pathVars = [ 'LoadScript', 'ExtensionAssetsPath', 'ResourceBasePath' ];
+
+               foreach ( $pathVars as $path ) {
+                       $url = $this->mwConfig->get( $path );
+                       $preparedUrl = $this->prepareUrlForCSP( $url );
+                       if ( $preparedUrl ) {
+                               $additionalUrls[] = $preparedUrl;
+                       }
+               }
+               $RLSources = $this->mwConfig->get( 'ResourceLoaderSources' );
+               foreach ( $RLSources as $wiki => $sources ) {
+                       foreach ( $sources as $id => $value ) {
+                               $url = $this->prepareUrlForCSP( $value );
+                               if ( $url ) {
+                                       $additionalUrls[] = $url;
+                               }
+                       }
+               }
+
+               return array_unique( $additionalUrls );
+       }
+
+       /**
+        * Get additional host names for the wiki (e.g. if static content loaded elsewhere)
+        *
+        * @note These are general load sources, not script sources
+        * @return array Array of other urls for wiki (for use in default-src)
+        */
+       private function getAdditionalSelfUrls() {
+               // XXX on a foreign repo, the included description page can have anything on it,
+               // including inline scripts. But nobody sane does that.
+
+               // In principle, you can have even more complex configs... (e.g. The urlsByExt option)
+               $pathUrls = [];
+               $additionalSelfUrls = [];
+
+               // Future todo: The zone urls should never go into
+               // style-src. They should either be only in img-src, or if
+               // img-src unspecified they should be in default-src. Similarly,
+               // the DescriptionStylesheetUrl only needs to be in style-src
+               // (or default-src if style-src unspecified).
+               $callback = function ( $repo, &$urls ) {
+                       $urls[] = $repo->getZoneUrl( 'public' );
+                       $urls[] = $repo->getZoneUrl( 'transcoded' );
+                       $urls[] = $repo->getZoneUrl( 'thumb' );
+                       $urls[] = $repo->getDescriptionStylesheetUrl();
+               };
+               $localRepo = RepoGroup::singleton()->getRepo( 'local' );
+               $callback( $localRepo, $pathUrls );
+               RepoGroup::singleton()->forEachForeignRepo( $callback, [ &$pathUrls ] );
+
+               // Globals that might point to a different domain
+               $pathGlobals = [ 'LoadScript', 'ExtensionAssetsPath', 'StylePath', 'ResourceBasePath' ];
+               foreach ( $pathGlobals as $path ) {
+                       $pathUrls[] = $this->mwConfig->get( $path );
+               }
+               foreach ( $pathUrls as $path ) {
+                       $preparedUrl = $this->prepareUrlForCSP( $path );
+                       if ( $preparedUrl !== false ) {
+                               $additionalSelfUrls[] = $preparedUrl;
+                       }
+               }
+               $RLSources = $this->mwConfig->get( 'ResourceLoaderSources' );
+
+               foreach ( $RLSources as $wiki => $sources ) {
+                       foreach ( $sources as $id => $value ) {
+                               $url = $this->prepareUrlForCSP( $value );
+                               if ( $url ) {
+                                       $additionalSelfUrls[] = $url;
+                               }
+                       }
+               }
+
+               return array_unique( $additionalSelfUrls );
+       }
+
+       /**
+        * include domains that are allowed to send us CORS requests.
+        *
+        * Technically, $wgCrossSiteAJAXdomains lists things that are allowed to talk to us
+        * not things that we are allowed to talk to - but if something is allowed to talk to us,
+        * then there is a good chance that we should probably be allowed to talk to it.
+        *
+        * This is configurable with the 'includeCORS' key in the CSP config, and enabled
+        * by default.
+        * @note CORS domains with single character ('?') wildcards, are not included.
+        * @return array Additional hosts
+        */
+       private function getCORSSources() {
+               $additionalUrls = [];
+               $CORSSources = $this->mwConfig->get( 'CrossSiteAJAXdomains' );
+               foreach ( $CORSSources as $source ) {
+                       if ( strpos( $source, '?' ) !== false ) {
+                               // CSP doesn't support single char wildcard
+                               continue;
+                       }
+                       $url = $this->prepareUrlForCSP( $source );
+                       if ( $url ) {
+                               $additionalUrls[] = $url;
+                       }
+               }
+               return $additionalUrls;
+       }
+
+       /**
+        * CSP spec says ',' and ';' are not allowed to appear in urls.
+        *
+        * @note This assumes that normal escaping has been applied to the url
+        * @param string $url URL (or possibly just part of one)
+        * @return string
+        */
+       private function escapeUrlForCSP( $url ) {
+               return str_replace(
+                       [ ';', ',' ],
+                       [ '%3B', '%2C' ],
+                       $url
+               );
+       }
+
+       /**
+        * Does this browser give false positive reports?
+        *
+        * Some versions of firefox (40-42) incorrectly report a csp
+        * violation for nonce sources, despite allowing them.
+        *
+        * @see https://bugzilla.mozilla.org/show_bug.cgi?id=1026520
+        * @param string $ua User-agent header
+        * @return bool
+        */
+       public static function falsePositiveBrowser( $ua ) {
+               return (bool)preg_match( '!Firefox/4[0-2]\.!', $ua );
+       }
+
+       /**
+        * Is CSP currently enabled (i.e. Should we set nonce attribute)
+        *
+        * @param Config $config Configuration object
+        * @return bool
+        */
+       public static function isEnabled( Config $config ) {
+               return $config->get( 'CSPHeader' ) !== false
+                       || $config->get( 'CSPReportOnlyHeader' ) !== false;
+       }
+}
index dcf648e..562d887 100644 (file)
@@ -2565,17 +2565,6 @@ $wgCacheEpoch = '20030516000000';
  */
 $wgGitInfoCacheDirectory = false;
 
-/**
- * Bump this number when changing the global style sheets and JavaScript.
- *
- * It should be appended in the query string of static CSS and JS includes,
- * to ensure that client-side caches do not keep obsolete copies of global
- * styles.
- *
- * @deprecated since 1.31
- */
-$wgStyleVersion = '303';
-
 /**
  * This will cache static pages for non-logged-in users to reduce
  * database traffic on public sites. ResourceLoader requests to default
@@ -3238,8 +3227,8 @@ $wgHTMLFormAllowTableFormat = true;
 $wgUseMediaWikiUIEverywhere = false;
 
 /**
- * Temporary variable that determines whether the EditPage class should use OOjs UI or not.
- * This will be removed later and OOjs UI will become the only option.
+ * Temporary variable that determines whether Special:Preferences should use OOUI or not.
+ * This will be removed later and OOUI will become the only option.
  *
  * @since 1.32
  */
@@ -3789,23 +3778,6 @@ $wgResourceLoaderLESSVars = [
        'deviceWidthTablet' => '720px',
 ];
 
-/**
- * Default import paths for LESS modules. LESS files referenced in @import
- * statements will be looked up here first, and relative to the importing file
- * second. To avoid collisions, it's important for the LESS files in these
- * directories to have a common, predictable file name prefix.
- *
- * Extensions need not (and should not) register paths in
- * $wgResourceLoaderLESSImportPaths. The import path includes the path of the
- * currently compiling LESS file, which allows each extension to freely import
- * files from its own tree.
- *
- * @since 1.22
- */
-$wgResourceLoaderLESSImportPaths = [
-       "$IP/resources/src/mediawiki.less/",
-];
-
 /**
  * Whether ResourceLoader should attempt to persist modules in localStorage on
  * browsers that support the Web Storage API.
@@ -6043,6 +6015,15 @@ $wgSessionName = false;
  */
 $wgCookieSetOnAutoblock = false;
 
+/**
+ * Whether to set a cookie when a logged-out user is blocked. Doing so means that a blocked user,
+ * even after moving to a new IP address, will still be blocked. This cookie will contain an
+ * authentication code if $wgSecretKey is set, or otherwise will just be the block ID (in which
+ * case there is a possibility of an attacker discovering the names of revdeleted users, so it
+ * is best to use this in conjunction with $wgSecretKey being set).
+ */
+$wgCookieSetOnIpBlock = false;
+
 /** @} */ # end of cookie settings }
 
 /************************************************************************//**
@@ -7864,10 +7845,6 @@ $wgActionFilteredLogs = [
                'autocreate' => [ 'autocreate' ],
                'byemail' => [ 'byemail' ],
        ],
-       'patrol' => [
-               'patrol' => [ 'patrol' ],
-               'autopatrol' => [ 'autopatrol' ],
-       ],
        'protect' => [
                'protect' => [ 'protect' ],
                'modify' => [ 'modify' ],
@@ -8752,6 +8729,34 @@ $wgMaxUserDBWriteDuration = false;
  */
 $wgMaxJobDBWriteDuration = false;
 
+/**
+ * Controls Content-Security-Policy header [Experimental]
+ *
+ * @see https://www.w3.org/TR/CSP2/
+ * @since 1.32
+ * @var bool|array true to send default version, false to not send.
+ *  If an array, can have parameters:
+ *  'default-src' If true or array (of additional urls) will set a default-src
+ *    directive, which limits what places things can load from. If false or not
+ *    set, will send a default-src directive allowing all sources.
+ *  'includeCORS' If true or not set, will include urls from
+ *    $wgCrossSiteAJAXdomains as an allowed load sources.
+ *  'unsafeFallback' Add unsafe-inline as a script source, as a fallback for
+ *    browsers that do not understand nonce-sources [default on].
+ *  'script-src' Array of additional places that are allowed to have JS be loaded from.
+ *  'report-uri' true to use MW api [default], false to disable, string for alternate uri
+ * @warning May cause slowness on windows due to slow random number generator.
+ */
+$wgCSPHeader = false;
+
+/**
+ * Controls Content-Security-Policy-Report-Only header
+ *
+ * @since 1.32
+ * @var bool|array Same as $wgCSPHeader
+ */
+$wgCSPReportOnlyHeader = false;
+
 /**
  * Mapping of event channels (or channel categories) to EventRelayer configuration.
  *
index 087af39..e5261e7 100644 (file)
@@ -22,7 +22,6 @@
 
 require_once __DIR__ . '/libs/mime/defines.php';
 require_once __DIR__ . '/libs/rdbms/defines.php';
-require_once __DIR__ . '/compat/normal/UtfNormalDefines.php';
 
 use Wikimedia\Rdbms\IDatabase;
 
index 4f6b7b4..bd44cf7 100644 (file)
@@ -587,6 +587,10 @@ class EditPage {
                $permErrors = $this->getEditPermissionErrors( $this->save ? 'secure' : 'full' );
                if ( $permErrors ) {
                        wfDebug( __METHOD__ . ": User can't edit\n" );
+
+                       // track block with a cookie if it doesn't exists already
+                       $this->context->getUser()->trackBlockWithCookie();
+
                        // Auto-block user's IP if the account was "hard" blocked
                        if ( !wfReadOnly() ) {
                                DeferredUpdates::addCallableUpdate( function () {
@@ -938,7 +942,7 @@ class EditPage {
                        if ( $this->incompleteForm ) {
                                # If the form is incomplete, force to preview.
                                wfDebug( __METHOD__ . ": Form data appears to be incomplete\n" );
-                               wfDebug( "POST DATA: " . var_export( $_POST, true ) . "\n" );
+                               wfDebug( "POST DATA: " . var_export( $request->getPostValues(), true ) . "\n" );
                                $this->preview = true;
                        } else {
                                $this->preview = $request->getCheck( 'wpPreview' );
@@ -4116,7 +4120,8 @@ ERROR;
                if ( Hooks::run( 'EditPageBeforeEditToolbar', [ &$toolbar ] ) ) {
                        // Only add the old toolbar cruft to the page payload if the toolbar has not
                        // been over-written by a hook caller
-                       $wgOut->addScript( ResourceLoader::makeInlineScript( $script ) );
+                       $nonce = $wgOut->getCSPNonce();
+                       $wgOut->addScript( ResourceLoader::makeInlineScript( $script, $nonce ) );
                };
 
                return $toolbar;
index 9569bc1..6f49a14 100644 (file)
@@ -32,75 +32,6 @@ use MediaWiki\Shell\Shell;
 use Wikimedia\ScopedCallback;
 use Wikimedia\Rdbms\DBReplicationWaitError;
 
-// Hide compatibility functions from Doxygen
-/// @cond
-/**
- * Compatibility functions
- *
- * We support PHP 5.5.9 and up.
- * Re-implementations of newer functions or functions in non-standard
- * PHP extensions may be included here.
- */
-
-// hash_equals function only exists in PHP >= 5.6.0
-// https://secure.php.net/hash_equals
-if ( !function_exists( 'hash_equals' ) ) {
-       /**
-        * Check whether a user-provided string is equal to a fixed-length secret string
-        * without revealing bytes of the secret string through timing differences.
-        *
-        * The usual way to compare strings (PHP's === operator or the underlying memcmp()
-        * function in C) is to compare corresponding bytes and stop at the first difference,
-        * which would take longer for a partial match than for a complete mismatch. This
-        * is not secure when one of the strings (e.g. an HMAC or token) must remain secret
-        * and the other may come from an attacker. Statistical analysis of timing measurements
-        * over many requests may allow the attacker to guess the string's bytes one at a time
-        * (and check his guesses) even if the timing differences are extremely small.
-        *
-        * When making such a security-sensitive comparison, it is essential that the sequence
-        * in which instructions are executed and memory locations are accessed not depend on
-        * the secret string's value. HOWEVER, for simplicity, we do not attempt to minimize
-        * the inevitable leakage of the string's length. That is generally known anyway as
-        * a chararacteristic of the hash function used to compute the secret value.
-        *
-        * Longer explanation: http://www.emerose.com/timing-attacks-explained
-        *
-        * @codeCoverageIgnore
-        * @param string $known_string Fixed-length secret string to compare against
-        * @param string $user_string User-provided string
-        * @return bool True if the strings are the same, false otherwise
-        */
-       function hash_equals( $known_string, $user_string ) {
-               // Strict type checking as in PHP's native implementation
-               if ( !is_string( $known_string ) ) {
-                       trigger_error( 'hash_equals(): Expected known_string to be a string, ' .
-                               gettype( $known_string ) . ' given', E_USER_WARNING );
-
-                       return false;
-               }
-
-               if ( !is_string( $user_string ) ) {
-                       trigger_error( 'hash_equals(): Expected user_string to be a string, ' .
-                               gettype( $user_string ) . ' given', E_USER_WARNING );
-
-                       return false;
-               }
-
-               $known_string_len = strlen( $known_string );
-               if ( $known_string_len !== strlen( $user_string ) ) {
-                       return false;
-               }
-
-               $result = 0;
-               for ( $i = 0; $i < $known_string_len; $i++ ) {
-                       $result |= ord( $known_string[$i] ) ^ ord( $user_string[$i] );
-               }
-
-               return ( $result === 0 );
-       }
-}
-/// @endcond
-
 /**
  * Load an extension
  *
@@ -1089,7 +1020,8 @@ function wfIsDebugRawPage() {
        if ( $cache !== null ) {
                return $cache;
        }
-       # Check for raw action using $_GET not $wgRequest, since the latter might not be initialised yet
+       // Check for raw action using $_GET not $wgRequest, since the latter might not be initialised yet
+       // phpcs:ignore MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals
        if ( ( isset( $_GET['action'] ) && $_GET['action'] == 'raw' )
                || (
                        isset( $_SERVER['SCRIPT_NAME'] )
@@ -1513,9 +1445,10 @@ function wfHostname() {
  * If $wgShowHostnames is true, the script will also set 'wgHostname' to the
  * hostname of the server handling the request.
  *
- * @return string
+ * @param string $nonce Value from OutputPage::getCSPNonce
+ * @return string|WrappedString HTML
  */
-function wfReportTime() {
+function wfReportTime( $nonce = null ) {
        global $wgShowHostnames;
 
        $elapsed = ( microtime( true ) - $_SERVER['REQUEST_TIME_FLOAT'] );
@@ -1525,7 +1458,7 @@ function wfReportTime() {
        if ( $wgShowHostnames ) {
                $reportVars['wgHostname'] = wfHostname();
        }
-       return Skin::makeVariablesScript( $reportVars );
+       return Skin::makeVariablesScript( $reportVars, $nonce );
 }
 
 /**
@@ -2737,6 +2670,28 @@ function wfGetPrecompiledData( $name ) {
        return false;
 }
 
+/**
+ * @since 1.32
+ * @param string[] $data Array with string keys/values to export
+ * @param string $header
+ * @return string PHP code
+ */
+function wfMakeStaticArrayFile( array $data, $header = 'Automatically generated' ) {
+       $format = "\t%s => %s,\n";
+       $code = "<?php\n"
+               . "// " . implode( "\n// ", explode( "\n", $header ) ) . "\n"
+               . "return [\n";
+       foreach ( $data as $key => $value ) {
+               $code .= sprintf(
+                       $format,
+                       var_export( $key, true ),
+                       var_export( $value, true )
+               );
+       }
+       $code .= "];\n";
+       return $code;
+}
+
 /**
  * Make a cache key for the local wiki.
  *
@@ -3227,7 +3182,7 @@ function wfRunHooks( $event, array $args = [], $deprecatedVersion = null ) {
  * @param string $format The format string (See php's docs)
  * @param string $data A binary string of binary data
  * @param int|bool $length The minimum length of $data or false. This is to
- *     prevent reading beyond the end of $data. false to disable the check.
+ *     prevent reading beyond the end of $data. false to disable the check.
  *
  * Also be careful when using this function to read unsigned 32 bit integer
  * because php might make it negative.
index c22dc97..d434120 100644 (file)
@@ -47,10 +47,6 @@ class Hooks {
         * @since 1.18
         */
        public static function register( $name, $callback ) {
-               if ( !isset( self::$handlers[$name] ) ) {
-                       self::$handlers[$name] = [];
-               }
-
                self::$handlers[$name][] = $callback;
        }
 
@@ -62,6 +58,7 @@ class Hooks {
         *
         * @since 1.21
         * @throws MWException If not in testing mode.
+        * @codeCoverageIgnore
         */
        public static function clear( $name ) {
                if ( !defined( 'MW_PHPUNIT_TEST' ) && !defined( 'MW_PARSER_TEST' ) ) {
index 3bcf131..019e078 100644 (file)
@@ -557,10 +557,18 @@ class Html {
         * literal "</script>" or (for XML) literal "]]>".
         *
         * @param string $contents JavaScript
+        * @param string $nonce Nonce for CSP header, from OutputPage::getCSPNonce()
         * @return string Raw HTML
         */
-       public static function inlineScript( $contents ) {
+       public static function inlineScript( $contents, $nonce = null ) {
                $attrs = [];
+               if ( $nonce !== null ) {
+                       $attrs['nonce'] = $nonce;
+               } else {
+                       if ( ContentSecurityPolicy::isEnabled( RequestContext::getMain()->getConfig() ) ) {
+                               wfWarn( "no nonce set on script. CSP will break it" );
+                       }
+               }
 
                if ( preg_match( '/[<&]/', $contents ) ) {
                        $contents = "/*<![CDATA[*/$contents/*]]>*/";
@@ -574,10 +582,18 @@ class Html {
         * "<script src=foo.js></script>".
         *
         * @param string $url
+        * @param string $nonce Nonce for CSP header, from OutputPage::getCSPNonce()
         * @return string Raw HTML
         */
-       public static function linkedScript( $url ) {
+       public static function linkedScript( $url, $nonce = null ) {
                $attrs = [ 'src' => $url ];
+               if ( $nonce !== null ) {
+                       $attrs['nonce'] = $nonce;
+               } else {
+                       if ( ContentSecurityPolicy::isEnabled( RequestContext::getMain()->getConfig() ) ) {
+                               wfWarn( "no nonce set on script. CSP will break it" );
+                       }
+               }
 
                return self::element( 'script', $attrs );
        }
index 5fc5eb1..5cdbfee 100644 (file)
@@ -1221,9 +1221,9 @@ class Linker {
         * @todo FIXME: Doesn't handle sub-links as in image thumb texts like the main parser
         *
         * @param string $comment Text to format links in. WARNING! Since the output of this
-        *      function is html, $comment must be sanitized for use as html. You probably want
-        *      to pass $comment through Sanitizer::escapeHtmlAllowEntities() before calling
-        *      this function.
+        *      function is html, $comment must be sanitized for use as html. You probably want
+        *      to pass $comment through Sanitizer::escapeHtmlAllowEntities() before calling
+        *      this function.
         * @param Title|null $title An optional title object used to links to sections
         * @param bool $local Whether section links should refer to local page
         * @param string|null $wikiId Id of the wiki to link to (if not the local wiki),
index e6dc0fe..459a7e1 100644 (file)
@@ -636,9 +636,11 @@ class MediaWiki {
 
                if ( $cpIndex > 0 ) {
                        if ( $allowHeaders ) {
-                               $expires = time() + ChronologyProtector::POSITION_TTL;
+                               $now = time();
+                               $expires = $now + ChronologyProtector::POSITION_COOKIE_TTL;
                                $options = [ 'prefix' => '' ];
-                               $request->response()->setCookie( 'cpPosIndex', $cpIndex, $expires, $options );
+                               $value = LBFactory::makeCookieValueFromCPIndex( $cpIndex, $now ); // T190082
+                               $request->response()->setCookie( 'cpPosIndex', $value, $expires, $options );
                        }
 
                        if ( $strategy === 'cookie+url' ) {
index fbc7b60..7f72d36 100644 (file)
@@ -304,6 +304,11 @@ class OutputPage extends ContextSource {
         */
        private $mLinkHeader = [];
 
+       /**
+        * @var string The nonce for Content-Security-Policy
+        */
+       private $CSPNonce;
+
        /**
         * Constructor for OutputPage. This should not be called directly.
         * Instead a new RequestContext should be created and it will implicitly create
@@ -458,24 +463,22 @@ class OutputPage extends ContextSource {
        }
 
        /**
-        * Add a JavaScript file out of skins/common, or a given relative path.
+        * Add a JavaScript file to be loaded as `<script>` on this page.
+        *
         * Internal use only. Use OutputPage::addModules() if possible.
         *
-        * @param string $file Filename in skins/common or complete on-server path
-        *              (/foo/bar.js)
-        * @param string $version Style version of the file. Defaults to $wgStyleVersion
+        * @param string $file URL to file (absolute path, protocol-relative, or full url)
+        * @param string $unused Previously used to change the cache-busting query parameter
         */
-       public function addScriptFile( $file, $version = null ) {
-               // See if $file parameter is an absolute URL or begins with a slash
-               if ( substr( $file, 0, 1 ) == '/' || preg_match( '#^[a-z]*://#i', $file ) ) {
-                       $path = $file;
-               } else {
-                       $path = $this->getConfig()->get( 'StylePath' ) . "/common/{$file}";
-               }
-               if ( is_null( $version ) ) {
-                       $version = $this->getConfig()->get( 'StyleVersion' );
+       public function addScriptFile( $file, $unused = null ) {
+               if ( substr( $file, 0, 1 ) !== '/' && !preg_match( '#^[a-z]*://#i', $file ) ) {
+                       // This is not an absolute path, protocol-relative url, or full scheme url,
+                       // presumed to be an old call intended to include a file from /w/skins/common,
+                       // which doesn't exist anymore as of MediaWiki 1.24 per T71277. Ignore.
+                       wfDeprecated( __METHOD__, '1.24' );
+                       return;
                }
-               $this->addScript( Html::linkedScript( wfAppendQuery( $path, $version ) ) );
+               $this->addScript( Html::linkedScript( $file, $this->getCSPNonce() ) );
        }
 
        /**
@@ -485,7 +488,7 @@ class OutputPage extends ContextSource {
         * @param string $script JavaScript text, no script tags
         */
        public function addInlineScript( $script ) {
-               $this->mScripts .= Html::inlineScript( $script );
+               $this->mScripts .= Html::inlineScript( "\n$script\n", $this->getCSPNonce() ) . "\n";
        }
 
        /**
@@ -2433,10 +2436,12 @@ class OutputPage extends ContextSource {
                        $response->header( "X-Frame-Options: $frameOptions" );
                }
 
+               ContentSecurityPolicy::sendHeaders( $this );
+
                if ( $this->mArticleBodyOnly ) {
                        echo $this->mBodytext;
                } else {
-                       // Enable safe mode if requested
+                       // Enable safe mode if requested (T152169)
                        if ( $this->getRequest()->getBool( 'safemode' ) ) {
                                $this->disallowUserJs();
                        }
@@ -2854,6 +2859,17 @@ class OutputPage extends ContextSource {
 
                        $rlClient = new ResourceLoaderClientHtml( $context, [
                                'target' => $this->getTarget(),
+                               'nonce' => $this->getCSPNonce(),
+                               // When 'safemode', disallowUserJs(), or reduceAllowedModules() is used
+                               // to only restrict modules to ORIGIN_CORE (ie. disallow ORIGIN_USER), the list of
+                               // modules enqueud for loading on this page is filtered to just those.
+                               // However, to make sure we also apply the restriction to dynamic dependencies and
+                               // lazy-loaded modules at run-time on the client-side, pass 'safemode' down to the
+                               // StartupModule so that the client-side registry will not contain any restricted
+                               // modules either. (T152169, T185303)
+                               'safemode' => ( $this->getAllowedModules( ResourceLoaderModule::TYPE_COMBINED )
+                                       <= ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL
+                               ) ? '1' : null,
                        ] );
                        $rlClient->setConfig( $this->getJSVars() );
                        $rlClient->setModules( $this->getModules( /*filter*/ true ) );
@@ -2911,7 +2927,8 @@ class OutputPage extends ContextSource {
                                ResourceLoaderContext::newDummyContext(),
                                [ 'html5shiv' ],
                                ResourceLoaderModule::TYPE_SCRIPTS,
-                               [ 'sync' => true ]
+                               [ 'sync' => true ],
+                               $this->getCSPNonce()
                        ) .
                        '<![endif]-->';
 
@@ -2992,7 +3009,8 @@ class OutputPage extends ContextSource {
                        $this->getRlClientContext(),
                        $modules,
                        $only,
-                       $extraQuery
+                       $extraQuery,
+                       $this->getCSPNonce()
                );
        }
 
@@ -3025,7 +3043,8 @@ class OutputPage extends ContextSource {
                        $chunks[] = ResourceLoader::makeInlineScript(
                                ResourceLoader::makeConfigSetScript(
                                        [ 'wgPageParseReport' => $this->limitReportJSData ]
-                               )
+                               ),
+                               $this->getCSPNonce()
                        );
                }
 
@@ -3643,8 +3662,11 @@ class OutputPage extends ContextSource {
                        $url = $style;
                } else {
                        $config = $this->getConfig();
-                       $url = $config->get( 'StylePath' ) . '/' . $style . '?' .
-                               $config->get( 'StyleVersion' );
+                       // Append file hash as query parameter
+                       $url = self::transformResourcePath(
+                               $config,
+                               $config->get( 'StylePath' ) . '/' . $style
+                       );
                }
 
                $link = Html::linkedStyle( $url, $media );
@@ -3992,4 +4014,26 @@ class OutputPage extends ContextSource {
                        );
                }
        }
+
+       /**
+        * Get (and set if not yet set) the CSP nonce.
+        *
+        * This value needs to be included in any <script> tags on the
+        * page.
+        *
+        * @return string|bool Nonce or false to mean don't output nonce
+        * @since 1.32
+        */
+       public function getCSPNonce() {
+               if ( !ContentSecurityPolicy::isEnabled( $this->getConfig() ) ) {
+                       return false;
+               }
+               if ( $this->CSPNonce === null ) {
+                       // XXX It might be expensive to generate randomness
+                       // on every request, on windows.
+                       $rand = MWCryptRand::generate( 15 );
+                       $this->CSPNonce = base64_encode( $rand );
+               }
+               return $this->CSPNonce;
+       }
 }
index cfe889f..8eda14a 100644 (file)
@@ -94,7 +94,7 @@ class PHPVersionCheck {
                        'version' => PHP_VERSION,
                        'vendor' => 'the PHP Group',
                        'upstreamSupported' => '5.6.0',
-                       'minSupported' => '5.5.9',
+                       'minSupported' => '7.0.0',
                        'upgradeURL' => 'https://secure.php.net/downloads.php',
                );
        }
@@ -120,7 +120,7 @@ class PHPVersionCheck {
                                . "MediaWiki $this->mwVersion needs {$phpInfo['implementation']}"
                                . " $minimumVersion or higher or {$otherInfo['implementation']} version "
                                . "{$otherInfo['minSupported']}.\n\nCheck if you have a"
-                               . " newer php executable with a different name, such as php5.\n\n";
+                               . " newer php executable with a different name.\n\n";
 
                        // phpcs:disable Generic.Files.LineLength
                        $longHtml = <<<HTML
@@ -134,7 +134,7 @@ class PHPVersionCheck {
                        If for some reason you are unable to upgrade your {$phpInfo['implementation']} version,
                        you will need to <a href="https://www.mediawiki.org/wiki/Download">download</a> an
                        older version of MediaWiki from our website.
-                       See our<a href="https://www.mediawiki.org/wiki/Compatibility#PHP">compatibility page</a>
+                       See our <a href="https://www.mediawiki.org/wiki/Compatibility#PHP">compatibility page</a>
                        for details of which versions are compatible with prior versions of {$phpInfo['implementation']}.
 HTML;
                        // phpcs:enable Generic.Files.LineLength
index 26e28ba..c458af0 100644 (file)
@@ -262,12 +262,12 @@ class Preferences {
         * @param IContextSource $context
         * @param string $formClass
         * @param array $remove Array of items to remove
-        * @return PreferencesForm|HTMLForm
+        * @return PreferencesFormLegacy|HTMLForm
         */
        public static function getFormObject(
                $user,
                IContextSource $context,
-               $formClass = PreferencesForm::class,
+               $formClass = PreferencesFormLegacy::class,
                array $remove = []
        ) {
                $preferencesFactory = self::getDefaultPreferencesFactory();
@@ -306,7 +306,7 @@ class Preferences {
         * @deprecated since 1.31, use PreferencesFactory
         *
         * @param array $formData
-        * @param PreferencesForm $form
+        * @param HTMLForm $form
         * @return bool|Status|string
         */
        public static function tryFormSubmit( $formData, $form ) {
@@ -316,7 +316,7 @@ class Preferences {
 
        /**
         * @param array $formData
-        * @param PreferencesForm $form
+        * @param HTMLForm $form
         * @return Status
         */
        public static function tryUISubmit( $formData, $form ) {
index 5cc9a96..f73e686 100644 (file)
@@ -24,6 +24,8 @@
  * @file
  */
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\LBFactory;
+use Wikimedia\Rdbms\ChronologyProtector;
 
 /**
  * This file is not a valid entry point, perform no further processing unless
@@ -625,10 +627,6 @@ define( 'MW_SERVICE_BOOTSTRAP_COMPLETE', 1 );
 
 MWExceptionHandler::installHandler();
 
-require_once "$IP/includes/compat/normal/UtfNormalUtil.php";
-
-$ps_validation = Profiler::instance()->scopedProfileIn( $fname . '-validation' );
-
 // T48998: Bail out early if $wgArticlePath is non-absolute
 foreach ( [ 'wgArticlePath', 'wgVariantArticlePath' ] as $varName ) {
        if ( $$varName && !preg_match( '/^(https?:\/\/|\/)/', $$varName ) ) {
@@ -641,8 +639,6 @@ foreach ( [ 'wgArticlePath', 'wgVariantArticlePath' ] as $varName ) {
        }
 }
 
-Profiler::instance()->scopedProfileOut( $ps_validation );
-
 $ps_default2 = Profiler::instance()->scopedProfileIn( $fname . '-defaults2' );
 
 if ( $wgCanonicalServer === false ) {
@@ -703,7 +699,7 @@ if ( $wgMainWANCache === false ) {
 
 Profiler::instance()->scopedProfileOut( $ps_default2 );
 
-$ps_misc = Profiler::instance()->scopedProfileIn( $fname . '-misc1' );
+$ps_misc = Profiler::instance()->scopedProfileIn( $fname . '-misc' );
 
 // Raise the memory limit if it's too low
 wfMemoryLimit();
@@ -738,9 +734,15 @@ MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->setRequestInfo( [
        'IPAddress' => $wgRequest->getIP(),
        'UserAgent' => $wgRequest->getHeader( 'User-Agent' ),
        'ChronologyProtection' => $wgRequest->getHeader( 'ChronologyProtection' ),
-       // The cpPosIndex cookie has no prefix and is set by MediaWiki::preOutputCommit()
-       'ChronologyPositionIndex' =>
-               $wgRequest->getInt( 'cpPosIndex', (int)$wgRequest->getCookie( 'cpPosIndex', '' ) )
+       'ChronologyPositionIndex' => $wgRequest->getInt(
+               'cpPosIndex',
+               LBFactory::getCPIndexFromCookieValue(
+                       // The cookie has no prefix and is set by MediaWiki::preOutputCommit()
+                       $wgRequest->getCookie( 'cpPosIndex', '' ),
+                       // Mitigate broken client-side cookie expiration handling (T190082)
+                       time() - ChronologyProtector::POSITION_COOKIE_TTL
+               )
+       )
 ] );
 // Make sure that object caching does not undermine the ChronologyProtector improvements
 if ( $wgRequest->getCookie( 'UseDC', '' ) === 'master' ) {
@@ -766,9 +768,6 @@ if ( $wgCommandLineMode ) {
        wfDebug( $debug );
 }
 
-Profiler::instance()->scopedProfileOut( $ps_misc );
-$ps_memcached = Profiler::instance()->scopedProfileIn( $fname . '-memcached' );
-
 $wgMemc = wfGetMainCache();
 $messageMemc = wfGetMessageCacheStorage();
 
@@ -787,7 +786,7 @@ wfDebugLog( 'caches',
        ', session: ' . get_class( ObjectCache::getInstance( $wgSessionCacheType ) )
 );
 
-Profiler::instance()->scopedProfileOut( $ps_memcached );
+Profiler::instance()->scopedProfileOut( $ps_misc );
 
 // Most of the config is out, some might want to run hooks here.
 Hooks::run( 'SetupAfterCache' );
@@ -819,8 +818,6 @@ if ( $wgAuth && !$wgAuth instanceof MediaWiki\Auth\AuthManagerAuthPlugin ) {
        ], '$wgAuth is ' . get_class( $wgAuth ) );
 }
 
-// Set up the session
-$ps_session = Profiler::instance()->scopedProfileIn( $fname . '-session' );
 /**
  * @var MediaWiki\Session\SessionId|null $wgInitialSessionId The persistent
  * session ID (if any) loaded at startup
@@ -884,7 +881,6 @@ if ( !defined( 'MW_NO_SESSION' ) && !$wgCommandLineMode ) {
                );
        }
 }
-Profiler::instance()->scopedProfileOut( $ps_session );
 
 /**
  * @var User $wgUser
@@ -921,22 +917,7 @@ $ps_extensions = Profiler::instance()->scopedProfileIn( $fname . '-extensions' )
 // of the extension file. This allows the extension to perform
 // any necessary initialisation in the fully initialised environment
 foreach ( $wgExtensionFunctions as $func ) {
-       // Allow closures in PHP 5.3+
-       if ( is_object( $func ) && $func instanceof Closure ) {
-               $profName = $fname . '-extensions-closure';
-       } elseif ( is_array( $func ) ) {
-               if ( is_object( $func[0] ) ) {
-                       $profName = $fname . '-extensions-' . get_class( $func[0] ) . '::' . $func[1];
-               } else {
-                       $profName = $fname . '-extensions-' . implode( '::', $func );
-               }
-       } else {
-               $profName = $fname . '-extensions-' . strval( $func );
-       }
-
-       $ps_ext_func = Profiler::instance()->scopedProfileIn( $profName );
        call_user_func( $func );
-       Profiler::instance()->scopedProfileOut( $ps_ext_func );
 }
 
 // If the session user has a 0 id but a valid name, that means we need to
@@ -944,13 +925,11 @@ foreach ( $wgExtensionFunctions as $func ) {
 if ( !defined( 'MW_NO_SESSION' ) && !$wgCommandLineMode ) {
        $sessionUser = MediaWiki\Session\SessionManager::getGlobalSession()->getUser();
        if ( $sessionUser->getId() === 0 && User::isValidUserName( $sessionUser->getName() ) ) {
-               $ps_autocreate = Profiler::instance()->scopedProfileIn( $fname . '-autocreate' );
                $res = MediaWiki\Auth\AuthManager::singleton()->autoCreateUser(
                        $sessionUser,
                        MediaWiki\Auth\AuthManager::AUTOCREATE_SOURCE_SESSION,
                        true
                );
-               Profiler::instance()->scopedProfileOut( $ps_autocreate );
                \MediaWiki\Logger\LoggerFactory::getInstance( 'authevents' )->info( 'Autocreation attempt', [
                        'event' => 'autocreate',
                        'status' => $res,
index b771477..fd7451c 100644 (file)
@@ -207,8 +207,8 @@ class Title implements LinkTarget {
         * Create a new Title from a prefixed DB key
         *
         * @param string $key The database key, which has underscores
-        *      instead of spaces, possibly including namespace and
-        *      interwiki prefixes
+        *      instead of spaces, possibly including namespace and
+        *      interwiki prefixes
         * @return Title|null Title, or null on an error
         */
        public static function newFromDBkey( $key ) {
@@ -4694,9 +4694,12 @@ class Title implements LinkTarget {
                }
 
                $dbw = wfGetDB( DB_MASTER );
-               $dbw->onTransactionPreCommitOrIdle( function () {
-                       ResourceLoaderWikiModule::invalidateModuleCache( $this, null, null, wfWikiID() );
-               } );
+               $dbw->onTransactionPreCommitOrIdle(
+                       function () {
+                               ResourceLoaderWikiModule::invalidateModuleCache( $this, null, null, wfWikiID() );
+                       },
+                       __METHOD__
+               );
 
                $conds = $this->pageCond();
                DeferredUpdates::addUpdate(
index c6ddf81..e0b8de7 100644 (file)
@@ -28,6 +28,9 @@ use MediaWiki\Session\Session;
 use MediaWiki\Session\SessionId;
 use MediaWiki\Session\SessionManager;
 
+// The point of this class is to be a wrapper around super globals
+// phpcs:disable MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals
+
 /**
  * The WebRequest class encapsulates getting at data passed in the
  * URL or via a POSTed form stripping illegal input characters and
@@ -654,6 +657,18 @@ class WebRequest {
                return $_GET;
        }
 
+       /**
+        * Get the values passed via POST.
+        * No transformation is performed on the values.
+        *
+        * @since 1.32
+        * @codeCoverageIgnore
+        * @return array
+        */
+       public function getPostValues() {
+               return $_POST;
+       }
+
        /**
         * Return the contents of the Query with no decoding. Use when you need to
         * know exactly what was sent, e.g. for an OAuth signature over the elements.
index 7dcd4a4..4f2720e 100644 (file)
@@ -49,7 +49,7 @@ class Xml {
                        if ( $allowShortTag && $contents === '' ) {
                                $out .= ' />';
                        } else {
-                               $out .= '>' . htmlspecialchars( $contents ) . "</$element>";
+                               $out .= '>' . htmlspecialchars( $contents, ENT_NOQUOTES ) . "</$element>";
                        }
                }
                return $out;
@@ -214,10 +214,10 @@ class Xml {
                // a custom language code might not have a defined name...
                if ( !array_key_exists( $wgLanguageCode, $languages ) ) {
                        $languages[$wgLanguageCode] = $wgLanguageCode;
+                       // Sort the array again
+                       ksort( $languages );
                }
 
-               ksort( $languages );
-
                /**
                 * If a bogus value is set, default to the content language.
                 * Otherwise, no default is selected and the user ends up
index 0141b9e..ec63910 100644 (file)
@@ -109,8 +109,13 @@ abstract class FormAction extends Action {
         *
         * If you don't want to do anything with the form, just return false here.
         *
+        * This method will be passed to the HTMLForm as a submit callback (see
+        * HTMLForm::setSubmitCallback) and must return as documented for HTMLForm::trySubmit.
+        *
+        * @see HTMLForm::setSubmitCallback()
+        * @see HTMLForm::trySubmit()
         * @param array $data
-        * @return bool|array True for success, false for didn't-try, array of errors on failure
+        * @return bool|string|array|Status Must return as documented for HTMLForm::trySubmit
         */
        abstract public function onSubmit( $data );
 
index 0988f73..0a4eae8 100644 (file)
@@ -195,9 +195,14 @@ class InfoAction extends FormlessAction {
        }
 
        /**
-        * Returns page information in an easily-manipulated format. Array keys are used so extensions
-        * may add additional information in arbitrary positions. Array values are arrays with one
-        * element to be rendered as a header, arrays with two elements to be rendered as a table row.
+        * Returns an array of info groups (will be rendered as tables), keyed by group ID.
+        * Group IDs are arbitrary and used so that extensions may add additional information in
+        * arbitrary positions (and as message keys for section headers for the tables, prefixed
+        * with 'pageinfo-').
+        * Each info group is a non-associative array of info items (rendered as table rows).
+        * Each info item is an array with two elements: the first describes the type of
+        * information, the second the value for the current page. Both can be strings (will be
+        * interpreted as raw HTML) or messages (will be interpreted as plain text and escaped).
         *
         * @return array
         */
index 812f962..50eb28a 100644 (file)
@@ -26,6 +26,8 @@
  * @file
  */
 
+use MediaWiki\Logger\LoggerFactory;
+
 /**
  * A simple method to retrieve the plain source of an article,
  * using "action=raw" in the GET request string.
@@ -85,7 +87,6 @@ class RawAction extends FormlessAction {
                        $response->header( $this->getOutput()->getKeyHeader() );
                }
 
-               $response->header( 'Content-type: ' . $contentType . '; charset=UTF-8' );
                // Output may contain user-specific data;
                // vary generated content for open sessions on private wikis
                $privateCache = !User::isEveryoneAllowed( 'read' ) &&
@@ -97,6 +98,36 @@ class RawAction extends FormlessAction {
                        'Cache-Control: ' . $mode . ', s-maxage=' . $smaxage . ', max-age=' . $maxage
                );
 
+               // In the event of user JS, don't allow loading a user JS/CSS/Json
+               // subpage that has no registered user associated with, as
+               // someone could register the account and take control of the
+               // JS/CSS/Json page.
+               $title = $this->getTitle();
+               if ( $title->isUserConfigPage() && $contentType !== 'text/x-wiki' ) {
+                       // not using getRootText() as we want this to work
+                       // even if subpages are disabled.
+                       $rootPage = strtok( $title->getText(), '/' );
+                       $userFromTitle = User::newFromName( $rootPage, 'usable' );
+                       if ( !$userFromTitle || $userFromTitle->getId() === 0 ) {
+                               $elevated = $this->getUser()->isAllowed( 'editinterface' );
+                               $elevatedText = $elevated ? 'by elevated ' : '';
+                               $log = LoggerFactory::getInstance( "security" );
+                               $log->warning(
+                                       "Unsafe JS/CSS/Json $elevatedText" . "load - {user} loaded {title} with {ctype}",
+                                       [
+                                               'user' => $this->getUser()->getName(),
+                                               'title' => $title->getPrefixedDBKey(),
+                                               'ctype' => $contentType,
+                                               'elevated' => $elevated
+                                       ]
+                               );
+                               $msg = wfMessage( 'unregistered-user-config' );
+                               throw new HttpError( 403, $msg );
+                       }
+               }
+
+               $response->header( 'Content-type: ' . $contentType . '; charset=UTF-8' );
+
                $text = $this->getRawText();
 
                // Don't return a 404 response for CSS or JavaScript;
index 528e0e2..aaccc0c 100644 (file)
@@ -40,9 +40,7 @@ class WatchAction extends FormAction {
        }
 
        public function onSubmit( $data ) {
-               self::doWatch( $this->getTitle(), $this->getUser() );
-
-               return true;
+               return self::doWatch( $this->getTitle(), $this->getUser() );
        }
 
        protected function checkCanExecute( User $user ) {
@@ -183,8 +181,10 @@ class WatchAction extends FormAction {
         * @param string $action Optionally override the action to 'watch'
         * @return string Token
         * @since 1.18
+        * @deprecated since 1.32 Use WatchAction::getWatchToken() with action 'unwatch' directly.
         */
        public static function getUnwatchToken( Title $title, User $user, $action = 'unwatch' ) {
+               wfDeprecated( __METHOD__, '1.32' );
                return self::getWatchToken( $title, $user, $action );
        }
 
index 7fafa1f..02a635a 100644 (file)
@@ -226,6 +226,24 @@ abstract class ApiBase extends ContextSource {
         */
        const PARAM_MAX_CHARS = 24;
 
+       /**
+        * (array) Indicate that this is a templated parameter, and specify replacements. Keys are the
+        * placeholders in the parameter name and values are the names of (unprefixed) parameters from
+        * which the replacement values are taken.
+        *
+        * For example, a parameter "foo-{ns}-{title}" could be defined with
+        * PARAM_TEMPLATE_VARS => [ 'ns' => 'namespaces', 'title' => 'titles' ]. Then a query for
+        * namespaces=0|1&titles=X|Y would support parameters foo-0-X, foo-0-Y, foo-1-X, and foo-1-Y.
+        *
+        * All placeholders must be present in the parameter's name. Each target parameter must have
+        * PARAM_ISMULTI true. If a target is itself a templated parameter, its PARAM_TEMPLATE_VARS must
+        * be a subset of the referring parameter's, mapping the same placeholders to the same targets.
+        * A parameter cannot target itself.
+        *
+        * @since 1.32
+        */
+       const PARAM_TEMPLATE_VARS = 25;
+
        /**@}*/
 
        const ALL_DEFAULT_STRING = '*';
@@ -743,24 +761,117 @@ abstract class ApiBase extends ContextSource {
         * value - validated value from user or default. limits will not be
         * parsed if $parseLimit is set to false; use this when the max
         * limit is not definitive yet, e.g. when getting revisions.
-        * @param bool $parseLimit True by default
+        * @param bool|array $options If a boolean, uses that as the value for 'parseLimit'
+        *  - parseLimit: (bool, default true) Whether to parse the 'max' value for limit types
+        *  - safeMode: (bool, default false) If true, avoid throwing for parameter validation errors.
+        *    Returned parameter values might be ApiUsageException instances.
         * @return array
         */
-       public function extractRequestParams( $parseLimit = true ) {
+       public function extractRequestParams( $options = [] ) {
+               if ( is_bool( $options ) ) {
+                       $options = [ 'parseLimit' => $options ];
+               }
+               $options += [
+                       'parseLimit' => true,
+                       'safeMode' => false,
+               ];
+
+               $parseLimit = (bool)$options['parseLimit'];
+
                // Cache parameters, for performance and to avoid T26564.
                if ( !isset( $this->mParamCache[$parseLimit] ) ) {
-                       $params = $this->getFinalParams();
+                       $params = $this->getFinalParams() ?: [];
                        $results = [];
+                       $warned = [];
+
+                       // Process all non-templates and save templates for secondary
+                       // processing.
+                       $toProcess = [];
+                       foreach ( $params as $paramName => $paramSettings ) {
+                               if ( isset( $paramSettings[self::PARAM_TEMPLATE_VARS] ) ) {
+                                       $toProcess[] = [ $paramName, $paramSettings[self::PARAM_TEMPLATE_VARS], $paramSettings ];
+                               } else {
+                                       try {
+                                               $results[$paramName] = $this->getParameterFromSettings(
+                                                       $paramName, $paramSettings, $parseLimit
+                                               );
+                                       } catch ( ApiUsageException $ex ) {
+                                               $results[$paramName] = $ex;
+                                       }
+                               }
+                       }
 
-                       if ( $params ) { // getFinalParams() can return false
-                               foreach ( $params as $paramName => $paramSettings ) {
-                                       $results[$paramName] = $this->getParameterFromSettings(
-                                               $paramName, $paramSettings, $parseLimit );
+                       // Now process all the templates by successively replacing the
+                       // placeholders with all client-supplied values.
+                       // This bit duplicates JavaScript logic in
+                       // ApiSandbox.PageLayout.prototype.updateTemplatedParams().
+                       // If you update this, see if that needs updating too.
+                       while ( $toProcess ) {
+                               list( $name, $targets, $settings ) = array_shift( $toProcess );
+
+                               foreach ( $targets as $placeholder => $target ) {
+                                       if ( !array_key_exists( $target, $results ) ) {
+                                               // The target wasn't processed yet, try the next one.
+                                               // If all hit this case, the parameter has no expansions.
+                                               continue;
+                                       }
+                                       if ( !is_array( $results[$target] ) || !$results[$target] ) {
+                                               // The target was processed but has no (valid) values.
+                                               // That means it has no expansions.
+                                               break;
+                                       }
+
+                                       // Expand this target in the name and all other targets,
+                                       // then requeue if there are more targets left or put in
+                                       // $results if all are done.
+                                       unset( $targets[$placeholder] );
+                                       $placeholder = '{' . $placeholder . '}';
+                                       foreach ( $results[$target] as $value ) {
+                                               if ( !preg_match( '/^[^{}]*$/', $value ) ) {
+                                                       // Skip values that make invalid parameter names.
+                                                       $encTargetName = $this->encodeParamName( $target );
+                                                       if ( !isset( $warned[$encTargetName][$value] ) ) {
+                                                               $warned[$encTargetName][$value] = true;
+                                                               $this->addWarning( [
+                                                                       'apiwarn-ignoring-invalid-templated-value',
+                                                                       wfEscapeWikiText( $encTargetName ),
+                                                                       wfEscapeWikiText( $value ),
+                                                               ] );
+                                                       }
+                                                       continue;
+                                               }
+
+                                               $newName = str_replace( $placeholder, $value, $name );
+                                               if ( !$targets ) {
+                                                       try {
+                                                               $results[$newName] = $this->getParameterFromSettings( $newName, $settings, $parseLimit );
+                                                       } catch ( ApiUsageException $ex ) {
+                                                               $results[$newName] = $ex;
+                                                       }
+                                               } else {
+                                                       $newTargets = [];
+                                                       foreach ( $targets as $k => $v ) {
+                                                               $newTargets[$k] = str_replace( $placeholder, $value, $v );
+                                                       }
+                                                       $toProcess[] = [ $newName, $newTargets, $settings ];
+                                               }
+                                       }
+                                       break;
                                }
                        }
+
                        $this->mParamCache[$parseLimit] = $results;
                }
 
+               $ret = $this->mParamCache[$parseLimit];
+               if ( !$options['safeMode'] ) {
+                       foreach ( $ret as $v ) {
+                               if ( $v instanceof ApiUsageException ) {
+                                       throw $v;
+                               }
+                       }
+               }
+
                return $this->mParamCache[$parseLimit];
        }
 
@@ -771,9 +882,14 @@ abstract class ApiBase extends ContextSource {
         * @return mixed Parameter value
         */
        protected function getParameter( $paramName, $parseLimit = true ) {
-               $paramSettings = $this->getFinalParams()[$paramName];
-
-               return $this->getParameterFromSettings( $paramName, $paramSettings, $parseLimit );
+               $ret = $this->extractRequestParams( [
+                       'parseLimit' => $parseLimit,
+                       'safeMode' => true,
+               ] )[$paramName];
+               if ( $ret instanceof ApiUsageException ) {
+                       throw $ret;
+               }
+               return $ret;
        }
 
        /**
@@ -1423,10 +1539,10 @@ abstract class ApiBase extends ContextSource {
                        return $allowedValues;
                }
 
-               if ( self::truncateArray( $valuesList, $sizeLimit ) ) {
-                       $this->addDeprecation(
-                               [ 'apiwarn-toomanyvalues', $valueName, $sizeLimit ],
-                               "too-many-$valueName-for-{$this->getModulePath()}"
+               if ( count( $valuesList ) > $sizeLimit ) {
+                       $this->dieWithError(
+                               [ 'apierror-toomanyvalues', $valueName, $sizeLimit ],
+                               "too-many-$valueName"
                        );
                }
 
@@ -1612,32 +1728,30 @@ abstract class ApiBase extends ContextSource {
                        return $value;
                }
 
-               $titleObj = Title::makeTitleSafe( NS_USER, $value );
-
-               if ( $titleObj ) {
-                       $value = $titleObj->getText();
+               $name = User::getCanonicalName( $value, 'valid' );
+               if ( $name !== false ) {
+                       return $name;
                }
 
                if (
-                       !User::isValidUserName( $value ) &&
                        // We allow ranges as well, for blocks.
-                       !IP::isIPAddress( $value ) &&
+                       IP::isIPAddress( $value ) ||
                        // See comment for User::isIP.  We don't just call that function
                        // here because it also returns true for things like
                        // 300.300.300.300 that are neither valid usernames nor valid IP
                        // addresses.
-                       !preg_match(
+                       preg_match(
                                '/^' . RE_IP_BYTE . '\.' . RE_IP_BYTE . '\.' . RE_IP_BYTE . '\.xxx$/',
                                $value
                        )
                ) {
-                       $this->dieWithError(
-                               [ 'apierror-baduser', $encParamName, wfEscapeWikiText( $value ) ],
-                               "baduser_{$encParamName}"
-                       );
+                       return IP::sanitizeIP( $value );
                }
 
-               return $value;
+               $this->dieWithError(
+                       [ 'apierror-baduser', $encParamName, wfEscapeWikiText( $value ) ],
+                       "baduser_{$encParamName}"
+               );
        }
 
        /**@}*/
@@ -1662,22 +1776,6 @@ abstract class ApiBase extends ContextSource {
                WatchAction::doWatchOrUnwatch( $value, $titleObj, $this->getUser() );
        }
 
-       /**
-        * Truncate an array to a certain length.
-        * @param array &$arr Array to truncate
-        * @param int $limit Maximum length
-        * @return bool True if the array was truncated, false otherwise
-        */
-       public static function truncateArray( &$arr, $limit ) {
-               $modified = false;
-               while ( count( $arr ) > $limit ) {
-                       array_pop( $arr );
-                       $modified = true;
-               }
-
-               return $modified;
-       }
-
        /**
         * Gets the user for whom to get the watchlist
         *
@@ -2962,6 +3060,24 @@ abstract class ApiBase extends ContextSource {
                ] ];
        }
 
+       /**
+        * Truncate an array to a certain length.
+        * @deprecated since 1.32, no replacement
+        * @param array &$arr Array to truncate
+        * @param int $limit Maximum length
+        * @return bool True if the array was truncated, false otherwise
+        */
+       public static function truncateArray( &$arr, $limit ) {
+               wfDeprecated( __METHOD__, '1.32' );
+               $modified = false;
+               while ( count( $arr ) > $limit ) {
+                       array_pop( $arr );
+                       $modified = true;
+               }
+
+               return $modified;
+       }
+
        /**@}*/
 }
 
index af040d1..82a7cce 100644 (file)
@@ -47,7 +47,7 @@ class ApiCSPReport extends ApiBase {
 
                $this->verifyPostBodyOk();
                $report = $this->getReport();
-               $flags = $this->getFlags( $report );
+               $flags = $this->getFlags( $report, $userAgent );
 
                $warningText = $this->generateLogLine( $flags, $report );
                $this->logReport( $flags, $warningText, [
@@ -81,9 +81,10 @@ class ApiCSPReport extends ApiBase {
         * Get extra notes about the report.
         *
         * @param array $report The CSP report
+        * @param string $userAgent
         * @return array
         */
-       private function getFlags( $report ) {
+       private function getFlags( $report, $userAgent ) {
                $reportOnly = $this->getParameter( 'reportonly' );
                $source = $this->getParameter( 'source' );
                $falsePositives = $this->getConfig()->get( 'CSPFalsePositiveUrls' );
@@ -97,12 +98,22 @@ class ApiCSPReport extends ApiBase {
                }
 
                if (
-                       ( isset( $report['blocked-uri'] ) &&
-                       isset( $falsePositives[$report['blocked-uri']] ) )
-                       || ( isset( $report['source-file'] ) &&
-                       isset( $falsePositives[$report['source-file']] ) )
+                       (
+                               ContentSecurityPolicy::falsePositiveBrowser( $userAgent ) &&
+                               $report['blocked-uri'] === "self"
+                       ) ||
+                       (
+                               isset( $report['blocked-uri'] ) &&
+                               isset( $falsePositives[$report['blocked-uri']] )
+                       ) ||
+                       (
+                               isset( $report['source-file'] ) &&
+                               isset( $falsePositives[$report['source-file']] )
+                       )
                ) {
-                       // Report caused by Ad-Ware
+                       // False positive due to:
+                       // https://bugzilla.mozilla.org/show_bug.cgi?id=1026520
+
                        $flags[] = 'false-positive';
                }
                return $flags;
@@ -127,7 +138,7 @@ class ApiCSPReport extends ApiBase {
        /**
         * Get the report from post body and turn into associative array.
         *
-        * @return Array
+        * @return array
         */
        private function getReport() {
                $postBody = $this->getRequest()->getRawInput();
index 8d24859..bccb338 100644 (file)
@@ -466,6 +466,20 @@ class ApiHelp extends ApiBase {
                                                }
                                        }
 
+                                       // Templated?
+                                       if ( !empty( $settings[ApiBase::PARAM_TEMPLATE_VARS] ) ) {
+                                               $vars = [];
+                                               $msg = 'api-help-param-templated-var-first';
+                                               foreach ( $settings[ApiBase::PARAM_TEMPLATE_VARS] as $k => $v ) {
+                                                       $vars[] = $context->msg( $msg, $k, $module->encodeParamName( $v ) );
+                                                       $msg = 'api-help-param-templated-var';
+                                               }
+                                               $info[] = $context->msg( 'api-help-param-templated' )
+                                                       ->numParams( count( $vars ) )
+                                                       ->params( Message::listParam( $vars ) )
+                                                       ->parse();
+                                       }
+
                                        // Type documentation
                                        if ( !isset( $settings[ApiBase::PARAM_TYPE] ) ) {
                                                $dflt = isset( $settings[ApiBase::PARAM_DFLT] )
index b7b13c5..914d8e9 100644 (file)
@@ -1888,6 +1888,7 @@ class ApiMain extends ApiBase {
                        $help[$k] = $v;
                }
                $help['datatypes'] = '';
+               $help['templatedparams'] = '';
                $help['credits'] = '';
 
                // Fill 'permissions'
@@ -1920,7 +1921,7 @@ class ApiMain extends ApiBase {
                $help['permissions'] .= Html::closeElement( 'dl' );
                $help['permissions'] .= Html::closeElement( 'div' );
 
-               // Fill 'datatypes' and 'credits', if applicable
+               // Fill 'datatypes', 'templatedparams', and 'credits', if applicable
                if ( empty( $options['nolead'] ) ) {
                        $level = $options['headerlevel'];
                        $tocnumber = &$options['tocnumber'];
@@ -1954,6 +1955,35 @@ class ApiMain extends ApiBase {
                                ];
                        }
 
+                       $header = $this->msg( 'api-help-templatedparams-header' )->parse();
+
+                       $id = Sanitizer::escapeIdForAttribute( 'main/templatedparams', Sanitizer::ID_PRIMARY );
+                       $idFallback = Sanitizer::escapeIdForAttribute( 'main/templatedparams', Sanitizer::ID_FALLBACK );
+                       $headline = Linker::makeHeadline( min( 6, $level ),
+                               ' class="apihelp-header">',
+                               $id,
+                               $header,
+                               '',
+                               $idFallback
+                       );
+                       // Ensure we have a sane anchor
+                       if ( $id !== 'main/templatedparams' && $idFallback !== 'main/templatedparams' ) {
+                               $headline = '<div id="main/templatedparams"></div>' . $headline;
+                       }
+                       $help['templatedparams'] .= $headline;
+                       $help['templatedparams'] .= $this->msg( 'api-help-templatedparams' )->parseAsBlock();
+                       if ( !isset( $tocData['main/templatedparams'] ) ) {
+                               $tocnumber[$level]++;
+                               $tocData['main/templatedparams'] = [
+                                       'toclevel' => count( $tocnumber ),
+                                       'level' => $level,
+                                       'anchor' => 'main/templatedparams',
+                                       'line' => $header,
+                                       'number' => implode( '.', $tocnumber ),
+                                       'index' => false,
+                               ];
+                       }
+
                        $header = $this->msg( 'api-credits-header' )->parse();
                        $id = Sanitizer::escapeIdForAttribute( 'main/credits', Sanitizer::ID_PRIMARY );
                        $idFallback = Sanitizer::escapeIdForAttribute( 'main/credits', Sanitizer::ID_FALLBACK );
index 3347128..6a8b7d0 100644 (file)
@@ -1,8 +1,5 @@
 <?php
 /**
- * Defines an interface for messages with additional machine-readable data for
- * use by the API, and provides concrete implementations of that interface.
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * @file
  */
 
-/**
- * Interface for messages with machine-readable data for use by the API
- *
- * The idea is that it's a Message that has some extra data for the API to use when interpreting it
- * as an error (or, in the future, as a warning). Internals of MediaWiki often use messages (or
- * message keys, or Status objects containing messages) to pass information about errors to the user
- * (see e.g. Title::getUserPermissionsErrors()) and the API has to make do with that.
- *
- * @since 1.25
- * @note This interface exists to work around PHP's inheritance, so ApiMessage
- *  can extend Message and ApiRawMessage can extend RawMessage while still
- *  allowing an instanceof check for a Message object including this
- *  functionality. If for some reason you feel the need to implement this
- *  interface on some other class, that class must also implement all the
- *  public methods the Message class provides (not just those from
- *  MessageSpecifier, which as written is fairly useless).
- * @ingroup API
- */
-interface IApiMessage extends MessageSpecifier {
-       /**
-        * Returns a machine-readable code for use by the API
-        *
-        * If no code was specifically set, the message key is used as the code
-        * after removing "apiwarn-" or "apierror-" prefixes and applying
-        * backwards-compatibility mappings.
-        *
-        * @return string
-        */
-       public function getApiCode();
-
-       /**
-        * Returns additional machine-readable data about the error condition
-        * @return array
-        */
-       public function getApiData();
-
-       /**
-        * Sets the machine-readable code for use by the API
-        * @param string|null $code If null, uses the default (see self::getApiCode())
-        * @param array|null $data If non-null, passed to self::setApiData()
-        */
-       public function setApiCode( $code, array $data = null );
-
-       /**
-        * Sets additional machine-readable data about the error condition
-        * @param array $data
-        */
-       public function setApiData( array $data );
-}
-
-/**
- * Trait to implement the IApiMessage interface for Message subclasses
- * @since 1.27
- * @ingroup API
- */
-trait ApiMessageTrait {
-
-       /**
-        * Compatibility code mappings for various MW messages.
-        * @todo Ideally anything relying on this should be changed to use ApiMessage.
-        */
-       protected static $messageMap = [
-               'actionthrottledtext' => 'ratelimited',
-               'autoblockedtext' => 'autoblocked',
-               'badaccess-group0' => 'permissiondenied',
-               'badaccess-groups' => 'permissiondenied',
-               'badipaddress' => 'invalidip',
-               'blankpage' => 'emptypage',
-               'blockedtext' => 'blocked',
-               'cannotdelete' => 'cantdelete',
-               'cannotundelete' => 'cantundelete',
-               'cantmove-titleprotected' => 'protectedtitle',
-               'cantrollback' => 'onlyauthor',
-               'confirmedittext' => 'confirmemail',
-               'content-not-allowed-here' => 'contentnotallowedhere',
-               'deleteprotected' => 'cantedit',
-               'delete-toobig' => 'bigdelete',
-               'edit-conflict' => 'editconflict',
-               'imagenocrossnamespace' => 'nonfilenamespace',
-               'imagetypemismatch' => 'filetypemismatch',
-               'importbadinterwiki' => 'badinterwiki',
-               'importcantopen' => 'cantopenfile',
-               'import-noarticle' => 'badinterwiki',
-               'importnofile' => 'nofile',
-               'importuploaderrorpartial' => 'partialupload',
-               'importuploaderrorsize' => 'filetoobig',
-               'importuploaderrortemp' => 'notempdir',
-               'ipb_already_blocked' => 'alreadyblocked',
-               'ipb_blocked_as_range' => 'blockedasrange',
-               'ipb_cant_unblock' => 'cantunblock',
-               'ipb_expiry_invalid' => 'invalidexpiry',
-               'ip_range_invalid' => 'invalidrange',
-               'mailnologin' => 'cantsend',
-               'markedaspatrollederror-noautopatrol' => 'noautopatrol',
-               'movenologintext' => 'cantmove-anon',
-               'movenotallowed' => 'cantmove',
-               'movenotallowedfile' => 'cantmovefile',
-               'namespaceprotected' => 'protectednamespace',
-               'nocreate-loggedin' => 'cantcreate',
-               'nocreatetext' => 'cantcreate-anon',
-               'noname' => 'invaliduser',
-               'nosuchusershort' => 'nosuchuser',
-               'notanarticle' => 'missingtitle',
-               'nouserspecified' => 'invaliduser',
-               'ns-specialprotected' => 'unsupportednamespace',
-               'protect-cantedit' => 'cantedit',
-               'protectedinterface' => 'protectednamespace-interface',
-               'protectedpagetext' => 'protectedpage',
-               'range_block_disabled' => 'rangedisabled',
-               'rcpatroldisabled' => 'patroldisabled',
-               'readonlytext' => 'readonly',
-               'sessionfailure' => 'badtoken',
-               'systemblockedtext' => 'blocked',
-               'titleprotected' => 'protectedtitle',
-               'undo-failure' => 'undofailure',
-               'userrights-nodatabase' => 'nosuchdatabase',
-               'userrights-no-interwiki' => 'nointerwikiuserrights',
-       ];
-
-       protected $apiCode = null;
-       protected $apiData = [];
-
-       public function getApiCode() {
-               if ( $this->apiCode === null ) {
-                       $key = $this->getKey();
-                       if ( isset( self::$messageMap[$key] ) ) {
-                               $this->apiCode = self::$messageMap[$key];
-                       } elseif ( $key === 'apierror-missingparam' ) {
-                               /// @todo: Kill this case along with ApiBase::$messageMap
-                               $this->apiCode = 'no' . $this->getParams()[0];
-                       } elseif ( substr( $key, 0, 8 ) === 'apiwarn-' ) {
-                               $this->apiCode = substr( $key, 8 );
-                       } elseif ( substr( $key, 0, 9 ) === 'apierror-' ) {
-                               $this->apiCode = substr( $key, 9 );
-                       } else {
-                               $this->apiCode = $key;
-                       }
-               }
-               return $this->apiCode;
-       }
-
-       public function setApiCode( $code, array $data = null ) {
-               if ( $code !== null && !( is_string( $code ) && $code !== '' ) ) {
-                       throw new InvalidArgumentException( "Invalid code \"$code\"" );
-               }
-
-               $this->apiCode = $code;
-               if ( $data !== null ) {
-                       $this->setApiData( $data );
-               }
-       }
-
-       public function getApiData() {
-               return $this->apiData;
-       }
-
-       public function setApiData( array $data ) {
-               $this->apiData = $data;
-       }
-
-       public function serialize() {
-               return serialize( [
-                       'parent' => parent::serialize(),
-                       'apiCode' => $this->apiCode,
-                       'apiData' => $this->apiData,
-               ] );
-       }
-
-       public function unserialize( $serialized ) {
-               $data = unserialize( $serialized );
-               parent::unserialize( $data['parent'] );
-               $this->apiCode = $data['apiCode'];
-               $this->apiData = $data['apiData'];
-       }
-}
-
 /**
  * Extension of Message implementing IApiMessage
  * @since 1.25
@@ -266,36 +87,3 @@ class ApiMessage extends Message implements IApiMessage {
                $this->setApiCode( $code, $data );
        }
 }
-
-/**
- * Extension of RawMessage implementing IApiMessage
- * @since 1.25
- * @ingroup API
- */
-class ApiRawMessage extends RawMessage implements IApiMessage {
-       use ApiMessageTrait;
-
-       /**
-        * @param RawMessage|string|array $msg
-        *  - RawMessage: is cloned
-        *  - array: first element is $key, rest are $params to RawMessage::__construct
-        *  - string: passed to RawMessage::__construct
-        * @param string|null $code
-        * @param array|null $data
-        */
-       public function __construct( $msg, $code = null, array $data = null ) {
-               if ( $msg instanceof RawMessage ) {
-                       foreach ( get_class_vars( get_class( $this ) ) as $key => $value ) {
-                               if ( isset( $msg->$key ) ) {
-                                       $this->$key = $msg->$key;
-                               }
-                       }
-               } elseif ( is_array( $msg ) ) {
-                       $key = array_shift( $msg );
-                       parent::__construct( $key, $msg );
-               } else {
-                       parent::__construct( $msg );
-               }
-               $this->setApiCode( $code, $data );
-       }
-}
diff --git a/includes/api/ApiMessageTrait.php b/includes/api/ApiMessageTrait.php
new file mode 100644 (file)
index 0000000..18b6bc4
--- /dev/null
@@ -0,0 +1,145 @@
+<?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
+ */
+
+/**
+ * Trait to implement the IApiMessage interface for Message subclasses
+ * @since 1.27
+ * @ingroup API
+ */
+trait ApiMessageTrait {
+
+       /**
+        * Compatibility code mappings for various MW messages.
+        * @todo Ideally anything relying on this should be changed to use ApiMessage.
+        */
+       protected static $messageMap = [
+               'actionthrottledtext' => 'ratelimited',
+               'autoblockedtext' => 'autoblocked',
+               'badaccess-group0' => 'permissiondenied',
+               'badaccess-groups' => 'permissiondenied',
+               'badipaddress' => 'invalidip',
+               'blankpage' => 'emptypage',
+               'blockedtext' => 'blocked',
+               'cannotdelete' => 'cantdelete',
+               'cannotundelete' => 'cantundelete',
+               'cantmove-titleprotected' => 'protectedtitle',
+               'cantrollback' => 'onlyauthor',
+               'confirmedittext' => 'confirmemail',
+               'content-not-allowed-here' => 'contentnotallowedhere',
+               'deleteprotected' => 'cantedit',
+               'delete-toobig' => 'bigdelete',
+               'edit-conflict' => 'editconflict',
+               'imagenocrossnamespace' => 'nonfilenamespace',
+               'imagetypemismatch' => 'filetypemismatch',
+               'importbadinterwiki' => 'badinterwiki',
+               'importcantopen' => 'cantopenfile',
+               'import-noarticle' => 'badinterwiki',
+               'importnofile' => 'nofile',
+               'importuploaderrorpartial' => 'partialupload',
+               'importuploaderrorsize' => 'filetoobig',
+               'importuploaderrortemp' => 'notempdir',
+               'ipb_already_blocked' => 'alreadyblocked',
+               'ipb_blocked_as_range' => 'blockedasrange',
+               'ipb_cant_unblock' => 'cantunblock',
+               'ipb_expiry_invalid' => 'invalidexpiry',
+               'ip_range_invalid' => 'invalidrange',
+               'mailnologin' => 'cantsend',
+               'markedaspatrollederror-noautopatrol' => 'noautopatrol',
+               'movenologintext' => 'cantmove-anon',
+               'movenotallowed' => 'cantmove',
+               'movenotallowedfile' => 'cantmovefile',
+               'namespaceprotected' => 'protectednamespace',
+               'nocreate-loggedin' => 'cantcreate',
+               'nocreatetext' => 'cantcreate-anon',
+               'noname' => 'invaliduser',
+               'nosuchusershort' => 'nosuchuser',
+               'notanarticle' => 'missingtitle',
+               'nouserspecified' => 'invaliduser',
+               'ns-specialprotected' => 'unsupportednamespace',
+               'protect-cantedit' => 'cantedit',
+               'protectedinterface' => 'protectednamespace-interface',
+               'protectedpagetext' => 'protectedpage',
+               'range_block_disabled' => 'rangedisabled',
+               'rcpatroldisabled' => 'patroldisabled',
+               'readonlytext' => 'readonly',
+               'sessionfailure' => 'badtoken',
+               'systemblockedtext' => 'blocked',
+               'titleprotected' => 'protectedtitle',
+               'undo-failure' => 'undofailure',
+               'userrights-nodatabase' => 'nosuchdatabase',
+               'userrights-no-interwiki' => 'nointerwikiuserrights',
+       ];
+
+       protected $apiCode = null;
+       protected $apiData = [];
+
+       public function getApiCode() {
+               if ( $this->apiCode === null ) {
+                       $key = $this->getKey();
+                       if ( isset( self::$messageMap[$key] ) ) {
+                               $this->apiCode = self::$messageMap[$key];
+                       } elseif ( $key === 'apierror-missingparam' ) {
+                               /// @todo: Kill this case along with ApiBase::$messageMap
+                               $this->apiCode = 'no' . $this->getParams()[0];
+                       } elseif ( substr( $key, 0, 8 ) === 'apiwarn-' ) {
+                               $this->apiCode = substr( $key, 8 );
+                       } elseif ( substr( $key, 0, 9 ) === 'apierror-' ) {
+                               $this->apiCode = substr( $key, 9 );
+                       } else {
+                               $this->apiCode = $key;
+                       }
+               }
+               return $this->apiCode;
+       }
+
+       public function setApiCode( $code, array $data = null ) {
+               if ( $code !== null && !( is_string( $code ) && $code !== '' ) ) {
+                       throw new InvalidArgumentException( "Invalid code \"$code\"" );
+               }
+
+               $this->apiCode = $code;
+               if ( $data !== null ) {
+                       $this->setApiData( $data );
+               }
+       }
+
+       public function getApiData() {
+               return $this->apiData;
+       }
+
+       public function setApiData( array $data ) {
+               $this->apiData = $data;
+       }
+
+       public function serialize() {
+               return serialize( [
+                       'parent' => parent::serialize(),
+                       'apiCode' => $this->apiCode,
+                       'apiData' => $this->apiData,
+               ] );
+       }
+
+       public function unserialize( $serialized ) {
+               $data = unserialize( $serialized );
+               parent::unserialize( $data['parent'] );
+               $this->apiCode = $data['apiCode'];
+               $this->apiData = $data['apiData'];
+       }
+}
index bfd3d61..b8a32ae 100644 (file)
@@ -305,16 +305,25 @@ class ApiParamInfo extends ApiBase {
                }
 
                $ret['parameters'] = [];
+               $ret['templatedparameters'] = [];
                $params = $module->getFinalParams( ApiBase::GET_VALUES_FOR_HELP );
                $paramDesc = $module->getFinalParamDescription();
+               $index = 0;
                foreach ( $params as $name => $settings ) {
                        if ( !is_array( $settings ) ) {
                                $settings = [ ApiBase::PARAM_DFLT => $settings ];
                        }
 
                        $item = [
-                               'name' => $name
+                               'index' => ++$index,
+                               'name' => $name,
                        ];
+
+                       if ( !empty( $settings[ApiBase::PARAM_TEMPLATE_VARS] ) ) {
+                               $item['templatevars'] = $settings[ApiBase::PARAM_TEMPLATE_VARS];
+                               ApiResult::setIndexedTagName( $item['templatevars'], 'var' );
+                       }
+
                        if ( isset( $paramDesc[$name] ) ) {
                                $this->formatHelpMessages( $item, 'description', $paramDesc[$name], true );
                        }
@@ -507,9 +516,11 @@ class ApiParamInfo extends ApiBase {
                                ApiResult::setIndexedTagName( $item['info'], 'i' );
                        }
 
-                       $ret['parameters'][] = $item;
+                       $key = empty( $settings[ApiBase::PARAM_TEMPLATE_VARS] ) ? 'parameters' : 'templatedparameters';
+                       $ret[$key][] = $item;
                }
                ApiResult::setIndexedTagName( $ret['parameters'], 'param' );
+               ApiResult::setIndexedTagName( $ret['templatedparameters'], 'param' );
 
                $dynamicParams = $module->dynamicParameterDocumentation();
                if ( $dynamicParams !== null ) {
index e49024d..c68ec2b 100644 (file)
@@ -98,7 +98,7 @@ class ApiQuery extends ApiBase {
                'recentchanges' => ApiQueryRecentChanges::class,
                'search' => ApiQuerySearch::class,
                'tags' => ApiQueryTags::class,
-               'usercontribs' => ApiQueryContributions::class,
+               'usercontribs' => ApiQueryUserContribs::class,
                'users' => ApiQueryUsers::class,
                'watchlist' => ApiQueryWatchlist::class,
                'watchlistraw' => ApiQueryWatchlistRaw::class,
index 326debc..f3af226 100644 (file)
@@ -181,6 +181,16 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                        }
                }
 
+               $title = $params['title'];
+               if ( !is_null( $title ) ) {
+                       $titleObj = Title::newFromText( $title );
+                       if ( is_null( $titleObj ) ) {
+                               $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $title ) ] );
+                       }
+                       $this->addWhereFld( 'rc_namespace', $titleObj->getNamespace() );
+                       $this->addWhereFld( 'rc_title', $titleObj->getDBkey() );
+               }
+
                if ( !is_null( $params['show'] ) ) {
                        $show = array_flip( $params['show'] );
 
@@ -727,6 +737,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                                ApiBase::PARAM_TYPE => RecentChange::getChangeTypes()
                        ],
                        'toponly' => false,
+                       'title' => null,
                        'continue' => [
                                ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
                        ],
diff --git a/includes/api/ApiQueryUserContribs.php b/includes/api/ApiQueryUserContribs.php
new file mode 100644 (file)
index 0000000..140ff6d
--- /dev/null
@@ -0,0 +1,839 @@
+<?php
+/**
+ * Copyright © 2006 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
+ */
+
+/**
+ * This query action adds a list of a specified user's contributions to the output.
+ *
+ * @ingroup API
+ */
+class ApiQueryUserContribs extends ApiQueryBase {
+
+       public function __construct( ApiQuery $query, $moduleName ) {
+               parent::__construct( $query, $moduleName, 'uc' );
+       }
+
+       private $params, $multiUserMode, $orderBy, $parentLens, $commentStore;
+
+       private $fld_ids = false, $fld_title = false, $fld_timestamp = false,
+               $fld_comment = false, $fld_parsedcomment = false, $fld_flags = false,
+               $fld_patrolled = false, $fld_tags = false, $fld_size = false, $fld_sizediff = false;
+
+       public function execute() {
+               global $wgActorTableSchemaMigrationStage;
+
+               // Parse some parameters
+               $this->params = $this->extractRequestParams();
+
+               $this->commentStore = CommentStore::getStore();
+
+               $prop = array_flip( $this->params['prop'] );
+               $this->fld_ids = isset( $prop['ids'] );
+               $this->fld_title = isset( $prop['title'] );
+               $this->fld_comment = isset( $prop['comment'] );
+               $this->fld_parsedcomment = isset( $prop['parsedcomment'] );
+               $this->fld_size = isset( $prop['size'] );
+               $this->fld_sizediff = isset( $prop['sizediff'] );
+               $this->fld_flags = isset( $prop['flags'] );
+               $this->fld_timestamp = isset( $prop['timestamp'] );
+               $this->fld_patrolled = isset( $prop['patrolled'] );
+               $this->fld_tags = isset( $prop['tags'] );
+
+               // Most of this code will use the 'contributions' group DB, which can map to replica DBs
+               // with extra user based indexes or partioning by user. The additional metadata
+               // queries should use a regular replica DB since the lookup pattern is not all by user.
+               $dbSecondary = $this->getDB(); // any random replica DB
+
+               // TODO: if the query is going only against the revision table, should this be done?
+               $this->selectNamedDB( 'contributions', DB_REPLICA, 'contributions' );
+
+               $sort = ( $this->params['dir'] == 'newer' ? '' : ' DESC' );
+               $op = ( $this->params['dir'] == 'older' ? '<' : '>' );
+
+               // Create an Iterator that produces the UserIdentity objects we need, depending
+               // on which of the 'userprefix', 'userids', or 'user' params was
+               // specified.
+               $this->requireOnlyOneParameter( $this->params, 'userprefix', 'userids', 'user' );
+               if ( isset( $this->params['userprefix'] ) ) {
+                       $this->multiUserMode = true;
+                       $this->orderBy = 'name';
+                       $fname = __METHOD__;
+
+                       // Because 'userprefix' might produce a huge number of users (e.g.
+                       // a wiki with users "Test00000001" to "Test99999999"), use a
+                       // generator with batched lookup and continuation.
+                       $userIter = call_user_func( function () use ( $dbSecondary, $sort, $op, $fname ) {
+                               global $wgActorTableSchemaMigrationStage;
+
+                               $fromName = false;
+                               if ( !is_null( $this->params['continue'] ) ) {
+                                       $continue = explode( '|', $this->params['continue'] );
+                                       $this->dieContinueUsageIf( count( $continue ) != 4 );
+                                       $this->dieContinueUsageIf( $continue[0] !== 'name' );
+                                       $fromName = $continue[1];
+                               }
+                               $like = $dbSecondary->buildLike( $this->params['userprefix'], $dbSecondary->anyString() );
+
+                               $limit = 501;
+
+                               do {
+                                       $from = $fromName ? "$op= " . $dbSecondary->addQuotes( $fromName ) : false;
+
+                                       // For the new schema, pull from the actor table. For the
+                                       // old, pull from rev_user. For migration a FULL [OUTER]
+                                       // JOIN would be what we want, except MySQL doesn't support
+                                       // that so we have to UNION instead.
+                                       if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
+                                               $res = $dbSecondary->select(
+                                                       'actor',
+                                                       [ 'actor_id', 'user_id' => 'COALESCE(actor_user,0)', 'user_name' => 'actor_name' ],
+                                                       array_merge( [ "actor_name$like" ], $from ? [ "actor_name $from" ] : [] ),
+                                                       $fname,
+                                                       [ 'ORDER BY' => [ "user_name $sort" ], 'LIMIT' => $limit ]
+                                               );
+                                       } elseif ( $wgActorTableSchemaMigrationStage === MIGRATION_OLD ) {
+                                               $res = $dbSecondary->select(
+                                                       'revision',
+                                                       [ 'actor_id' => 'NULL', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
+                                                       array_merge( [ "rev_user_text$like" ], $from ? [ "rev_user_text $from" ] : [] ),
+                                                       $fname,
+                                                       [ 'DISTINCT', 'ORDER BY' => [ "rev_user_text $sort" ], 'LIMIT' => $limit ]
+                                               );
+                                       } else {
+                                               // There are three queries we have to combine to be sure of getting all results:
+                                               //  - actor table (any rows that have been migrated will have empty rev_user_text)
+                                               //  - revision+actor by user id
+                                               //  - revision+actor by name for anons
+                                               $options = $dbSecondary->unionSupportsOrderAndLimit()
+                                                       ? [ 'ORDER BY' => [ "user_name $sort" ], 'LIMIT' => $limit ] : [];
+                                               $subsql = [];
+                                               $subsql[] = $dbSecondary->selectSQLText(
+                                                       'actor',
+                                                       [ 'actor_id', 'user_id' => 'COALESCE(actor_user,0)', 'user_name' => 'actor_name' ],
+                                                       array_merge( [ "actor_name$like" ], $from ? [ "actor_name $from" ] : [] ),
+                                                       $fname,
+                                                       $options
+                                               );
+                                               $subsql[] = $dbSecondary->selectSQLText(
+                                                       [ 'revision', 'actor' ],
+                                                       [ 'actor_id', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
+                                                       array_merge(
+                                                               [ "rev_user_text$like", 'rev_user != 0' ],
+                                                               $from ? [ "rev_user_text $from" ] : []
+                                                       ),
+                                                       $fname,
+                                                       array_merge( [ 'DISTINCT' ], $options ),
+                                                       [ 'actor' => [ 'LEFT JOIN', 'rev_user = actor_user' ] ]
+                                               );
+                                               $subsql[] = $dbSecondary->selectSQLText(
+                                                       [ 'revision', 'actor' ],
+                                                       [ 'actor_id', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
+                                                       array_merge(
+                                                               [ "rev_user_text$like", 'rev_user = 0' ],
+                                                               $from ? [ "rev_user_text $from" ] : []
+                                                       ),
+                                                       $fname,
+                                                       array_merge( [ 'DISTINCT' ], $options ),
+                                                       [ 'actor' => [ 'LEFT JOIN', 'rev_user_text = actor_name' ] ]
+                                               );
+                                               $sql = $dbSecondary->unionQueries( $subsql, false ) . " ORDER BY user_name $sort";
+                                               $sql = $dbSecondary->limitResult( $sql, $limit );
+                                               $res = $dbSecondary->query( $sql, $fname );
+                                       }
+
+                                       $count = 0;
+                                       $fromName = false;
+                                       foreach ( $res as $row ) {
+                                               if ( ++$count >= $limit ) {
+                                                       $fromName = $row->user_name;
+                                                       break;
+                                               }
+                                               yield User::newFromRow( $row );
+                                       }
+                               } while ( $fromName !== false );
+                       } );
+                       // Do the actual sorting client-side, because otherwise
+                       // prepareQuery might try to sort by actor and confuse everything.
+                       $batchSize = 1;
+               } elseif ( isset( $this->params['userids'] ) ) {
+                       if ( !count( $this->params['userids'] ) ) {
+                               $encParamName = $this->encodeParamName( 'userids' );
+                               $this->dieWithError( [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName" );
+                       }
+
+                       $ids = [];
+                       foreach ( $this->params['userids'] as $uid ) {
+                               if ( $uid <= 0 ) {
+                                       $this->dieWithError( [ 'apierror-invaliduserid', $uid ], 'invaliduserid' );
+                               }
+                               $ids[] = $uid;
+                       }
+
+                       $this->orderBy = 'id';
+                       $this->multiUserMode = count( $ids ) > 1;
+
+                       $from = $fromId = false;
+                       if ( $this->multiUserMode && !is_null( $this->params['continue'] ) ) {
+                               $continue = explode( '|', $this->params['continue'] );
+                               $this->dieContinueUsageIf( count( $continue ) != 4 );
+                               $this->dieContinueUsageIf( $continue[0] !== 'id' && $continue[0] !== 'actor' );
+                               $fromId = (int)$continue[1];
+                               $this->dieContinueUsageIf( $continue[1] !== (string)$fromId );
+                               $from = "$op= $fromId";
+                       }
+
+                       // For the new schema, just select from the actor table. For the
+                       // old and transitional schemas, select from user and left join
+                       // actor if it exists.
+                       if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
+                               $res = $dbSecondary->select(
+                                       'actor',
+                                       [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
+                                       array_merge( [ 'actor_user' => $ids ], $from ? [ "actor_id $from" ] : [] ),
+                                       __METHOD__,
+                                       [ 'ORDER BY' => "user_id $sort" ]
+                               );
+                       } elseif ( $wgActorTableSchemaMigrationStage === MIGRATION_OLD ) {
+                               $res = $dbSecondary->select(
+                                       'user',
+                                       [ 'actor_id' => 'NULL', 'user_id' => 'user_id', 'user_name' => 'user_name' ],
+                                       array_merge( [ 'user_id' => $ids ], $from ? [ "user_id $from" ] : [] ),
+                                       __METHOD__,
+                                       [ 'ORDER BY' => "user_id $sort" ]
+                               );
+                       } else {
+                               $res = $dbSecondary->select(
+                                       [ 'user', 'actor' ],
+                                       [ 'actor_id', 'user_id', 'user_name' ],
+                                       array_merge( [ 'user_id' => $ids ], $from ? [ "user_id $from" ] : [] ),
+                                       __METHOD__,
+                                       [ 'ORDER BY' => "user_id $sort" ],
+                                       [ 'actor' => [ 'LEFT JOIN', 'actor_user = user_id' ] ]
+                               );
+                       }
+                       $userIter = UserArray::newFromResult( $res );
+                       $batchSize = count( $ids );
+               } else {
+                       $names = [];
+                       if ( !count( $this->params['user'] ) ) {
+                               $encParamName = $this->encodeParamName( 'user' );
+                               $this->dieWithError(
+                                       [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName"
+                               );
+                       }
+                       foreach ( $this->params['user'] as $u ) {
+                               if ( $u === '' ) {
+                                       $encParamName = $this->encodeParamName( 'user' );
+                                       $this->dieWithError(
+                                               [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName"
+                                       );
+                               }
+
+                               if ( User::isIP( $u ) || ExternalUserNames::isExternal( $u ) ) {
+                                       $names[$u] = null;
+                               } else {
+                                       $name = User::getCanonicalName( $u, 'valid' );
+                                       if ( $name === false ) {
+                                               $encParamName = $this->encodeParamName( 'user' );
+                                               $this->dieWithError(
+                                                       [ 'apierror-baduser', $encParamName, wfEscapeWikiText( $u ) ], "baduser_$encParamName"
+                                               );
+                                       }
+                                       $names[$name] = null;
+                               }
+                       }
+
+                       $this->orderBy = 'name';
+                       $this->multiUserMode = count( $names ) > 1;
+
+                       $from = $fromName = false;
+                       if ( $this->multiUserMode && !is_null( $this->params['continue'] ) ) {
+                               $continue = explode( '|', $this->params['continue'] );
+                               $this->dieContinueUsageIf( count( $continue ) != 4 );
+                               $this->dieContinueUsageIf( $continue[0] !== 'name' && $continue[0] !== 'actor' );
+                               $fromName = $continue[1];
+                               $from = "$op= " . $dbSecondary->addQuotes( $fromName );
+                       }
+
+                       // For the new schema, just select from the actor table. For the
+                       // old and transitional schemas, select from user and left join
+                       // actor if it exists then merge in any unknown users (IPs and imports).
+                       if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
+                               $res = $dbSecondary->select(
+                                       'actor',
+                                       [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
+                                       array_merge( [ 'actor_name' => array_keys( $names ) ], $from ? [ "actor_id $from" ] : [] ),
+                                       __METHOD__,
+                                       [ 'ORDER BY' => "actor_name $sort" ]
+                               );
+                               $userIter = UserArray::newFromResult( $res );
+                       } else {
+                               if ( $wgActorTableSchemaMigrationStage === MIGRATION_OLD ) {
+                                       $res = $dbSecondary->select(
+                                               'user',
+                                               [ 'actor_id' => 'NULL', 'user_id', 'user_name' ],
+                                               array_merge( [ 'user_name' => array_keys( $names ) ], $from ? [ "user_name $from" ] : [] ),
+                                               __METHOD__
+                                       );
+                               } else {
+                                       $res = $dbSecondary->select(
+                                               [ 'user', 'actor' ],
+                                               [ 'actor_id', 'user_id', 'user_name' ],
+                                               array_merge( [ 'user_name' => array_keys( $names ) ], $from ? [ "user_name $from" ] : [] ),
+                                               __METHOD__,
+                                               [],
+                                               [ 'actor' => [ 'LEFT JOIN', 'actor_user = user_id' ] ]
+                                       );
+                               }
+                               foreach ( $res as $row ) {
+                                       $names[$row->user_name] = $row;
+                               }
+                               call_user_func_array(
+                                       $this->params['dir'] == 'newer' ? 'ksort' : 'krsort', [ &$names, SORT_STRING ]
+                               );
+                               $neg = $op === '>' ? -1 : 1;
+                               $userIter = call_user_func( function () use ( $names, $fromName, $neg ) {
+                                       foreach ( $names as $name => $row ) {
+                                               if ( $fromName === false || $neg * strcmp( $name, $fromName ) <= 0 ) {
+                                                       $user = $row ? User::newFromRow( $row ) : User::newFromName( $name, false );
+                                                       yield $user;
+                                               }
+                                       }
+                               } );
+                       }
+                       $batchSize = count( $names );
+               }
+
+               // During migration, force ordering on the client side because we're
+               // having to combine multiple queries that would otherwise have
+               // different sort orders.
+               if ( $wgActorTableSchemaMigrationStage === MIGRATION_WRITE_BOTH ||
+                       $wgActorTableSchemaMigrationStage === MIGRATION_WRITE_NEW
+               ) {
+                       $batchSize = 1;
+               }
+
+               // With the new schema, the DB query will order by actor so update $this->orderBy to match.
+               if ( $batchSize > 1 && $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
+                       $this->orderBy = 'actor';
+               }
+
+               $count = 0;
+               $limit = $this->params['limit'];
+               $userIter->rewind();
+               while ( $userIter->valid() ) {
+                       $users = [];
+                       while ( count( $users ) < $batchSize && $userIter->valid() ) {
+                               $users[] = $userIter->current();
+                               $userIter->next();
+                       }
+
+                       // Ugh. We have to run the query three times, once for each
+                       // possible 'orcond' from ActorMigration, and then merge them all
+                       // together in the proper order. And preserving the correct
+                       // $hookData for each one.
+                       // @todo When ActorMigration is removed, this can go back to a
+                       //  single prepare and select.
+                       $merged = [];
+                       foreach ( [ 'actor', 'userid', 'username' ] as $which ) {
+                               if ( $this->prepareQuery( $users, $limit - $count, $which ) ) {
+                                       $hookData = [];
+                                       $res = $this->select( __METHOD__, [], $hookData );
+                                       foreach ( $res as $row ) {
+                                               $merged[] = [ $row, &$hookData ];
+                                       }
+                               }
+                       }
+                       $neg = $this->params['dir'] == 'newer' ? 1 : -1;
+                       usort( $merged, function ( $a, $b ) use ( $neg, $batchSize ) {
+                               if ( $batchSize === 1 ) { // One user, can't be different
+                                       $ret = 0;
+                               } elseif ( $this->orderBy === 'id' ) {
+                                       $ret = $a[0]->rev_user - $b[0]->rev_user;
+                               } elseif ( $this->orderBy === 'name' ) {
+                                       $ret = strcmp( $a[0]->rev_user_text, $b[0]->rev_user_text );
+                               } else {
+                                       $ret = $a[0]->rev_actor - $b[0]->rev_actor;
+                               }
+
+                               if ( !$ret ) {
+                                       $ret = strcmp(
+                                               wfTimestamp( TS_MW, $a[0]->rev_timestamp ),
+                                               wfTimestamp( TS_MW, $b[0]->rev_timestamp )
+                                       );
+                               }
+
+                               if ( !$ret ) {
+                                       $ret = $a[0]->rev_id - $b[0]->rev_id;
+                               }
+
+                               return $neg * $ret;
+                       } );
+                       $merged = array_slice( $merged, 0, $limit - $count + 1 );
+                       // (end "Ugh")
+
+                       if ( $this->fld_sizediff ) {
+                               $revIds = [];
+                               foreach ( $merged as $data ) {
+                                       if ( $data[0]->rev_parent_id ) {
+                                               $revIds[] = $data[0]->rev_parent_id;
+                                       }
+                               }
+                               $this->parentLens = Revision::getParentLengths( $dbSecondary, $revIds );
+                       }
+
+                       foreach ( $merged as $data ) {
+                               $row = $data[0];
+                               $hookData = &$data[1];
+                               if ( ++$count > $limit ) {
+                                       // We've reached the one extra which shows that there are
+                                       // additional pages to be had. Stop here...
+                                       $this->setContinueEnumParameter( 'continue', $this->continueStr( $row ) );
+                                       break 2;
+                               }
+
+                               $vals = $this->extractRowInfo( $row );
+                               $fit = $this->processRow( $row, $vals, $hookData ) &&
+                                       $this->getResult()->addValue( [ 'query', $this->getModuleName() ], null, $vals );
+                               if ( !$fit ) {
+                                       $this->setContinueEnumParameter( 'continue', $this->continueStr( $row ) );
+                                       break 2;
+                               }
+                       }
+               }
+
+               $this->getResult()->addIndexedTagName( [ 'query', $this->getModuleName() ], 'item' );
+       }
+
+       /**
+        * Prepares the query and returns the limit of rows requested
+        * @param User[] $users
+        * @param int $limit
+        * @param string $which 'actor', 'userid', or 'username'
+        * @return bool
+        */
+       private function prepareQuery( array $users, $limit, $which ) {
+               global $wgActorTableSchemaMigrationStage;
+
+               $this->resetQueryParams();
+               $db = $this->getDB();
+
+               $revQuery = Revision::getQueryInfo( [ 'page' ] );
+               $this->addTables( $revQuery['tables'] );
+               $this->addJoinConds( $revQuery['joins'] );
+               $this->addFields( $revQuery['fields'] );
+
+               $revWhere = ActorMigration::newMigration()->getWhere( $db, 'rev_user', $users );
+               if ( !isset( $revWhere['orconds'][$which] ) ) {
+                       return false;
+               }
+               $this->addWhere( $revWhere['orconds'][$which] );
+
+               if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
+                       $orderUserField = 'rev_actor';
+                       $userField = $this->orderBy === 'actor' ? 'revactor_actor' : 'actor_name';
+               } else {
+                       $orderUserField = $this->orderBy === 'id' ? 'rev_user' : 'rev_user_text';
+                       $userField = $revQuery['fields'][$orderUserField];
+               }
+               if ( $which === 'actor' ) {
+                       $tsField = 'revactor_timestamp';
+                       $idField = 'revactor_rev';
+               } else {
+                       $tsField = 'rev_timestamp';
+                       $idField = 'rev_id';
+               }
+
+               // Handle continue parameter
+               if ( !is_null( $this->params['continue'] ) ) {
+                       $continue = explode( '|', $this->params['continue'] );
+                       if ( $this->multiUserMode ) {
+                               $this->dieContinueUsageIf( count( $continue ) != 4 );
+                               $modeFlag = array_shift( $continue );
+                               $this->dieContinueUsageIf( $modeFlag !== $this->orderBy );
+                               $encUser = $db->addQuotes( array_shift( $continue ) );
+                       } else {
+                               $this->dieContinueUsageIf( count( $continue ) != 2 );
+                       }
+                       $encTS = $db->addQuotes( $db->timestamp( $continue[0] ) );
+                       $encId = (int)$continue[1];
+                       $this->dieContinueUsageIf( $encId != $continue[1] );
+                       $op = ( $this->params['dir'] == 'older' ? '<' : '>' );
+                       if ( $this->multiUserMode ) {
+                               $this->addWhere(
+                                       "$userField $op $encUser OR " .
+                                       "($userField = $encUser AND " .
+                                       "($tsField $op $encTS OR " .
+                                       "($tsField = $encTS AND " .
+                                       "$idField $op= $encId)))"
+                               );
+                       } else {
+                               $this->addWhere(
+                                       "$tsField $op $encTS OR " .
+                                       "($tsField = $encTS AND " .
+                                       "$idField $op= $encId)"
+                               );
+                       }
+               }
+
+               // Don't include any revisions where we're not supposed to be able to
+               // see the username.
+               $user = $this->getUser();
+               if ( !$user->isAllowed( 'deletedhistory' ) ) {
+                       $bitmask = Revision::DELETED_USER;
+               } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
+                       $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED;
+               } else {
+                       $bitmask = 0;
+               }
+               if ( $bitmask ) {
+                       $this->addWhere( $db->bitAnd( 'rev_deleted', $bitmask ) . " != $bitmask" );
+               }
+
+               // Add the user field to ORDER BY if there are multiple users
+               if ( count( $users ) > 1 ) {
+                       $this->addWhereRange( $orderUserField, $this->params['dir'], null, null );
+               }
+
+               // Then timestamp
+               $this->addTimestampWhereRange( $tsField,
+                       $this->params['dir'], $this->params['start'], $this->params['end'] );
+
+               // Then rev_id for a total ordering
+               $this->addWhereRange( $idField, $this->params['dir'], null, null );
+
+               $this->addWhereFld( 'page_namespace', $this->params['namespace'] );
+
+               $show = $this->params['show'];
+               if ( $this->params['toponly'] ) { // deprecated/old param
+                       $show[] = 'top';
+               }
+               if ( !is_null( $show ) ) {
+                       $show = array_flip( $show );
+
+                       if ( ( isset( $show['minor'] ) && isset( $show['!minor'] ) )
+                               || ( isset( $show['patrolled'] ) && isset( $show['!patrolled'] ) )
+                               || ( isset( $show['autopatrolled'] ) && isset( $show['!autopatrolled'] ) )
+                               || ( isset( $show['autopatrolled'] ) && isset( $show['!patrolled'] ) )
+                               || ( isset( $show['top'] ) && isset( $show['!top'] ) )
+                               || ( isset( $show['new'] ) && isset( $show['!new'] ) )
+                       ) {
+                               $this->dieWithError( 'apierror-show' );
+                       }
+
+                       $this->addWhereIf( 'rev_minor_edit = 0', isset( $show['!minor'] ) );
+                       $this->addWhereIf( 'rev_minor_edit != 0', isset( $show['minor'] ) );
+                       $this->addWhereIf(
+                               'rc_patrolled = ' . RecentChange::PRC_UNPATROLLED,
+                               isset( $show['!patrolled'] )
+                       );
+                       $this->addWhereIf(
+                               'rc_patrolled != ' . RecentChange::PRC_UNPATROLLED,
+                               isset( $show['patrolled'] )
+                       );
+                       $this->addWhereIf(
+                               'rc_patrolled != ' . RecentChange::PRC_AUTOPATROLLED,
+                               isset( $show['!autopatrolled'] )
+                       );
+                       $this->addWhereIf(
+                               'rc_patrolled = ' . RecentChange::PRC_AUTOPATROLLED,
+                               isset( $show['autopatrolled'] )
+                       );
+                       $this->addWhereIf( $idField . ' != page_latest', isset( $show['!top'] ) );
+                       $this->addWhereIf( $idField . ' = page_latest', isset( $show['top'] ) );
+                       $this->addWhereIf( 'rev_parent_id != 0', isset( $show['!new'] ) );
+                       $this->addWhereIf( 'rev_parent_id = 0', isset( $show['new'] ) );
+               }
+               $this->addOption( 'LIMIT', $limit + 1 );
+
+               if ( isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ||
+                       isset( $show['autopatrolled'] ) || isset( $show['!autopatrolled'] ) || $this->fld_patrolled
+               ) {
+                       if ( !$user->useRCPatrol() && !$user->useNPPatrol() ) {
+                               $this->dieWithError( 'apierror-permissiondenied-patrolflag', 'permissiondenied' );
+                       }
+
+                       $isFilterset = isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ||
+                               isset( $show['autopatrolled'] ) || isset( $show['!autopatrolled'] );
+                       $this->addTables( 'recentchanges' );
+                       $this->addJoinConds( [ 'recentchanges' => [
+                               $isFilterset ? 'JOIN' : 'LEFT JOIN',
+                               [
+                                       // This is a crazy hack. recentchanges has no index on rc_this_oldid, so instead of adding
+                                       // one T19237 did a join using rc_user_text and rc_timestamp instead. Now rc_user_text is
+                                       // probably unavailable, so just do rc_timestamp.
+                                       'rc_timestamp = ' . $tsField,
+                                       'rc_this_oldid = ' . $idField,
+                               ]
+                       ] ] );
+               }
+
+               $this->addFieldsIf( 'rc_patrolled', $this->fld_patrolled );
+
+               if ( $this->fld_tags ) {
+                       $this->addTables( 'tag_summary' );
+                       $this->addJoinConds(
+                               [ 'tag_summary' => [ 'LEFT JOIN', [ $idField . ' = ts_rev_id' ] ] ]
+                       );
+                       $this->addFields( 'ts_tags' );
+               }
+
+               if ( isset( $this->params['tag'] ) ) {
+                       $this->addTables( 'change_tag' );
+                       $this->addJoinConds(
+                               [ 'change_tag' => [ 'INNER JOIN', [ $idField . ' = ct_rev_id' ] ] ]
+                       );
+                       $this->addWhereFld( 'ct_tag', $this->params['tag'] );
+               }
+
+               return true;
+       }
+
+       /**
+        * Extract fields from the database row and append them to a result array
+        *
+        * @param stdClass $row
+        * @return array
+        */
+       private function extractRowInfo( $row ) {
+               $vals = [];
+               $anyHidden = false;
+
+               if ( $row->rev_deleted & Revision::DELETED_TEXT ) {
+                       $vals['texthidden'] = true;
+                       $anyHidden = true;
+               }
+
+               // Any rows where we can't view the user were filtered out in the query.
+               $vals['userid'] = (int)$row->rev_user;
+               $vals['user'] = $row->rev_user_text;
+               if ( $row->rev_deleted & Revision::DELETED_USER ) {
+                       $vals['userhidden'] = true;
+                       $anyHidden = true;
+               }
+               if ( $this->fld_ids ) {
+                       $vals['pageid'] = intval( $row->rev_page );
+                       $vals['revid'] = intval( $row->rev_id );
+                       // $vals['textid'] = intval( $row->rev_text_id ); // todo: Should this field be exposed?
+
+                       if ( !is_null( $row->rev_parent_id ) ) {
+                               $vals['parentid'] = intval( $row->rev_parent_id );
+                       }
+               }
+
+               $title = Title::makeTitle( $row->page_namespace, $row->page_title );
+
+               if ( $this->fld_title ) {
+                       ApiQueryBase::addTitleInfo( $vals, $title );
+               }
+
+               if ( $this->fld_timestamp ) {
+                       $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->rev_timestamp );
+               }
+
+               if ( $this->fld_flags ) {
+                       $vals['new'] = $row->rev_parent_id == 0 && !is_null( $row->rev_parent_id );
+                       $vals['minor'] = (bool)$row->rev_minor_edit;
+                       $vals['top'] = $row->page_latest == $row->rev_id;
+               }
+
+               if ( $this->fld_comment || $this->fld_parsedcomment ) {
+                       if ( $row->rev_deleted & Revision::DELETED_COMMENT ) {
+                               $vals['commenthidden'] = true;
+                               $anyHidden = true;
+                       }
+
+                       $userCanView = Revision::userCanBitfield(
+                               $row->rev_deleted,
+                               Revision::DELETED_COMMENT, $this->getUser()
+                       );
+
+                       if ( $userCanView ) {
+                               $comment = $this->commentStore->getComment( 'rev_comment', $row )->text;
+                               if ( $this->fld_comment ) {
+                                       $vals['comment'] = $comment;
+                               }
+
+                               if ( $this->fld_parsedcomment ) {
+                                       $vals['parsedcomment'] = Linker::formatComment( $comment, $title );
+                               }
+                       }
+               }
+
+               if ( $this->fld_patrolled ) {
+                       $vals['patrolled'] = $row->rc_patrolled != RecentChange::PRC_UNPATROLLED;
+                       $vals['autopatrolled'] = $row->rc_patrolled == RecentChange::PRC_AUTOPATROLLED;
+               }
+
+               if ( $this->fld_size && !is_null( $row->rev_len ) ) {
+                       $vals['size'] = intval( $row->rev_len );
+               }
+
+               if ( $this->fld_sizediff
+                       && !is_null( $row->rev_len )
+                       && !is_null( $row->rev_parent_id )
+               ) {
+                       $parentLen = isset( $this->parentLens[$row->rev_parent_id] )
+                               ? $this->parentLens[$row->rev_parent_id]
+                               : 0;
+                       $vals['sizediff'] = intval( $row->rev_len - $parentLen );
+               }
+
+               if ( $this->fld_tags ) {
+                       if ( $row->ts_tags ) {
+                               $tags = explode( ',', $row->ts_tags );
+                               ApiResult::setIndexedTagName( $tags, 'tag' );
+                               $vals['tags'] = $tags;
+                       } else {
+                               $vals['tags'] = [];
+                       }
+               }
+
+               if ( $anyHidden && $row->rev_deleted & Revision::DELETED_RESTRICTED ) {
+                       $vals['suppressed'] = true;
+               }
+
+               return $vals;
+       }
+
+       private function continueStr( $row ) {
+               if ( $this->multiUserMode ) {
+                       switch ( $this->orderBy ) {
+                               case 'id':
+                                       return "id|$row->rev_user|$row->rev_timestamp|$row->rev_id";
+                               case 'name':
+                                       return "name|$row->rev_user_text|$row->rev_timestamp|$row->rev_id";
+                               case 'actor':
+                                       return "actor|$row->rev_actor|$row->rev_timestamp|$row->rev_id";
+                       }
+               } else {
+                       return "$row->rev_timestamp|$row->rev_id";
+               }
+       }
+
+       public function getCacheMode( $params ) {
+               // This module provides access to deleted revisions and patrol flags if
+               // the requester is logged in
+               return 'anon-public-user-private';
+       }
+
+       public function getAllowedParams() {
+               return [
+                       'limit' => [
+                               ApiBase::PARAM_DFLT => 10,
+                               ApiBase::PARAM_TYPE => 'limit',
+                               ApiBase::PARAM_MIN => 1,
+                               ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
+                               ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
+                       ],
+                       'start' => [
+                               ApiBase::PARAM_TYPE => 'timestamp'
+                       ],
+                       'end' => [
+                               ApiBase::PARAM_TYPE => 'timestamp'
+                       ],
+                       'continue' => [
+                               ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+                       ],
+                       'user' => [
+                               ApiBase::PARAM_TYPE => 'user',
+                               ApiBase::PARAM_ISMULTI => true
+                       ],
+                       'userids' => [
+                               ApiBase::PARAM_TYPE => 'integer',
+                               ApiBase::PARAM_ISMULTI => true
+                       ],
+                       'userprefix' => null,
+                       'dir' => [
+                               ApiBase::PARAM_DFLT => 'older',
+                               ApiBase::PARAM_TYPE => [
+                                       'newer',
+                                       'older'
+                               ],
+                               ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
+                       ],
+                       'namespace' => [
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_TYPE => 'namespace'
+                       ],
+                       'prop' => [
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_DFLT => 'ids|title|timestamp|comment|size|flags',
+                               ApiBase::PARAM_TYPE => [
+                                       'ids',
+                                       'title',
+                                       'timestamp',
+                                       'comment',
+                                       'parsedcomment',
+                                       'size',
+                                       'sizediff',
+                                       'flags',
+                                       'patrolled',
+                                       'tags'
+                               ],
+                               ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
+                       ],
+                       'show' => [
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_TYPE => [
+                                       'minor',
+                                       '!minor',
+                                       'patrolled',
+                                       '!patrolled',
+                                       'autopatrolled',
+                                       '!autopatrolled',
+                                       'top',
+                                       '!top',
+                                       'new',
+                                       '!new',
+                               ],
+                               ApiBase::PARAM_HELP_MSG => [
+                                       'apihelp-query+usercontribs-param-show',
+                                       $this->getConfig()->get( 'RCMaxAge' )
+                               ],
+                       ],
+                       'tag' => null,
+                       'toponly' => [
+                               ApiBase::PARAM_DFLT => false,
+                               ApiBase::PARAM_DEPRECATED => true,
+                       ],
+               ];
+       }
+
+       protected function getExamplesMessages() {
+               return [
+                       'action=query&list=usercontribs&ucuser=Example'
+                               => 'apihelp-query+usercontribs-example-user',
+                       'action=query&list=usercontribs&ucuserprefix=192.0.2.'
+                               => 'apihelp-query+usercontribs-example-ipprefix',
+               ];
+       }
+
+       public function getHelpUrls() {
+               return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Usercontribs';
+       }
+}
+
+/**
+ * @since 1.9
+ * @deprecated since 1.32
+ */
+class_alias( ApiQueryUserContribs::class, 'ApiQueryContributions' );
diff --git a/includes/api/ApiQueryUserContributions.php b/includes/api/ApiQueryUserContributions.php
deleted file mode 100644 (file)
index 12f42ed..0000000
+++ /dev/null
@@ -1,832 +0,0 @@
-<?php
-/**
- * Copyright © 2006 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
- */
-
-/**
- * This query action adds a list of a specified user's contributions to the output.
- *
- * @ingroup API
- */
-class ApiQueryContributions extends ApiQueryBase {
-
-       public function __construct( ApiQuery $query, $moduleName ) {
-               parent::__construct( $query, $moduleName, 'uc' );
-       }
-
-       private $params, $multiUserMode, $orderBy, $parentLens;
-       private $fld_ids = false, $fld_title = false, $fld_timestamp = false,
-               $fld_comment = false, $fld_parsedcomment = false, $fld_flags = false,
-               $fld_patrolled = false, $fld_tags = false, $fld_size = false, $fld_sizediff = false;
-
-       public function execute() {
-               global $wgActorTableSchemaMigrationStage;
-
-               // Parse some parameters
-               $this->params = $this->extractRequestParams();
-
-               $this->commentStore = CommentStore::getStore();
-
-               $prop = array_flip( $this->params['prop'] );
-               $this->fld_ids = isset( $prop['ids'] );
-               $this->fld_title = isset( $prop['title'] );
-               $this->fld_comment = isset( $prop['comment'] );
-               $this->fld_parsedcomment = isset( $prop['parsedcomment'] );
-               $this->fld_size = isset( $prop['size'] );
-               $this->fld_sizediff = isset( $prop['sizediff'] );
-               $this->fld_flags = isset( $prop['flags'] );
-               $this->fld_timestamp = isset( $prop['timestamp'] );
-               $this->fld_patrolled = isset( $prop['patrolled'] );
-               $this->fld_tags = isset( $prop['tags'] );
-
-               // Most of this code will use the 'contributions' group DB, which can map to replica DBs
-               // with extra user based indexes or partioning by user. The additional metadata
-               // queries should use a regular replica DB since the lookup pattern is not all by user.
-               $dbSecondary = $this->getDB(); // any random replica DB
-
-               // TODO: if the query is going only against the revision table, should this be done?
-               $this->selectNamedDB( 'contributions', DB_REPLICA, 'contributions' );
-
-               $sort = ( $this->params['dir'] == 'newer' ? '' : ' DESC' );
-               $op = ( $this->params['dir'] == 'older' ? '<' : '>' );
-
-               // Create an Iterator that produces the UserIdentity objects we need, depending
-               // on which of the 'userprefix', 'userids', or 'user' params was
-               // specified.
-               $this->requireOnlyOneParameter( $this->params, 'userprefix', 'userids', 'user' );
-               if ( isset( $this->params['userprefix'] ) ) {
-                       $this->multiUserMode = true;
-                       $this->orderBy = 'name';
-                       $fname = __METHOD__;
-
-                       // Because 'userprefix' might produce a huge number of users (e.g.
-                       // a wiki with users "Test00000001" to "Test99999999"), use a
-                       // generator with batched lookup and continuation.
-                       $userIter = call_user_func( function () use ( $dbSecondary, $sort, $op, $fname ) {
-                               global $wgActorTableSchemaMigrationStage;
-
-                               $fromName = false;
-                               if ( !is_null( $this->params['continue'] ) ) {
-                                       $continue = explode( '|', $this->params['continue'] );
-                                       $this->dieContinueUsageIf( count( $continue ) != 4 );
-                                       $this->dieContinueUsageIf( $continue[0] !== 'name' );
-                                       $fromName = $continue[1];
-                               }
-                               $like = $dbSecondary->buildLike( $this->params['userprefix'], $dbSecondary->anyString() );
-
-                               $limit = 501;
-
-                               do {
-                                       $from = $fromName ? "$op= " . $dbSecondary->addQuotes( $fromName ) : false;
-
-                                       // For the new schema, pull from the actor table. For the
-                                       // old, pull from rev_user. For migration a FULL [OUTER]
-                                       // JOIN would be what we want, except MySQL doesn't support
-                                       // that so we have to UNION instead.
-                                       if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
-                                               $res = $dbSecondary->select(
-                                                       'actor',
-                                                       [ 'actor_id', 'user_id' => 'COALESCE(actor_user,0)', 'user_name' => 'actor_name' ],
-                                                       array_merge( [ "actor_name$like" ], $from ? [ "actor_name $from" ] : [] ),
-                                                       $fname,
-                                                       [ 'ORDER BY' => [ "user_name $sort" ], 'LIMIT' => $limit ]
-                                               );
-                                       } elseif ( $wgActorTableSchemaMigrationStage === MIGRATION_OLD ) {
-                                               $res = $dbSecondary->select(
-                                                       'revision',
-                                                       [ 'actor_id' => 'NULL', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
-                                                       array_merge( [ "rev_user_text$like" ], $from ? [ "rev_user_text $from" ] : [] ),
-                                                       $fname,
-                                                       [ 'DISTINCT', 'ORDER BY' => [ "rev_user_text $sort" ], 'LIMIT' => $limit ]
-                                               );
-                                       } else {
-                                               // There are three queries we have to combine to be sure of getting all results:
-                                               //  - actor table (any rows that have been migrated will have empty rev_user_text)
-                                               //  - revision+actor by user id
-                                               //  - revision+actor by name for anons
-                                               $options = $dbSecondary->unionSupportsOrderAndLimit()
-                                                       ? [ 'ORDER BY' => [ "user_name $sort" ], 'LIMIT' => $limit ] : [];
-                                               $subsql = [];
-                                               $subsql[] = $dbSecondary->selectSQLText(
-                                                       'actor',
-                                                       [ 'actor_id', 'user_id' => 'COALESCE(actor_user,0)', 'user_name' => 'actor_name' ],
-                                                       array_merge( [ "actor_name$like" ], $from ? [ "actor_name $from" ] : [] ),
-                                                       $fname,
-                                                       $options
-                                               );
-                                               $subsql[] = $dbSecondary->selectSQLText(
-                                                       [ 'revision', 'actor' ],
-                                                       [ 'actor_id', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
-                                                       array_merge(
-                                                               [ "rev_user_text$like", 'rev_user != 0' ],
-                                                               $from ? [ "rev_user_text $from" ] : []
-                                                       ),
-                                                       $fname,
-                                                       array_merge( [ 'DISTINCT' ], $options ),
-                                                       [ 'actor' => [ 'LEFT JOIN', 'rev_user = actor_user' ] ]
-                                               );
-                                               $subsql[] = $dbSecondary->selectSQLText(
-                                                       [ 'revision', 'actor' ],
-                                                       [ 'actor_id', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
-                                                       array_merge(
-                                                               [ "rev_user_text$like", 'rev_user = 0' ],
-                                                               $from ? [ "rev_user_text $from" ] : []
-                                                       ),
-                                                       $fname,
-                                                       array_merge( [ 'DISTINCT' ], $options ),
-                                                       [ 'actor' => [ 'LEFT JOIN', 'rev_user_text = actor_name' ] ]
-                                               );
-                                               $sql = $dbSecondary->unionQueries( $subsql, false ) . " ORDER BY user_name $sort";
-                                               $sql = $dbSecondary->limitResult( $sql, $limit );
-                                               $res = $dbSecondary->query( $sql, $fname );
-                                       }
-
-                                       $count = 0;
-                                       $fromName = false;
-                                       foreach ( $res as $row ) {
-                                               if ( ++$count >= $limit ) {
-                                                       $fromName = $row->user_name;
-                                                       break;
-                                               }
-                                               yield User::newFromRow( $row );
-                                       }
-                               } while ( $fromName !== false );
-                       } );
-                       // Do the actual sorting client-side, because otherwise
-                       // prepareQuery might try to sort by actor and confuse everything.
-                       $batchSize = 1;
-               } elseif ( isset( $this->params['userids'] ) ) {
-                       if ( !count( $this->params['userids'] ) ) {
-                               $encParamName = $this->encodeParamName( 'userids' );
-                               $this->dieWithError( [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName" );
-                       }
-
-                       $ids = [];
-                       foreach ( $this->params['userids'] as $uid ) {
-                               if ( $uid <= 0 ) {
-                                       $this->dieWithError( [ 'apierror-invaliduserid', $uid ], 'invaliduserid' );
-                               }
-                               $ids[] = $uid;
-                       }
-
-                       $this->orderBy = 'id';
-                       $this->multiUserMode = count( $ids ) > 1;
-
-                       $from = $fromId = false;
-                       if ( $this->multiUserMode && !is_null( $this->params['continue'] ) ) {
-                               $continue = explode( '|', $this->params['continue'] );
-                               $this->dieContinueUsageIf( count( $continue ) != 4 );
-                               $this->dieContinueUsageIf( $continue[0] !== 'id' && $continue[0] !== 'actor' );
-                               $fromId = (int)$continue[1];
-                               $this->dieContinueUsageIf( $continue[1] !== (string)$fromId );
-                               $from = "$op= $fromId";
-                       }
-
-                       // For the new schema, just select from the actor table. For the
-                       // old and transitional schemas, select from user and left join
-                       // actor if it exists.
-                       if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
-                               $res = $dbSecondary->select(
-                                       'actor',
-                                       [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
-                                       array_merge( [ 'actor_user' => $ids ], $from ? [ "actor_id $from" ] : [] ),
-                                       __METHOD__,
-                                       [ 'ORDER BY' => "user_id $sort" ]
-                               );
-                       } elseif ( $wgActorTableSchemaMigrationStage === MIGRATION_OLD ) {
-                               $res = $dbSecondary->select(
-                                       'user',
-                                       [ 'actor_id' => 'NULL', 'user_id' => 'user_id', 'user_name' => 'user_name' ],
-                                       array_merge( [ 'user_id' => $ids ], $from ? [ "user_id $from" ] : [] ),
-                                       __METHOD__,
-                                       [ 'ORDER BY' => "user_id $sort" ]
-                               );
-                       } else {
-                               $res = $dbSecondary->select(
-                                       [ 'user', 'actor' ],
-                                       [ 'actor_id', 'user_id', 'user_name' ],
-                                       array_merge( [ 'user_id' => $ids ], $from ? [ "user_id $from" ] : [] ),
-                                       __METHOD__,
-                                       [ 'ORDER BY' => "user_id $sort" ],
-                                       [ 'actor' => [ 'LEFT JOIN', 'actor_user = user_id' ] ]
-                               );
-                       }
-                       $userIter = UserArray::newFromResult( $res );
-                       $batchSize = count( $ids );
-               } else {
-                       $names = [];
-                       if ( !count( $this->params['user'] ) ) {
-                               $encParamName = $this->encodeParamName( 'user' );
-                               $this->dieWithError(
-                                       [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName"
-                               );
-                       }
-                       foreach ( $this->params['user'] as $u ) {
-                               if ( $u === '' ) {
-                                       $encParamName = $this->encodeParamName( 'user' );
-                                       $this->dieWithError(
-                                               [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName"
-                                       );
-                               }
-
-                               if ( User::isIP( $u ) || ExternalUserNames::isExternal( $u ) ) {
-                                       $names[$u] = null;
-                               } else {
-                                       $name = User::getCanonicalName( $u, 'valid' );
-                                       if ( $name === false ) {
-                                               $encParamName = $this->encodeParamName( 'user' );
-                                               $this->dieWithError(
-                                                       [ 'apierror-baduser', $encParamName, wfEscapeWikiText( $u ) ], "baduser_$encParamName"
-                                               );
-                                       }
-                                       $names[$name] = null;
-                               }
-                       }
-
-                       $this->orderBy = 'name';
-                       $this->multiUserMode = count( $names ) > 1;
-
-                       $from = $fromName = false;
-                       if ( $this->multiUserMode && !is_null( $this->params['continue'] ) ) {
-                               $continue = explode( '|', $this->params['continue'] );
-                               $this->dieContinueUsageIf( count( $continue ) != 4 );
-                               $this->dieContinueUsageIf( $continue[0] !== 'name' && $continue[0] !== 'actor' );
-                               $fromName = $continue[1];
-                               $from = "$op= " . $dbSecondary->addQuotes( $fromName );
-                       }
-
-                       // For the new schema, just select from the actor table. For the
-                       // old and transitional schemas, select from user and left join
-                       // actor if it exists then merge in any unknown users (IPs and imports).
-                       if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
-                               $res = $dbSecondary->select(
-                                       'actor',
-                                       [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
-                                       array_merge( [ 'actor_name' => array_keys( $names ) ], $from ? [ "actor_id $from" ] : [] ),
-                                       __METHOD__,
-                                       [ 'ORDER BY' => "actor_name $sort" ]
-                               );
-                               $userIter = UserArray::newFromResult( $res );
-                       } else {
-                               if ( $wgActorTableSchemaMigrationStage === MIGRATION_OLD ) {
-                                       $res = $dbSecondary->select(
-                                               'user',
-                                               [ 'actor_id' => 'NULL', 'user_id', 'user_name' ],
-                                               array_merge( [ 'user_name' => array_keys( $names ) ], $from ? [ "user_name $from" ] : [] ),
-                                               __METHOD__
-                                       );
-                               } else {
-                                       $res = $dbSecondary->select(
-                                               [ 'user', 'actor' ],
-                                               [ 'actor_id', 'user_id', 'user_name' ],
-                                               array_merge( [ 'user_name' => array_keys( $names ) ], $from ? [ "user_name $from" ] : [] ),
-                                               __METHOD__,
-                                               [],
-                                               [ 'actor' => [ 'LEFT JOIN', 'actor_user = user_id' ] ]
-                                       );
-                               }
-                               foreach ( $res as $row ) {
-                                       $names[$row->user_name] = $row;
-                               }
-                               call_user_func_array(
-                                       $this->params['dir'] == 'newer' ? 'ksort' : 'krsort', [ &$names, SORT_STRING ]
-                               );
-                               $neg = $op === '>' ? -1 : 1;
-                               $userIter = call_user_func( function () use ( $names, $fromName, $neg ) {
-                                       foreach ( $names as $name => $row ) {
-                                               if ( $fromName === false || $neg * strcmp( $name, $fromName ) <= 0 ) {
-                                                       $user = $row ? User::newFromRow( $row ) : User::newFromName( $name, false );
-                                                       yield $user;
-                                               }
-                                       }
-                               } );
-                       }
-                       $batchSize = count( $names );
-               }
-
-               // During migration, force ordering on the client side because we're
-               // having to combine multiple queries that would otherwise have
-               // different sort orders.
-               if ( $wgActorTableSchemaMigrationStage === MIGRATION_WRITE_BOTH ||
-                       $wgActorTableSchemaMigrationStage === MIGRATION_WRITE_NEW
-               ) {
-                       $batchSize = 1;
-               }
-
-               // With the new schema, the DB query will order by actor so update $this->orderBy to match.
-               if ( $batchSize > 1 && $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
-                       $this->orderBy = 'actor';
-               }
-
-               $count = 0;
-               $limit = $this->params['limit'];
-               $userIter->rewind();
-               while ( $userIter->valid() ) {
-                       $users = [];
-                       while ( count( $users ) < $batchSize && $userIter->valid() ) {
-                               $users[] = $userIter->current();
-                               $userIter->next();
-                       }
-
-                       // Ugh. We have to run the query three times, once for each
-                       // possible 'orcond' from ActorMigration, and then merge them all
-                       // together in the proper order. And preserving the correct
-                       // $hookData for each one.
-                       // @todo When ActorMigration is removed, this can go back to a
-                       //  single prepare and select.
-                       $merged = [];
-                       foreach ( [ 'actor', 'userid', 'username' ] as $which ) {
-                               if ( $this->prepareQuery( $users, $limit - $count, $which ) ) {
-                                       $hookData = [];
-                                       $res = $this->select( __METHOD__, [], $hookData );
-                                       foreach ( $res as $row ) {
-                                               $merged[] = [ $row, &$hookData ];
-                                       }
-                               }
-                       }
-                       $neg = $this->params['dir'] == 'newer' ? 1 : -1;
-                       usort( $merged, function ( $a, $b ) use ( $neg, $batchSize ) {
-                               if ( $batchSize === 1 ) { // One user, can't be different
-                                       $ret = 0;
-                               } elseif ( $this->orderBy === 'id' ) {
-                                       $ret = $a[0]->rev_user - $b[0]->rev_user;
-                               } elseif ( $this->orderBy === 'name' ) {
-                                       $ret = strcmp( $a[0]->rev_user_text, $b[0]->rev_user_text );
-                               } else {
-                                       $ret = $a[0]->rev_actor - $b[0]->rev_actor;
-                               }
-
-                               if ( !$ret ) {
-                                       $ret = strcmp(
-                                               wfTimestamp( TS_MW, $a[0]->rev_timestamp ),
-                                               wfTimestamp( TS_MW, $b[0]->rev_timestamp )
-                                       );
-                               }
-
-                               if ( !$ret ) {
-                                       $ret = $a[0]->rev_id - $b[0]->rev_id;
-                               }
-
-                               return $neg * $ret;
-                       } );
-                       $merged = array_slice( $merged, 0, $limit - $count + 1 );
-                       // (end "Ugh")
-
-                       if ( $this->fld_sizediff ) {
-                               $revIds = [];
-                               foreach ( $merged as $data ) {
-                                       if ( $data[0]->rev_parent_id ) {
-                                               $revIds[] = $data[0]->rev_parent_id;
-                                       }
-                               }
-                               $this->parentLens = Revision::getParentLengths( $dbSecondary, $revIds );
-                       }
-
-                       foreach ( $merged as $data ) {
-                               $row = $data[0];
-                               $hookData = &$data[1];
-                               if ( ++$count > $limit ) {
-                                       // We've reached the one extra which shows that there are
-                                       // additional pages to be had. Stop here...
-                                       $this->setContinueEnumParameter( 'continue', $this->continueStr( $row ) );
-                                       break 2;
-                               }
-
-                               $vals = $this->extractRowInfo( $row );
-                               $fit = $this->processRow( $row, $vals, $hookData ) &&
-                                       $this->getResult()->addValue( [ 'query', $this->getModuleName() ], null, $vals );
-                               if ( !$fit ) {
-                                       $this->setContinueEnumParameter( 'continue', $this->continueStr( $row ) );
-                                       break 2;
-                               }
-                       }
-               }
-
-               $this->getResult()->addIndexedTagName( [ 'query', $this->getModuleName() ], 'item' );
-       }
-
-       /**
-        * Prepares the query and returns the limit of rows requested
-        * @param User[] $users
-        * @param int $limit
-        * @param string $which 'actor', 'userid', or 'username'
-        * @return bool
-        */
-       private function prepareQuery( array $users, $limit, $which ) {
-               global $wgActorTableSchemaMigrationStage;
-
-               $this->resetQueryParams();
-               $db = $this->getDB();
-
-               $revQuery = Revision::getQueryInfo( [ 'page' ] );
-               $this->addTables( $revQuery['tables'] );
-               $this->addJoinConds( $revQuery['joins'] );
-               $this->addFields( $revQuery['fields'] );
-
-               $revWhere = ActorMigration::newMigration()->getWhere( $db, 'rev_user', $users );
-               if ( !isset( $revWhere['orconds'][$which] ) ) {
-                       return false;
-               }
-               $this->addWhere( $revWhere['orconds'][$which] );
-
-               if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
-                       $orderUserField = 'rev_actor';
-                       $userField = $this->orderBy === 'actor' ? 'revactor_actor' : 'actor_name';
-               } else {
-                       $orderUserField = $this->orderBy === 'id' ? 'rev_user' : 'rev_user_text';
-                       $userField = $revQuery['fields'][$orderUserField];
-               }
-               if ( $which === 'actor' ) {
-                       $tsField = 'revactor_timestamp';
-                       $idField = 'revactor_rev';
-               } else {
-                       $tsField = 'rev_timestamp';
-                       $idField = 'rev_id';
-               }
-
-               // Handle continue parameter
-               if ( !is_null( $this->params['continue'] ) ) {
-                       $continue = explode( '|', $this->params['continue'] );
-                       if ( $this->multiUserMode ) {
-                               $this->dieContinueUsageIf( count( $continue ) != 4 );
-                               $modeFlag = array_shift( $continue );
-                               $this->dieContinueUsageIf( $modeFlag !== $this->orderBy );
-                               $encUser = $db->addQuotes( array_shift( $continue ) );
-                       } else {
-                               $this->dieContinueUsageIf( count( $continue ) != 2 );
-                       }
-                       $encTS = $db->addQuotes( $db->timestamp( $continue[0] ) );
-                       $encId = (int)$continue[1];
-                       $this->dieContinueUsageIf( $encId != $continue[1] );
-                       $op = ( $this->params['dir'] == 'older' ? '<' : '>' );
-                       if ( $this->multiUserMode ) {
-                               $this->addWhere(
-                                       "$userField $op $encUser OR " .
-                                       "($userField = $encUser AND " .
-                                       "($tsField $op $encTS OR " .
-                                       "($tsField = $encTS AND " .
-                                       "$idField $op= $encId)))"
-                               );
-                       } else {
-                               $this->addWhere(
-                                       "$tsField $op $encTS OR " .
-                                       "($tsField = $encTS AND " .
-                                       "$idField $op= $encId)"
-                               );
-                       }
-               }
-
-               // Don't include any revisions where we're not supposed to be able to
-               // see the username.
-               $user = $this->getUser();
-               if ( !$user->isAllowed( 'deletedhistory' ) ) {
-                       $bitmask = Revision::DELETED_USER;
-               } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
-                       $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED;
-               } else {
-                       $bitmask = 0;
-               }
-               if ( $bitmask ) {
-                       $this->addWhere( $db->bitAnd( 'rev_deleted', $bitmask ) . " != $bitmask" );
-               }
-
-               // Add the user field to ORDER BY if there are multiple users
-               if ( count( $users ) > 1 ) {
-                       $this->addWhereRange( $orderUserField, $this->params['dir'], null, null );
-               }
-
-               // Then timestamp
-               $this->addTimestampWhereRange( $tsField,
-                       $this->params['dir'], $this->params['start'], $this->params['end'] );
-
-               // Then rev_id for a total ordering
-               $this->addWhereRange( $idField, $this->params['dir'], null, null );
-
-               $this->addWhereFld( 'page_namespace', $this->params['namespace'] );
-
-               $show = $this->params['show'];
-               if ( $this->params['toponly'] ) { // deprecated/old param
-                       $show[] = 'top';
-               }
-               if ( !is_null( $show ) ) {
-                       $show = array_flip( $show );
-
-                       if ( ( isset( $show['minor'] ) && isset( $show['!minor'] ) )
-                               || ( isset( $show['patrolled'] ) && isset( $show['!patrolled'] ) )
-                               || ( isset( $show['autopatrolled'] ) && isset( $show['!autopatrolled'] ) )
-                               || ( isset( $show['autopatrolled'] ) && isset( $show['!patrolled'] ) )
-                               || ( isset( $show['top'] ) && isset( $show['!top'] ) )
-                               || ( isset( $show['new'] ) && isset( $show['!new'] ) )
-                       ) {
-                               $this->dieWithError( 'apierror-show' );
-                       }
-
-                       $this->addWhereIf( 'rev_minor_edit = 0', isset( $show['!minor'] ) );
-                       $this->addWhereIf( 'rev_minor_edit != 0', isset( $show['minor'] ) );
-                       $this->addWhereIf(
-                               'rc_patrolled = ' . RecentChange::PRC_UNPATROLLED,
-                               isset( $show['!patrolled'] )
-                       );
-                       $this->addWhereIf(
-                               'rc_patrolled != ' . RecentChange::PRC_UNPATROLLED,
-                               isset( $show['patrolled'] )
-                       );
-                       $this->addWhereIf(
-                               'rc_patrolled != ' . RecentChange::PRC_AUTOPATROLLED,
-                               isset( $show['!autopatrolled'] )
-                       );
-                       $this->addWhereIf(
-                               'rc_patrolled = ' . RecentChange::PRC_AUTOPATROLLED,
-                               isset( $show['autopatrolled'] )
-                       );
-                       $this->addWhereIf( $idField . ' != page_latest', isset( $show['!top'] ) );
-                       $this->addWhereIf( $idField . ' = page_latest', isset( $show['top'] ) );
-                       $this->addWhereIf( 'rev_parent_id != 0', isset( $show['!new'] ) );
-                       $this->addWhereIf( 'rev_parent_id = 0', isset( $show['new'] ) );
-               }
-               $this->addOption( 'LIMIT', $limit + 1 );
-
-               if ( isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ||
-                       isset( $show['autopatrolled'] ) || isset( $show['!autopatrolled'] ) || $this->fld_patrolled
-               ) {
-                       if ( !$user->useRCPatrol() && !$user->useNPPatrol() ) {
-                               $this->dieWithError( 'apierror-permissiondenied-patrolflag', 'permissiondenied' );
-                       }
-
-                       $isFilterset = isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ||
-                               isset( $show['autopatrolled'] ) || isset( $show['!autopatrolled'] );
-                       $this->addTables( 'recentchanges' );
-                       $this->addJoinConds( [ 'recentchanges' => [
-                               $isFilterset ? 'JOIN' : 'LEFT JOIN',
-                               [
-                                       // This is a crazy hack. recentchanges has no index on rc_this_oldid, so instead of adding
-                                       // one T19237 did a join using rc_user_text and rc_timestamp instead. Now rc_user_text is
-                                       // probably unavailable, so just do rc_timestamp.
-                                       'rc_timestamp = ' . $tsField,
-                                       'rc_this_oldid = ' . $idField,
-                               ]
-                       ] ] );
-               }
-
-               $this->addFieldsIf( 'rc_patrolled', $this->fld_patrolled );
-
-               if ( $this->fld_tags ) {
-                       $this->addTables( 'tag_summary' );
-                       $this->addJoinConds(
-                               [ 'tag_summary' => [ 'LEFT JOIN', [ $idField . ' = ts_rev_id' ] ] ]
-                       );
-                       $this->addFields( 'ts_tags' );
-               }
-
-               if ( isset( $this->params['tag'] ) ) {
-                       $this->addTables( 'change_tag' );
-                       $this->addJoinConds(
-                               [ 'change_tag' => [ 'INNER JOIN', [ $idField . ' = ct_rev_id' ] ] ]
-                       );
-                       $this->addWhereFld( 'ct_tag', $this->params['tag'] );
-               }
-
-               return true;
-       }
-
-       /**
-        * Extract fields from the database row and append them to a result array
-        *
-        * @param stdClass $row
-        * @return array
-        */
-       private function extractRowInfo( $row ) {
-               $vals = [];
-               $anyHidden = false;
-
-               if ( $row->rev_deleted & Revision::DELETED_TEXT ) {
-                       $vals['texthidden'] = true;
-                       $anyHidden = true;
-               }
-
-               // Any rows where we can't view the user were filtered out in the query.
-               $vals['userid'] = (int)$row->rev_user;
-               $vals['user'] = $row->rev_user_text;
-               if ( $row->rev_deleted & Revision::DELETED_USER ) {
-                       $vals['userhidden'] = true;
-                       $anyHidden = true;
-               }
-               if ( $this->fld_ids ) {
-                       $vals['pageid'] = intval( $row->rev_page );
-                       $vals['revid'] = intval( $row->rev_id );
-                       // $vals['textid'] = intval( $row->rev_text_id ); // todo: Should this field be exposed?
-
-                       if ( !is_null( $row->rev_parent_id ) ) {
-                               $vals['parentid'] = intval( $row->rev_parent_id );
-                       }
-               }
-
-               $title = Title::makeTitle( $row->page_namespace, $row->page_title );
-
-               if ( $this->fld_title ) {
-                       ApiQueryBase::addTitleInfo( $vals, $title );
-               }
-
-               if ( $this->fld_timestamp ) {
-                       $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->rev_timestamp );
-               }
-
-               if ( $this->fld_flags ) {
-                       $vals['new'] = $row->rev_parent_id == 0 && !is_null( $row->rev_parent_id );
-                       $vals['minor'] = (bool)$row->rev_minor_edit;
-                       $vals['top'] = $row->page_latest == $row->rev_id;
-               }
-
-               if ( $this->fld_comment || $this->fld_parsedcomment ) {
-                       if ( $row->rev_deleted & Revision::DELETED_COMMENT ) {
-                               $vals['commenthidden'] = true;
-                               $anyHidden = true;
-                       }
-
-                       $userCanView = Revision::userCanBitfield(
-                               $row->rev_deleted,
-                               Revision::DELETED_COMMENT, $this->getUser()
-                       );
-
-                       if ( $userCanView ) {
-                               $comment = $this->commentStore->getComment( 'rev_comment', $row )->text;
-                               if ( $this->fld_comment ) {
-                                       $vals['comment'] = $comment;
-                               }
-
-                               if ( $this->fld_parsedcomment ) {
-                                       $vals['parsedcomment'] = Linker::formatComment( $comment, $title );
-                               }
-                       }
-               }
-
-               if ( $this->fld_patrolled ) {
-                       $vals['patrolled'] = $row->rc_patrolled != RecentChange::PRC_UNPATROLLED;
-                       $vals['autopatrolled'] = $row->rc_patrolled == RecentChange::PRC_AUTOPATROLLED;
-               }
-
-               if ( $this->fld_size && !is_null( $row->rev_len ) ) {
-                       $vals['size'] = intval( $row->rev_len );
-               }
-
-               if ( $this->fld_sizediff
-                       && !is_null( $row->rev_len )
-                       && !is_null( $row->rev_parent_id )
-               ) {
-                       $parentLen = isset( $this->parentLens[$row->rev_parent_id] )
-                               ? $this->parentLens[$row->rev_parent_id]
-                               : 0;
-                       $vals['sizediff'] = intval( $row->rev_len - $parentLen );
-               }
-
-               if ( $this->fld_tags ) {
-                       if ( $row->ts_tags ) {
-                               $tags = explode( ',', $row->ts_tags );
-                               ApiResult::setIndexedTagName( $tags, 'tag' );
-                               $vals['tags'] = $tags;
-                       } else {
-                               $vals['tags'] = [];
-                       }
-               }
-
-               if ( $anyHidden && $row->rev_deleted & Revision::DELETED_RESTRICTED ) {
-                       $vals['suppressed'] = true;
-               }
-
-               return $vals;
-       }
-
-       private function continueStr( $row ) {
-               if ( $this->multiUserMode ) {
-                       switch ( $this->orderBy ) {
-                               case 'id':
-                                       return "id|$row->rev_user|$row->rev_timestamp|$row->rev_id";
-                               case 'name':
-                                       return "name|$row->rev_user_text|$row->rev_timestamp|$row->rev_id";
-                               case 'actor':
-                                       return "actor|$row->rev_actor|$row->rev_timestamp|$row->rev_id";
-                       }
-               } else {
-                       return "$row->rev_timestamp|$row->rev_id";
-               }
-       }
-
-       public function getCacheMode( $params ) {
-               // This module provides access to deleted revisions and patrol flags if
-               // the requester is logged in
-               return 'anon-public-user-private';
-       }
-
-       public function getAllowedParams() {
-               return [
-                       'limit' => [
-                               ApiBase::PARAM_DFLT => 10,
-                               ApiBase::PARAM_TYPE => 'limit',
-                               ApiBase::PARAM_MIN => 1,
-                               ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
-                               ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
-                       ],
-                       'start' => [
-                               ApiBase::PARAM_TYPE => 'timestamp'
-                       ],
-                       'end' => [
-                               ApiBase::PARAM_TYPE => 'timestamp'
-                       ],
-                       'continue' => [
-                               ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
-                       ],
-                       'user' => [
-                               ApiBase::PARAM_TYPE => 'user',
-                               ApiBase::PARAM_ISMULTI => true
-                       ],
-                       'userids' => [
-                               ApiBase::PARAM_TYPE => 'integer',
-                               ApiBase::PARAM_ISMULTI => true
-                       ],
-                       'userprefix' => null,
-                       'dir' => [
-                               ApiBase::PARAM_DFLT => 'older',
-                               ApiBase::PARAM_TYPE => [
-                                       'newer',
-                                       'older'
-                               ],
-                               ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
-                       ],
-                       'namespace' => [
-                               ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_TYPE => 'namespace'
-                       ],
-                       'prop' => [
-                               ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_DFLT => 'ids|title|timestamp|comment|size|flags',
-                               ApiBase::PARAM_TYPE => [
-                                       'ids',
-                                       'title',
-                                       'timestamp',
-                                       'comment',
-                                       'parsedcomment',
-                                       'size',
-                                       'sizediff',
-                                       'flags',
-                                       'patrolled',
-                                       'tags'
-                               ],
-                               ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
-                       ],
-                       'show' => [
-                               ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_TYPE => [
-                                       'minor',
-                                       '!minor',
-                                       'patrolled',
-                                       '!patrolled',
-                                       'autopatrolled',
-                                       '!autopatrolled',
-                                       'top',
-                                       '!top',
-                                       'new',
-                                       '!new',
-                               ],
-                               ApiBase::PARAM_HELP_MSG => [
-                                       'apihelp-query+usercontribs-param-show',
-                                       $this->getConfig()->get( 'RCMaxAge' )
-                               ],
-                       ],
-                       'tag' => null,
-                       'toponly' => [
-                               ApiBase::PARAM_DFLT => false,
-                               ApiBase::PARAM_DEPRECATED => true,
-                       ],
-               ];
-       }
-
-       protected function getExamplesMessages() {
-               return [
-                       'action=query&list=usercontribs&ucuser=Example'
-                               => 'apihelp-query+usercontribs-example-user',
-                       'action=query&list=usercontribs&ucuserprefix=192.0.2.'
-                               => 'apihelp-query+usercontribs-example-ipprefix',
-               ];
-       }
-
-       public function getHelpUrls() {
-               return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Usercontribs';
-       }
-}
diff --git a/includes/api/ApiRawMessage.php b/includes/api/ApiRawMessage.php
new file mode 100644 (file)
index 0000000..ed3537a
--- /dev/null
@@ -0,0 +1,52 @@
+<?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
+ */
+
+/**
+ * Extension of RawMessage implementing IApiMessage
+ * @since 1.25
+ * @ingroup API
+ */
+class ApiRawMessage extends RawMessage implements IApiMessage {
+       use ApiMessageTrait;
+
+       /**
+        * @param RawMessage|string|array $msg
+        *  - RawMessage: is cloned
+        *  - array: first element is $key, rest are $params to RawMessage::__construct
+        *  - string: passed to RawMessage::__construct
+        * @param string|null $code
+        * @param array|null $data
+        */
+       public function __construct( $msg, $code = null, array $data = null ) {
+               if ( $msg instanceof RawMessage ) {
+                       foreach ( get_class_vars( get_class( $this ) ) as $key => $value ) {
+                               if ( isset( $msg->$key ) ) {
+                                       $this->$key = $msg->$key;
+                               }
+                       }
+               } elseif ( is_array( $msg ) ) {
+                       $key = array_shift( $msg );
+                       parent::__construct( $key, $msg );
+               } else {
+                       parent::__construct( $msg );
+               }
+               $this->setApiCode( $code, $data );
+       }
+}
index c200dcb..7f8a26b 100644 (file)
  * @file
  */
 
-/**
- * This exception will be thrown when dieUsage is called to stop module execution.
- *
- * @ingroup API
- * @deprecated since 1.29, use ApiUsageException instead
- */
-class UsageException extends MWException {
-
-       private $mCodestr;
-
-       /**
-        * @var null|array
-        */
-       private $mExtraData;
-
-       /**
-        * @param string $message
-        * @param string $codestr
-        * @param int $code
-        * @param array|null $extradata
-        */
-       public function __construct( $message, $codestr, $code = 0, $extradata = null ) {
-               parent::__construct( $message, $code );
-               $this->mCodestr = $codestr;
-               $this->mExtraData = $extradata;
-
-               if ( !$this instanceof ApiUsageException ) {
-                       wfDeprecated( __METHOD__, '1.29' );
-               }
-
-               // This should never happen, so throw an exception about it that will
-               // hopefully get logged with a backtrace (T138585)
-               if ( !is_string( $codestr ) || $codestr === '' ) {
-                       throw new InvalidArgumentException( 'Invalid $codestr, was ' .
-                               ( $codestr === '' ? 'empty string' : gettype( $codestr ) )
-                       );
-               }
-       }
-
-       /**
-        * @return string
-        */
-       public function getCodeString() {
-               wfDeprecated( __METHOD__, '1.29' );
-               return $this->mCodestr;
-       }
-
-       /**
-        * @return array
-        */
-       public function getMessageArray() {
-               wfDeprecated( __METHOD__, '1.29' );
-               $result = [
-                       'code' => $this->mCodestr,
-                       'info' => $this->getMessage()
-               ];
-               if ( is_array( $this->mExtraData ) ) {
-                       $result = array_merge( $result, $this->mExtraData );
-               }
-
-               return $result;
-       }
-
-       /**
-        * @return string
-        */
-       public function __toString() {
-               return "{$this->getCodeString()}: {$this->getMessage()}";
-       }
-}
-
 /**
  * Exception used to abort API execution with an error
  *
diff --git a/includes/api/IApiMessage.php b/includes/api/IApiMessage.php
new file mode 100644 (file)
index 0000000..fee62c5
--- /dev/null
@@ -0,0 +1,69 @@
+<?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
+ */
+
+/**
+ * Interface for messages with machine-readable data for use by the API
+ *
+ * The idea is that it's a Message that has some extra data for the API to use when interpreting it
+ * as an error (or, in the future, as a warning). Internals of MediaWiki often use messages (or
+ * message keys, or Status objects containing messages) to pass information about errors to the user
+ * (see e.g. Title::getUserPermissionsErrors()) and the API has to make do with that.
+ *
+ * @since 1.25
+ * @note This interface exists to work around PHP's inheritance, so ApiMessage
+ *  can extend Message and ApiRawMessage can extend RawMessage while still
+ *  allowing an instanceof check for a Message object including this
+ *  functionality. If for some reason you feel the need to implement this
+ *  interface on some other class, that class must also implement all the
+ *  public methods the Message class provides (not just those from
+ *  MessageSpecifier, which as written is fairly useless).
+ * @ingroup API
+ */
+interface IApiMessage extends MessageSpecifier {
+       /**
+        * Returns a machine-readable code for use by the API
+        *
+        * If no code was specifically set, the message key is used as the code
+        * after removing "apiwarn-" or "apierror-" prefixes and applying
+        * backwards-compatibility mappings.
+        *
+        * @return string
+        */
+       public function getApiCode();
+
+       /**
+        * Returns additional machine-readable data about the error condition
+        * @return array
+        */
+       public function getApiData();
+
+       /**
+        * Sets the machine-readable code for use by the API
+        * @param string|null $code If null, uses the default (see self::getApiCode())
+        * @param array|null $data If non-null, passed to self::setApiData()
+        */
+       public function setApiCode( $code, array $data = null );
+
+       /**
+        * Sets additional machine-readable data about the error condition
+        * @param array $data
+        */
+       public function setApiData( array $data );
+}
diff --git a/includes/api/UsageException.php b/includes/api/UsageException.php
new file mode 100644 (file)
index 0000000..426ce91
--- /dev/null
@@ -0,0 +1,90 @@
+<?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
+ */
+
+/**
+ * This exception will be thrown when dieUsage is called to stop module execution.
+ *
+ * @ingroup API
+ * @deprecated since 1.29, use ApiUsageException instead
+ */
+class UsageException extends MWException {
+
+       private $mCodestr;
+
+       /**
+        * @var null|array
+        */
+       private $mExtraData;
+
+       /**
+        * @param string $message
+        * @param string $codestr
+        * @param int $code
+        * @param array|null $extradata
+        */
+       public function __construct( $message, $codestr, $code = 0, $extradata = null ) {
+               parent::__construct( $message, $code );
+               $this->mCodestr = $codestr;
+               $this->mExtraData = $extradata;
+
+               if ( !$this instanceof ApiUsageException ) {
+                       wfDeprecated( __METHOD__, '1.29' );
+               }
+
+               // This should never happen, so throw an exception about it that will
+               // hopefully get logged with a backtrace (T138585)
+               if ( !is_string( $codestr ) || $codestr === '' ) {
+                       throw new InvalidArgumentException( 'Invalid $codestr, was ' .
+                               ( $codestr === '' ? 'empty string' : gettype( $codestr ) )
+                       );
+               }
+       }
+
+       /**
+        * @return string
+        */
+       public function getCodeString() {
+               wfDeprecated( __METHOD__, '1.29' );
+               return $this->mCodestr;
+       }
+
+       /**
+        * @return array
+        */
+       public function getMessageArray() {
+               wfDeprecated( __METHOD__, '1.29' );
+               $result = [
+                       'code' => $this->mCodestr,
+                       'info' => $this->getMessage()
+               ];
+               if ( is_array( $this->mExtraData ) ) {
+                       $result = array_merge( $result, $this->mExtraData );
+               }
+
+               return $result;
+       }
+
+       /**
+        * @return string
+        */
+       public function __toString() {
+               return "{$this->getCodeString()}: {$this->getMessage()}";
+       }
+}
index f07c6e2..dece40e 100644 (file)
        "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Documentation]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailing list]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API Announcements]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bugs & requests]\n</div>\n<strong>Status:</strong> يجب أن تعمل جميع الميزات المعروضة في هذه الصفحة، إلا أن واجهة برمجة التطبيقات لا تزال قيد التطوير النشط، وقد تتغير في أي وقت. الاشتراك في\n<strong>Erroneous requests:</strong>عند إرسال طلبات خاطئة إلى api, فالـHTTP سيتم إرسال رأس مع المفتاح \"MediaWiki-API-Error\" ومن ثم سيتم تعيين قيمة رأس ورمز الخطأ المرسل مرة أخرى إلى نفس القيمة. لمزيد من المعلومات، راجع  [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Errors and warnings]].\n<p class=\"mw-apisandbox-link\"><strong>Testing:</strong> لسهولة إختبار طلبات API، انظر [[Special:ApiSandbox]].</p>",
        "apihelp-main-param-action": "أي فعل للعمل.",
        "apihelp-main-param-format": "صيغة الخرج.",
+       "apihelp-main-param-maxlag": "يمكن استخدام التأخر الأقصى عند تثبيت ميدياويكي على قاعدة بيانات مكررة، لحفظ الإجراءات التي تتسبب في أي تأخير أكثر في النسخ المتماثل للموقع; يمكن أن يجعل هذا الوسيط العميل ينتظر حتى يكون تأخر النسخ المتماثل أقل من القيمة المحددة، في حالة التأخير المفرط، يتم إرجاع رمز الخطأ <samp>maxlag</samp> برسالة مثل <samp>Waiting for $host: $lag seconds lagged</samp>،<br />انظر [[mw:Special:MyLanguage/Manual:Maxlag_parameter|دليل: الوسيط maxlag]] لمزيد من المعلومات.",
+       "apihelp-main-param-smaxage": "تعيين رأس التحكم في ذاكرة التخزين المؤقت HTTP <code>s-maxage</code> إلى هذه الثواني العديدة، لا يتم تخزين الأخطاء مؤقتا أبدا.",
+       "apihelp-main-param-maxage": "تعيين رأس التحكم في ذاكرة التخزين المؤقت HTTP <code>max-age</code> إلى هذه الثواني العديدة، لا يتم تخزين الأخطاء مؤقتا أبدا.",
+       "apihelp-main-param-assert": "تحقق من تسجيل دخول المستخدم إذا كان مضبوطا على <kbd>user</kbd>، أو إذا كان لديه صلاحية البوت إذا <kbd>bot</kbd>.",
        "apihelp-main-param-assertuser": "التحقق من أن المستخدم الحالي هو المستخدم المسمى.",
        "apihelp-main-param-requestid": "سيتم إدراج أي قيمة معينة هنا في الاستجابة. يمكن أن تُستخدَم لتمييز الطلبات.",
        "apihelp-main-param-servedby": "تتضمن اسم المضيف الذي الخدم طلب في النتائج.",
        "apihelp-main-param-curtimestamp": "تشمل الطابع الزمني الحالي في النتيجة.",
        "apihelp-main-param-responselanginfo": "تشمل اللغات المستخدمة لأجل <var>uselang</var> and <var>errorlang</var> في النتيجة.",
+       "apihelp-main-param-origin": "عند الوصول إلى API باستخدام طلب AJAX عبر النطاقات (CORS)، اضبطها على النطاق الأصلي، يجب تضمين هذا في أي طلب ما قبل الطيران، وبالتالي يجب أن يكون جزءا من طلب URI (وليس جسم POST). \n\nبالنسبة للطلبات المصادقة، يجب أن يتطابق هذا مع أحد المصادر الموجودة في الرأس<code>Origin</code> بالضبط; لذا يجب تعيينه على شيء مثل<kbd>https://en.wikipedia.org</kbd> أو <kbd>https://meta.wikimedia.org</kbd>، إذا لم يتطابق هذا الوسيط مع الرأس<code>Origin</code>، فسيتم إرجاع استجابة 403، إذا كان هذا الوسيط مطابقا للرأس <code>Origin</code>، ستتم إضافة الأصل إلى القائمة البيضاء، سيتم تعيين الرؤوس <code>Access-Control-Allow-Origin</code> و<code>Access-Control-Allow-Credentials</code>.\n\nبالنسبة للطلبات غير المصادقة، حدد القيمة <kbd>*</kbd>، سيؤدي ذلك إلى تعيين الرأس <code>Access-Control-Allow-Origin</code>، ولكن <code>Access-Control-Allow-Credentials</code> سيكون <code>false</code> وسيتم تقييد كل البيانات الخاصة بالمستخدم.",
+       "apihelp-main-param-uselang": "اللغة المستخدمة لترجمة الرسائل. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> بـ<kbd>siprop=languages</kbd> يقوم بإرجاع قائمة أكواد اللغة، أو تحديد <kbd>user</kbd> لاستخدام تفضيل اللغة للمستخدم الحالي، أو تحديد <kbd>content</kbd> لاستخدام لغة محتوى الويكي هذا.",
+       "apihelp-main-param-errorformat": "تنسيق لاستخدامه في التحذير وإخراج نص الخطأ. \n; نص عادي: إزالة نص الويكي ذي وسوم HTML واستبدال الكيانات.\n; نص الويكي: نص ويكي غير مقتبس.\n; html: HTML.\n; خام: مفتاح ووسائط الرسالة.\n; لا شيء: لا يوجد إخراج نص، فقط رموز الخطأ.\n; bc: التنسيق المستخدم قبل ميدياويكي 1.29، يتم تجاهل <var>errorlang</var> و<var>errorsuselocal</var>.",
+       "apihelp-main-param-errorlang": "لغة لاستخدامها في التحذيرات والأخطاء. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> بـ<kbd>siprop=languages</kbd> يقوم بإرجاع قائمة أكواد اللغة، أو تحديد <kbd>content</kbd> لاستخدام لغة محتوى الويكي هذا، أو تحديد <kbd>uselang</kbd> لاستخدام نفس القيمة كوسيط <var>uselang</var>.",
        "apihelp-main-param-errorsuselocal": "إذا ما أعطيت، النصوص الخطأ ستستخدم الرسائل المخصصة محليا من نطاق {{ns:MediaWiki}}.",
        "apihelp-block-summary": "منع مستخدم.",
        "apihelp-block-param-user": "اسم المستخدم، أو عنوان IP أو نطاق عنوان IP لمنعه. لا يمكن أن يُستخدَم جنبا إلى جنب مع <var>$1userid</var>",
        "apihelp-block-param-userid": "معرف المستخدم لمنعه، لا يمكن أن يُستخدَم جنبا إلى جنب مع <var>$1user</var>",
+       "apihelp-block-param-expiry": "وقت انتهاء الصلاحية، قد يكون نسبيا (على سبيل المثال <kbd>5 months</kbd> أو <kbd>2 weeks</kbd>) أو مطلق (على سبيل المثال <kbd>2014-09-18T12:34:56Z</kbd>)، إذا تم التعيين على <kbd>infinite</kbd> أو <kbd>indefinite</kbd> أو <kbd>never</kbd> فلن تنتهي صلاحية المنع مطلقا.",
        "apihelp-block-param-reason": "السبب للمنع.",
        "apihelp-block-param-anononly": "منع المستخدمين المجهولين فقط (أي تعطيل تعديلات المجهولين من  عنوان IP هذا).",
        "apihelp-block-param-nocreate": "امنع إنشاء الحسابات.",
        "apihelp-compare-param-fromtitle": "العنوان الأول للمقارنة.",
        "apihelp-compare-param-fromid": "رقم الصفحة الأول للمقارنة.",
        "apihelp-compare-param-fromrev": "أول مراجعة للمقارنة.",
+       "apihelp-compare-param-fromtext": "استخدم هذا النص بدلا من محتوى المراجعة المحدد بواسطة <var>fromtitle</var>، <var>fromid</var> أو <var>fromrev</var>.",
+       "apihelp-compare-param-fromsection": "استخدم فقط القسم المحدد في المحتوى 'من' المحدد.",
+       "apihelp-compare-param-frompst": "قم بإجراء تحويل ما قبل الحفظ على <var>fromtext</var>.",
+       "apihelp-compare-param-fromcontentmodel": "نموذج محتوى <var>fromtext</var>، إذا لم يتم توفيره، فسيتم تخمينه استنادا إلى الوسائط الأخرى.",
+       "apihelp-compare-param-fromcontentformat": "تنسيق محتوى تسلسل <var>fromtext</var>.",
        "apihelp-compare-param-totitle": "العنوان الثاني للمقارنة.",
        "apihelp-compare-param-toid": "رقم الصفحة الثاني للمقارنة.",
        "apihelp-compare-param-torev": "المراجعة الثانية للمقارنة.",
+       "apihelp-compare-param-torelative": "استخدم مراجعة متعلقة بالمراجعة المحددة من <var>fromtitle</var> أو <var>fromid</var> أو <var>fromrev</var>، سيتم تجاهل جميع خيارات 'إلى' الأخرى.",
+       "apihelp-compare-param-totext": "استخدم هذا النص بدلا من محتوى المراجعة المحدد بواسطة <var>totitle</var> أو <var>toid</var> أو <var>torev</var>.",
+       "apihelp-compare-param-tosection": "استخدم فقط القسم المحدد في المحتوى 'إلى' المحدد.",
+       "apihelp-compare-param-topst": "قم بإجراء تحويل ما قبل الحفظ على <var>totext</var>.",
+       "apihelp-compare-param-tocontentmodel": "نموذج محتوى <var>totext</var>، إذا لم يتم توفيره، فسيتم تخمينه استنادا إلى الوسائط الأخرى.",
+       "apihelp-compare-param-tocontentformat": "تنسيق محتوى تسلسل <var>totext</var>.",
+       "apihelp-compare-param-prop": "أية قطعة من المعلومات للحصول عليها.",
+       "apihelp-compare-paramvalue-prop-diff": "HTML الفرق.",
+       "apihelp-compare-paramvalue-prop-diffsize": "حجم HTML الفرق، بالبايت.",
+       "apihelp-compare-paramvalue-prop-rel": "معرفات المراجعة السابقة للمراجعة السابقة من 'من' وبعد 'إلى'، إن وُجِدت.",
+       "apihelp-compare-paramvalue-prop-ids": "معرفات الصفحة والمراجعة للمراجعات 'من' و'إلى'.",
+       "apihelp-compare-paramvalue-prop-title": "عناوين صفحات المراجعات 'من' و'إلى'.",
+       "apihelp-compare-paramvalue-prop-user": "المعرف واسم المستخدم للمراجعات 'من' و'إلى'.",
+       "apihelp-compare-paramvalue-prop-comment": "التعليق على المراجعات 'من' و'إلى'.",
+       "apihelp-compare-paramvalue-prop-parsedcomment": "التعليق المحلل على المراجعات 'من' و'إلى'.",
+       "apihelp-compare-paramvalue-prop-size": "حجم المراجعات 'من' و'إلى'.",
        "apihelp-compare-example-1": "إنشاء فرق بين المراجعة 1 و2.",
        "apihelp-createaccount-summary": "انشاء حساب مستخدم جديد",
+       "apihelp-createaccount-param-preservestate": "إذا تم عرض <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> بشكل صحيح لـ<samp>hasprimarypreservedstate</samp>، فقد تم تعليم طلبات <samp>primary-required</samp> لكي يجب حذفها، إذا عرضت قيمة غير فارغة لـ<samp>preservedusername</samp> فيجب استخدام اسم المستخدم هذا للوسيط <var>username</var>.",
        "apihelp-createaccount-example-create": "بدء عملية إنشاء المستخدم <kbd>Example</kbd> بكلمة المرور <kbd>ExamplePassword</kbd>.",
        "apihelp-createaccount-param-name": "اسم المستخدم.",
+       "apihelp-createaccount-param-password": "كلمة المرور (يتم تجاهلها إذا تم تعيين <var>$1mailpassword</var>).",
        "apihelp-createaccount-param-domain": "مجال للمصادقة الخارجية (اختياري).",
        "apihelp-createaccount-param-token": "حصلت على رمز إنشاء حساب في الطلب الأول.",
        "apihelp-createaccount-param-email": "عنوان البريد الإلكتروني للمستخدم (اختياري).",
        "apihelp-createaccount-example-mail": "إنشاء مستخدم <kbd>testmailuser</kbd> وأرسل كلمة المرور بالبريد الإلكتروني بشكل عشوائي.",
        "apihelp-cspreport-summary": "مستخدمة من قبل المتصفحات للإبلاغ عن انتهاكات سياسة أمن المحتوى. لا ينبغي أبدا أن تستخدم هذه الوحدة، إلا عند استخدامها تلقائيا باستخدام متصفح ويب CSP متوافق.",
        "apihelp-cspreport-param-reportonly": "علم على أنه تقرير عن سياسة الرصد، وليس فرض سياسة",
+       "apihelp-cspreport-param-source": "ماذا أنشأ رأس CSP الذي تسبب في هذا التقرير",
        "apihelp-delete-summary": "حذف صفحة.",
        "apihelp-delete-param-title": "عنوان الصفحة للحذف. لا يمكن أن يُستخدَم جنبا إلى جنب مع <var>$1pageid</var",
        "apihelp-delete-param-pageid": "معرف الصفحة للحذف. لا يمكن أن يُستخدَم جنبا إلى جنب مع <var>$1pageid</var",
        "apihelp-delete-param-reason": "سبب الحذف. إذا لم يُحدَّد، سوف تُستخدَم أحد الأسباب التي تنشأ تلقائيا.",
        "apihelp-delete-param-tags": "تغيير وسوم لتطبيق الإدخال في سجل الحذف.",
        "apihelp-delete-param-watch": "أضف الصفحة إلى لائحة مراقبة المستعمل الحالي",
+       "apihelp-delete-param-watchlist": "إضافة أو إزالة الصفحة من قائمة مراقبة المستخدم الحالي أو استخدام التفضيلات أو عدم تغيير المراقبة بدون شروط.",
        "apihelp-delete-param-unwatch": "إزالة الصفحة من قائمة المراقبة للمستخدم الحالي.",
        "apihelp-delete-param-oldimage": "اسم الصورة القديمة لحذفها كما هو منصوص عليه [[Special:ApiHelp/query+imageinfo|action=query&prop=imageinfo&iiprop=archivename]].",
        "apihelp-delete-example-simple": "حذف <kbd>Main Page</kbd>.",
        "apihelp-edit-param-nocreate": "يحدث خطأ إذا كانت الصفحة غير موجودة.",
        "apihelp-edit-param-watch": "أضف الصفحة إلى لائحة مراقبة المستعمل الحالي",
        "apihelp-edit-param-unwatch": "إزالة الصفحة من قائمة المراقبة للمستخدم الحالي.",
+       "apihelp-edit-param-watchlist": "إضافة أو إزالة الصفحة من قائمة مراقبة المستخدم الحالي أو استخدام التفضيلات أو عدم تغيير المراقبة بدون شروط.",
+       "apihelp-edit-param-md5": "رمز الرقم MD5 للوسيط $1text، أو الوسائط $1prependtext و$1appendtext متسلسلة، في حالة التعيين، لن يتم التعديل ما لم يكن رمز الرقم صحيحا.",
        "apihelp-edit-param-prependtext": "إضافة هذا النص إلى بداية الصفحة. تجاوز $1text.",
        "apihelp-edit-param-appendtext": "إضافة هذا النص إلى بداية الصفحة. تجاوز $1text.\n\nاستخدم $1section=جديد لحاق القسم الجديد، بدلا من هذا الوسيط.",
        "apihelp-edit-param-undo": "التراجع عن هذه المراجعة. تجاوز $1text, $1prependtext و$1appendtext.",
        "apihelp-edit-param-undoafter": "التراجع عن جميع المراجعات من $1undo لهذه. إذا لم يتم التغيير، تراجع عن تعديل واحد فقط.",
        "apihelp-edit-param-redirect": "حل التحويلات تلقائيا.",
+       "apihelp-edit-param-contentformat": "نسق المحتوى التسلسلي المستخدم لنص المدخلات.",
        "apihelp-edit-param-contentmodel": "نموذج المحتوى للمحتوى الجديد.",
        "apihelp-edit-param-token": "ينبغي دائما أن يُرسَل الرمز كوسيط أخير، أو على الأقل بعد الوسيط $1text.",
        "apihelp-edit-example-edit": "عدل صفحة.",
        "apihelp-expandtemplates-param-title": "عنوان الصفحة.",
        "apihelp-expandtemplates-param-text": "نص ويكي للتحويل.",
        "apihelp-expandtemplates-param-revid": "معرف المراجعة، ل<code><nowiki>{{REVISIONID}}</nowiki></code> والمتغيرات مماثلة.",
+       "apihelp-expandtemplates-param-prop": "أية قطعة من المعلومات للحصول عليها،\n\nلاحظ أنه في حالة عدم تحديد أية قيم، فإن النتيجة ستحتوي على نص ويكي، ولكن سيكون الإخراج بتنسيق موقوف.",
        "apihelp-expandtemplates-paramvalue-prop-wikitext": "نص الويكي الموسع",
+       "apihelp-expandtemplates-paramvalue-prop-categories": "أية تصنيفات موجودة في المدخلات غير ممثلة في مخرجات نص الويكي.",
        "apihelp-expandtemplates-paramvalue-prop-properties": "خصائص الصفحة التي تحددها الكلمات السحرية الموسعة في نص الويكي.",
        "apihelp-expandtemplates-paramvalue-prop-volatile": "إذا كان الإخراج سريع التأثر، ينبغي عدم استخدامه في أي مكان آخر داخل الصفحة.",
+       "apihelp-expandtemplates-paramvalue-prop-ttl": "الحد الأقصى للوقت الذي يجب بعده إبطال ذاكرة التخزين المؤقت للنتيجة.",
        "apihelp-expandtemplates-paramvalue-prop-jsconfigvars": "يعطي متغيرات تكوين جافا سكريبت الخاصة بهذه الصفحة.",
        "apihelp-expandtemplates-paramvalue-prop-encodedjsconfigvars": "يعطي متغيرات تكوين جافا سكريبت الخاصة بهذه الصفحة كسلسلة JSON.",
        "apihelp-expandtemplates-paramvalue-prop-parsetree": "شجرة تحليل XML للمدخلات.",
        "apihelp-feedcontributions-param-newonly": "أظهر إنشاء الصفحات فقط",
        "apihelp-feedcontributions-param-hideminor": "إخفاء التعديلات الطفيفة.",
        "apihelp-feedcontributions-param-showsizediff": "عرض حجم الفرق بين النسخ.",
+       "apihelp-feedcontributions-example-simple": "عودة المساهمات للمستخدم <kbd>Example</kbd>.",
+       "apihelp-feedrecentchanges-summary": "عرض خلاصة أحدث التغييرات.",
        "apihelp-feedrecentchanges-param-feedformat": "هيئة التلقيم.",
        "apihelp-feedrecentchanges-param-namespace": "نطاق لتقييد النتائج.",
        "apihelp-feedrecentchanges-param-invert": "جميع النطاقات عدا المختار.",
        "apihelp-feedwatchlist-summary": "إرجاع تغذية قائمة المراقبة.",
        "apihelp-feedwatchlist-param-feedformat": "هيئة التلقيم.",
        "apihelp-feedwatchlist-param-hours": "صفحات قائمة معدلة ضمن عدة ساعات من الآن.",
+       "apihelp-feedwatchlist-param-linktosections": "الربط مباشرةً بالأقسام التي تم تغييرها إن أمكن.",
        "apihelp-feedwatchlist-example-default": "عرض تغذية قائمة المراقبة.",
        "apihelp-feedwatchlist-example-all6hrs": "اظهر كل التغييرات في اخر 6 ساعات",
        "apihelp-filerevert-summary": "استرجع الملف لنسخة قديمة.",
        "apihelp-filerevert-param-filename": "اسم الملف المستهدف، دون البادئة ملف:.",
        "apihelp-filerevert-param-comment": "تعليق الرفع.",
+       "apihelp-filerevert-param-archivename": "اسم أرشيف المراجعة للعودة إليه.",
        "apihelp-filerevert-example-revert": "استرجاع <kbd>Wiki.png</kbd> لنسحة <kbd>2011-03-05T15:27:40Z</kbd>.",
        "apihelp-help-summary": "عرض مساعدة لوحدات محددة.",
        "apihelp-help-param-modules": "وحدات لعرض مساعدة لها (قيم وسائط <var>action</var> و<var>format</var> أو<kbd>main</kbd>). يمكن تحديد الوحدات الفرعية ب <kbd>+</kbd>.",
        "apihelp-help-example-query": "مساعدة لوحدتي استعلام فرعيتين.",
        "apihelp-imagerotate-summary": "تدوير صورة واحدة أو أكثر.",
        "apihelp-imagerotate-param-rotation": "درجة تدوير الصورة في اتجاه عقارب الساعة.",
+       "apihelp-imagerotate-param-tags": "تنطبق الوسوم على الإدخال في سجل الرفع.",
        "apihelp-imagerotate-example-simple": "تدوير <kbd>File:Example.png</kbd> بمقدار <kbd>90</kbd> درجة.",
        "apihelp-imagerotate-example-generator": "تدوير جميع الصور في <kbd>Category:Flip</kbd> بمقدار <kbd>180</kbd> درجة.",
+       "apihelp-import-summary": "استيراد صفحة من موقع ويكي آخر أو من ملف XML.",
+       "apihelp-import-extended-description": "لاحظ أنه يجب أن يتم إجراء POST HTTP كرفع ملف (أي باستخدام بيانات متعددة الأجزاء/النماذج) عند إرسال ملف للوسيط <var>xml</var>.",
        "apihelp-import-param-summary": "ملخص إدخال سجل الاستيراد.",
        "apihelp-import-param-xml": "ملف XML مرفوع.",
+       "apihelp-import-param-interwikiprefix": "بالنسبة للواردات المرفوعة: بادئة إنترويكي لتطبيقها على أسماء مستخدمين غير معروفة (والمستخدمين المعروفين إذا تم تعيين <var>$1assignknownusers</var>).",
+       "apihelp-import-param-assignknownusers": "تعيين تعديلات للمستخدمين المحليين حيث يوجد المستخدم المحدد محليا.",
        "apihelp-import-param-interwikisource": "بالنسبة لواردات الإنترويكي: ويكي للاستيراد منه.",
        "apihelp-import-param-interwikipage": "بالنسبة لواردات الإنترويكي: صفحة لاستيرادها.",
        "apihelp-import-param-fullhistory": "بالنسبة لواردات الإنترويكي: استيراد التاريخ كاملا، وليست النسخة الحالية فقط.",
        "apihelp-import-param-templates": "بالنسبة لواردات الإنترويكي: الإستيراد شمل كافة القوالب كذلك.",
        "apihelp-import-param-namespace": "استيراد إلى هذا النطاق. لا يمكن أن يُستخدَم إلى جانب <var>$1rootpage</var>.",
        "apihelp-import-param-rootpage": "استيراد كصفحة فرعية لهذه الصفحة. لا يمكن أن يُستخدَم إلى جانب <var>$1rootpage</var>.",
+       "apihelp-import-param-tags": "تغيير الوسوم لتطبيقها على الإدخال في سجل الاستيراد وعلى المراجعة الخالية في الصفحات المستوردة.",
        "apihelp-import-example-import": "استيراد [[meta:Help:ParserFunctions]] للنطاق 100 بالتاريخ الكامل.",
        "apihelp-linkaccount-summary": "ربط حساب من موفر طرف ثالث للمستخدم الحالي.",
        "apihelp-linkaccount-example-link": "بدء عملية ربط حساب من <kbd>Example</kbd>.",
        "apihelp-logout-example-logout": "تسجيل خروج المستخدم الحالي.",
        "apihelp-managetags-summary": "أداء المهام الإدارية المتعلقة بتغيير الوسوم.",
        "apihelp-managetags-param-operation": "أي الإجراءات ستنفذ:\n؛ إنشاء: إنشاء وسم التغيير جديدة للاستخدام اليدوي.\n؛ حذف: إزالة وسم التغيير من قاعدة البيانات، بما في ذلك إزالة الوسم من كافة المراجعات، وإدخالات التغيير الأخيرة، وإدخالات السجل المستخدم.\n؛ تنشيط: تنشيط وسم التغيير، مما يسمح للمستخدمين بتطبيقه يدويا.\n; إلغاء: إلغاء تنشيط وسم التغيير، ومنع المستخدمين من تطبيقه يدويا.",
+       "apihelp-managetags-param-tag": "وسم لإنشاء أو حذف أو تنشيط أو إلغاء تنشيط. لإنشاء وسم; يجب ألا يكون الوسم موجودا، لحذف وسم; يجب أن يكون الوسم موجودا، لتنشيط وسم; يجب أن يكون الوسم موجودا وغير مستخدم بواسطة إضافة، لإلغاء تنشيط وسم; يجب أن يكون الوسم نشطا في الوقت الحالي ويتم تحديدها يدويا.",
        "apihelp-managetags-param-reason": "سبب اختياري لإنشاء، وحذف، وتفعيل أو تعطيل الوسم.",
        "apihelp-managetags-param-ignorewarnings": "إذا كان سيتم تجاهل أي تحذيرات تصدر خلال العملية.",
+       "apihelp-managetags-param-tags": "تغيير الوسوم لتطبيق الإدخال في سجل الحذف إدارة الوسوم.",
        "apihelp-managetags-example-create": "إنشاء وسم مسمى <kbd>spam</kbd> بسبب <kbd>For use in edit patrolling</kbd>",
        "apihelp-managetags-example-delete": "حذف <kbd>vandlaism</kbd> وسم بسبب <kbd>Misspelt</kbd>",
        "apihelp-managetags-example-activate": "تنشيط الوسم المسمى <kbd>spam</kbd> بسبب <kbd>For use in edit patrolling</kbd>",
        "apihelp-move-param-noredirect": "لا تنشئ تحويلة.",
        "apihelp-move-param-watch": "إضافة الصفحة والتحويلة إلى قائمة مراقبة المستخدم الحالي.",
        "apihelp-move-param-unwatch": "إزالة الصفحة والتحويلة إلى قائمة مراقبة المستخدم الحالي.",
+       "apihelp-move-param-watchlist": "إضافة أو إزالة الصفحة من قائمة مراقبة المستخدم الحالي أو استخدام التفضيلات أو عدم تغيير المراقبة دون قيد أو شرط.",
        "apihelp-move-param-ignorewarnings": "تجاهل أي تحذيرات.",
+       "apihelp-move-param-tags": "غير الوسوم لتطبيقها على الإدخال في سجل النقل وعلى النسخة الفارغة في الصفحة الوجهة.",
        "apihelp-move-example-move": "انقل <kbd>Badtitle</kbd> إلى <kbd>Goodtitle</kbd> دون ترك تحويلة.",
        "apihelp-opensearch-summary": "بحث الويكي باستخدام بروتوكول أوبن سيرش OpenSearch.",
        "apihelp-opensearch-param-search": "سطر البحث",
        "apihelp-opensearch-param-limit": "الحد الأقصى للنتائج المُرجعة",
-       "apihelp-opensearch-param-namespace": "النطاقات للبحث.",
+       "apihelp-opensearch-param-namespace": "النطاقات للبحث، يتم التجاهل إذا بدأ <var>$1search</var> ببادئة نطاق صالحة.",
        "apihelp-opensearch-param-suggest": "لا تفعل شيئا إذا كان <var>[[mw:Special:MyLanguage/Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> خاطئا.",
+       "apihelp-opensearch-param-redirects": "كيفية التعامل مع التحويلات:\n;إرجاع: إرجاع التحويلة نفسها.\n;حل: إرجاع الصفحة الهدف، قد ترجع نتائج أقل من $1limit.\nلأسباب تاريخية; يكون الإعداد الافتراضي هو \"إرجاع\" لـ$1format=json و\"حل\" للتنسيقات الأخرى.",
        "apihelp-opensearch-param-format": "شكل الإخراج.",
        "apihelp-opensearch-param-warningsaserror": "إذا تم رفع التحذيرات ب<kbd>format=json</kbd>, أعد أخطاء API بدلا من تجاهلها.",
        "apihelp-opensearch-example-te": "العثور على صفحات تبدأ ب<kbd>Te</kbd>.",
+       "apihelp-options-summary": "تغيير تفضيلات المستخدم الحالي.",
+       "apihelp-options-extended-description": "لا يمكن تعيين سوى الخيارات المسجلة في النواة أو في أحد الملحقات المثبتة، أو الخيارات مع المفاتيح المسبوقة بـ<code>userjs-</code> (التي يُراد استخدامها من قبل سكريبتات المستخدم).",
        "apihelp-options-param-reset": "إعادة تعيين التفضيلات إلى إعدادات الموقع الإفتراضية.",
        "apihelp-options-param-resetkinds": "قائمة أنواع الخيارات لإعادة ضبطها عندما يتم تعيين خيار <var>$1reset</var>.",
+       "apihelp-options-param-change": "قائمة بالتغييرات، الاسم المنسق=value (مثل skin=vector)، إذا لم يتم تحديد أية قيمة (ولا حتى علامة المساواة)، على سبيل المثال، optionname|otheroption|..., ستتم إعادة تعيين الخيار إلى قيمته الافتراضية، إذا كانت أية قيمة تم تمريرها تحتوي على حرف الأنبوب(<kbd>|</kbd>)، فاستخدم [[Special:ApiHelp/main#main/datatypes| فاصل بديل متعدد القيم]] للعملية الصحيحة.",
        "apihelp-options-param-optionname": "اسم الخيار الذي ينبغي ضبطه إلى القيمة التي قدمها <var>$1optionvalue</var>.",
        "apihelp-options-param-optionvalue": "قيمة للخيار المحدد من قبل <var>$1optionname</var>.",
        "apihelp-options-example-reset": "إعادة تعيين كل التفضيلات.",
        "apihelp-options-example-change": "غير تفضيلات <kbd>skin</kbd> و<kbd>hideminor</kbd>.",
        "apihelp-options-example-complex": "إعادة تعيين جميع تفضيلات، ثم تعيين <kbd>skin</kbd> و<kbd>nickname</kbd>.",
        "apihelp-paraminfo-summary": "الحصول على معلومات حول وحدات API.",
+       "apihelp-paraminfo-param-modules": "قائمة بأسماء الوحدات (قيم الوسائط <var>action</var> أو <var>format</var> أو <kbd>main</kbd>)، يمكن تحديد الوحدات الفرعية التي تحتوي على <kbd>+</kbd>، أو كل الوحدات الفرعية التي تحتوي على <kbd>+*</kbd>، أو جميع الوحدات الفرعية بشكل متكرر بـ<kbd>+**</kbd>.",
        "apihelp-paraminfo-param-helpformat": "شكل سلاسل المساعدة.",
+       "apihelp-paraminfo-param-querymodules": "قائمة بأسماء وحدات الاستعلام (قيمة وسيط <var>prop</var> أو <var>meta</var> أو <var>list</var>)، استخدم <kbd>$1modules=query+foo</kbd> بدلا من <kbd>$1querymodules=foo</kbd>.",
        "apihelp-paraminfo-param-mainmodule": "الحصول على معلومات عن وحدة (المستوى الأعلى) الرئيسية أيضا. استخدم <kbd>$1modules=main</kbd> بدلا من ذلك.",
+       "apihelp-paraminfo-param-pagesetmodule": "الحصول على معلومات حول وحدة مجموعة الصفحة (يتم توفير titles= والأصدقاء) كذلك.",
        "apihelp-paraminfo-param-formatmodules": "قائمة بأسماء أشكال الوحدات (قيم الوسيط <var>format</var>). استخدم <var>$1modules</var> بدلا من ذلك.",
        "apihelp-paraminfo-example-1": "عرض معلومات عن <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd> و<kbd>[[Special:ApiHelp/jsonfm|format=jsonfm]]</kbd> و<kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd> و<kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd>.",
        "apihelp-paraminfo-example-2": "أظهر المعلومات لجميع الوحدات الفرعية ل<kbd>[[Special:ApiHelp/query|action=query]]</kbd>.",
+       "apihelp-parse-summary": "يوزع المحتوى ويرجع مخرجات المحلل.",
+       "apihelp-parse-extended-description": "راجع مختلف وحدات prop لـ<kbd>[[Special:ApiHelp/query|action=query]]</kbd>  للحصول على معلومات من الإصدار الحالي للصفحة.\n\nهناك عدة طرق لتحديد النص المراد تحليله: \n# حدد صفحة أو مراجعة، باستخدام <var>$1page</var> أو <var>$1pageid</var> أو <var>$1oldid</var>.\n# حدد المحتوى بشكل صريح، باستخدام <var>$1text</var> و<var>$1title</var> و<var>$1revid</var> و<var>$1contentmodel</var>.\n# تحديد ملخص للتحليل فقط، يجب إعطاء قيمة فارغة لـ<var>$1prop</var>.",
        "apihelp-parse-param-title": "عنوان الصفحة التي ينتمي النص إليها.إذا تم حذفها، <var>$1contentmodel</var> يجب أن تكون محددة، و[[API]] سيتم استخدامه كعنوان.",
        "apihelp-parse-param-text": "نص للتحليل. استخدم <var>$1title</var> أو <var>$1contentmodel</var> للتحكم في نموذج المحتوى.",
+       "apihelp-parse-param-revid": "معرف المراجعة، لـ<code><nowiki>{{REVISIONID}}</nowiki></code> ومتغيرات مشابهة.",
        "apihelp-parse-param-summary": "ملخص للتحليل.",
        "apihelp-parse-param-page": "تحليل محتوى هذه الصفحة. لا يمكن أن تُستخدَم بجانب <var>$1text</var> and <var>$1title</var>.",
        "apihelp-parse-param-pageid": "حلل محتوى هذه الصفحة. تجاوز <var>$1page</var>.",
        "apihelp-parse-param-redirects": "لو <var>$1page</var> أو <var>$1pageid</var> is تم تعيينها للتحويل، حلها.",
        "apihelp-parse-param-oldid": "تحليل مضمون هذا التعديل. تجاوز <var>$1page</var> و<var>$1pageid</var>.",
        "apihelp-parse-param-prop": "أي قطعة من المعلومات تريد الحصول عليها:",
+       "apihelp-parse-paramvalue-prop-text": "يعطي النص المعالج لنص الويكي.",
        "apihelp-parse-paramvalue-prop-langlinks": "يعطي وصلات اللغات في تحليل نصوص الويكي.",
        "apihelp-parse-paramvalue-prop-categories": "يعطي التصنيفات في تحليل نصوص الويكي.",
        "apihelp-parse-paramvalue-prop-categorieshtml": "يعطي إصدار HTML للتصنيفات.",
        "apihelp-parse-paramvalue-prop-images": "يعطي الصور في تحليل نصوص الويكي.",
        "apihelp-parse-paramvalue-prop-externallinks": "يعطي الوصلات الخارجية في تحليل نصوص الويكي.",
        "apihelp-parse-paramvalue-prop-sections": "يعطي الأقسام في تحليل نصوص الويكي.",
+       "apihelp-parse-paramvalue-prop-revid": "يضيف معرِف المراجعة للصفحة التي تم تحليلها.",
        "apihelp-parse-paramvalue-prop-displaytitle": "يضيف العنوان في تحليل نصوص الويكي.",
        "apihelp-parse-paramvalue-prop-headitems": "يعطي عناصر لوضعها في <code>&lt;head&gt;</code> الصفحة.",
        "apihelp-parse-paramvalue-prop-headhtml": "يعطي تحليل <code>&lt;head&gt;</code> الصفحة.",
+       "apihelp-parse-paramvalue-prop-modules": "يعطي وحدات ResourceLoader المستخدمة في الصفحة، للتحميل; استخدم <code>mw.loader.using()</code>، يجب طلب <kbd>jsconfigvars</kbd> أو <kbd>encodedjsconfigvars</kbd> بشكل مشترك مع <kbd>modules</kbd>.",
        "apihelp-parse-paramvalue-prop-jsconfigvars": "يعطي متغيرات تكوين جافا سكريبت الخاصة بهذه الصفحة. للتطبيق; استخدم <code>mw.config.set()</code>.",
        "apihelp-parse-paramvalue-prop-encodedjsconfigvars": "يعطي متغيرات تكوين جافا سكريبت الخاصة بهذه الصفحة كسلسلة JSON.",
        "apihelp-parse-paramvalue-prop-indicators": "يعطي HTML مؤشرات حالة الصفحة المستخدمة في الصفحة.",
        "apihelp-parse-paramvalue-prop-limitreportdata": "يعطي تقرير الحد بطريقة منظمة. لا يعطي أية بيانات، عندما يتم تعيين <var>$1disablelimitreport</var>.",
        "apihelp-parse-paramvalue-prop-limitreporthtml": "يعطي إصدار HTML لتقرير الحد. لا يعطي أية بيانات، عندما يتم تعيين<var>$1disablelimitreport</var>.",
        "apihelp-parse-paramvalue-prop-parsetree": "شجرة تحليل XML لمحتويات المراجعة (يتطلب نموذج محتوى <code>$1</code>)",
+       "apihelp-parse-paramvalue-prop-parsewarnings": "يعطي التحذيرات التي حدثت أثناء تحليل المحتوى.",
+       "apihelp-parse-param-wrapoutputclass": "فئة CSS لاستخدام التفاف إخراج المحلل.",
        "apihelp-parse-param-pst": "قم بتحويل قبل الحفظ على المدخلات قبل تحليل ذلك. صالح فقط عند استخدامه مع النص.",
+       "apihelp-parse-param-onlypst": "قم بإجراء تحويل ما قبل الحفظ (PST) على الإدخال، ولكن لا تقم بتحليله; لعرض نفس نص الويكي، بعد تطبيق PST، صالح فقط عند استخدامه مع <var>$1text</var>.",
        "apihelp-parse-param-effectivelanglinks": "يشمل وصلات لغة المقدمة بواسطة ملحقات (للاستخدام مع <kbd>$1prop=langlinks</kbd>).",
+       "apihelp-parse-param-section": "فقط تحليل محتوى رقم هذا القسم. \nعندما <kbd>new</kbd>، تحليل <var>$1text</var> و<var>$1sectiontitle</var> كما لو كانت إضافة قسم جديد إلى الصفحة.",
+       "apihelp-parse-param-sectiontitle": "عنوان قسم جديد عندما يكون <var>section</var> <kbd>new</kbd>.\n\nعلى عكس تحرير الصفحة، لا يرجع هذا إلى <var>summary</var> عند حذفه أو تفريغه.",
        "apihelp-parse-param-disablelimitreport": "تجاهل تقرير الحد (\"NewPP limit report\") من مخرجات المحلل.",
        "apihelp-parse-param-disablepp": "استخدم <var>$1disablelimitreport</var> بدلا من ذلك.",
        "apihelp-parse-param-disableeditsection": "تجاهل روابط تحرير الأقسام من مخرجات المحلل.",
        "apihelp-parse-param-disabletidy": "لا تشغل تنظيف HTML (على سبيل المثال مرتبة) على مخرجات المحلل.",
+       "apihelp-parse-param-disablestylededuplication": "لا تكرر أوراق الأنماط المضمنة في إخراج المحلل.",
        "apihelp-parse-param-generatexml": "توليد شجرة تحليل XML (يتطلب نموذج المحتوى <code>$1</code>; حل محلها <kbd>$2prop=parsetree</kbd>).",
        "apihelp-parse-param-preview": "تحليل في وضع المعاينة.",
        "apihelp-parse-param-sectionpreview": "تحليل في وضع معاينة القسم (يمكن وضع المعاينة أيضا).",
index 90af65f..c69f267 100644 (file)
        "api-help-param-required": "Tento parametr je povinný.",
        "api-help-datatypes-header": "Datové typy",
        "api-help-datatypes": "Vstupem do MediaWiki by mělo být UTF-8 normalizované do NFC. Jiný vstup se MediaWiki může pokusit převést, ale tím se může stát, že některé operace (např. [[Special:ApiHelp/edit|editace]] s kontrolou MD5) selžou.\n\nNěkteré typy parametrů v API potřebují bližší vysvětlení:\n;boolean\n:Booleovské parametry fungují jako zaškrtávací políčka v HTML: pokud je parametr uveden, bez ohledu na hodnotu, je považován za pravdivý. Pro nepravdivou hodnotu parametr zcela vynechte.\n;časová značka\n:Časové značky lze uvádět v několika formátech. Doporučuje se datum a čas podle ISO 8601. Všechny časy jsou v UTC a obsažené časové pásmo je ignorováno.\n:* Datum a čas podle ISO 8601, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (interpunkce a <kbd>Z</kbd> jsou nepovinné)\n:* Datum a čas podle ISO 8601 s (ignorovaným) zlomkem sekundy, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (pomlčky, dvojtečky a <kbd>Z</kbd> jsou nepovinné)\n:* Formát MediaWiki, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* Obecný číselný formát, <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (nepovinné časové pásmo <kbd>GMT</kbd>, <kbd>+<var>##</var></kbd> nebo <kbd>-<var>##</var></kbd> se ignoruje)\n:* Formát EXIF, <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Formát podle RFC 2822 (časové pásmo lze vynechat), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Formát podle RFC 850 (časové pásmo lze vynechat), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Formát podle céčkové funkce ctime, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* Sekundy od 1970-01-01T00:00:00Z jako celé číslo o 1–13 číslicích (s výjimkou <kbd>0</kbd>)\n:* Řetězec <kbd>now</kbd>\n;alternativní oddělovač vícenásobných hodnot\n:Parametry, které přijímají několik hodnot, se zpravidla předávají s hodnotami oddělenými svislítkem, např. <kbd>param=hodnota1|hodnota2</kbd> nebo <kbd>param=hodnota1%7Chodnota2</kbd>. Pokud musí hodnota obsahovat svislítko, použijte jako oddělovač znak U+001F (Unit Separator) ''a'' před hodnotu přidejte U+001F, např. <kbd>param=%1Fhodnota1%1Fhodnota2</kbd>.",
+       "api-help-templatedparams-header": "Šablonované parametry",
+       "api-help-templatedparams": "Šablonované parametry umožňují situace, kdy modul API potřebuje hodnotu pro každou hodnotu nějakého jiného parametru. Pokud by například existoval modul API pro získání ovoce, mohl by mít parametr <var>ovoce</var>, kterým se určí požadované druhy ovoce, a šablonovaný parametr <var>{ovoce}-počet</var>, kterým se určí požadované počty jednotlivých druhů. Klient API, který by chtěl 1 jablko, 5 banánů a 20 jahod, by mohl vytvořit požadavek <kbd>ovoce=jablka|banány|jahody&jablka-počet=1&banány-počet=5&jahody-počet=20</kbd>.",
        "api-help-param-type-integer": "Typ: {{PLURAL:$1|1=celé číslo|2=seznam celých čísel}}",
        "api-help-param-type-boolean": "Typ: boolean ([[Special:ApiHelp/main#main/datatypes|podrobnosti]])",
        "api-help-param-list": "{{PLURAL:$1|1=Jedna z následujících hodnot|2=Hodnoty (oddělené <kbd>{{!}}</kbd> nebo [[Special:ApiHelp/main#main/datatypes|alternativou]].)}}: $2",
index b1eee12..13d392e 100644 (file)
        "apihelp-query+iwbacklinks-paramvalue-prop-iwtitle": "Ergänzt den Titel des Interwikis.",
        "apihelp-query+iwbacklinks-param-dir": "Die Auflistungsrichtung.",
        "apihelp-query+iwbacklinks-example-simple": "Ruft Seiten ab, die auf [[wikibooks:Test]] verlinken.",
+       "apihelp-query+iwlinks-summary": "Gibt alle Interwikilinks der angegebenen Seiten zurück.",
        "apihelp-query+iwlinks-param-prop": "Zusätzlich zurückzugebende Eigenschaften jedes Interlanguage-Links:",
        "apihelp-query+iwlinks-paramvalue-prop-url": "Ergänzt die vollständige URL.",
        "apihelp-query+iwlinks-param-limit": "Wie viele Interwiki-Links zurückgegeben werden sollen.",
        "apihelp-query+iwlinks-param-prefix": "Gibt nur Interwiki-Links mit diesem Präfix zurück.",
        "apihelp-query+iwlinks-param-dir": "Die Auflistungsrichtung.",
+       "apihelp-query+langbacklinks-param-lang": "Sprache für den Sprachlink.",
        "apihelp-query+langbacklinks-param-limit": "Wie viele Gesamtseiten zurückgegeben werden sollen.",
        "apihelp-query+langbacklinks-param-prop": "Zurückzugebende Eigenschaften:",
        "apihelp-query+langbacklinks-paramvalue-prop-lltitle": "Ergänzt den Titel des Sprachlinks.",
        "api-help-parameters": "{{PLURAL:$1|Parameter}}:",
        "api-help-param-deprecated": "Veraltet.",
        "api-help-param-required": "Dieser Parameter ist erforderlich.",
+       "api-help-param-templated": "Dies ist ein [[Special:ApiHelp/main#main/templatedparams|Vorlagenparameter]]. Bei der Erstellung der Anfrage $2.",
+       "api-help-param-templated-var-first": "<var>&#x7B;$1&#x7D;</var> im Parameternamen sollte mit Werten von <var>$2</var> ersetzt werden",
+       "api-help-param-templated-var": "<var>&#x7B;$1&#x7D;</var> mit Werten von <var>$2</var>",
        "api-help-datatypes-header": "Datentypen",
+       "api-help-templatedparams-header": "Vorlagenparameter",
        "api-help-param-type-limit": "Typ: Ganzzahl oder <kbd>max</kbd>",
        "api-help-param-type-integer": "Typ: {{PLURAL:$1|1=Ganzzahl|2=Liste von Ganzzahlen}}",
        "api-help-param-type-boolean": "Typ: boolesch ([[Special:ApiHelp/main#main/datatypes|Einzelheiten]])",
        "apierror-stashwrongowner": "Falscher Besitzer: $1",
        "apierror-systemblocked": "Du wurdest von MediaWiki automatisch gesperrt.",
        "apierror-timeout": "Der Server hat nicht innerhalb der erwarteten Zeit reagiert.",
+       "apierror-toomanyvalues": "Es wurden zu viele Werte für den Parameter <var>$1</var> angegeben. Die Obergrenze liegt bei $2.",
        "apierror-unknownerror-nocode": "Unbekannter Fehler.",
        "apierror-unknownerror": "Unbekannter Fehler: „$1“.",
        "apierror-unknownformat": "Nicht erkanntes Format „$1“.",
+       "apiwarn-ignoring-invalid-templated-value": "Ignorieren des Wertes <kbd>$2</kbd> in <var>$1</var> bei der Verarbeitung von Vorlagenparametern.",
        "apiwarn-invalidcategory": "„$1“ ist keine Kategorie.",
        "apiwarn-invalidtitle": "„$1“ ist kein gültiger Titel.",
        "apiwarn-notfile": "„$1“ ist keine Datei.",
        "apiwarn-parse-revidwithouttext": "<var>revid</var>, ohne <var>text</var> verwendet, und geparste Seiteneigenschaften wurden angefordert. Wolltest du <var>oldid</var> anstatt <var>revid</var> verwenden?",
-       "apiwarn-toomanyvalues": "Es wurden zu viele Werte für den Parameter <var>$1</var> angegeben. Die Obergrenze liegt bei $2.",
        "apiwarn-validationfailed-badpref": "Keine gültige Einstellung.",
        "apiwarn-validationfailed-cannotset": "Kann nicht von diesem Modul festgelegt werden.",
        "apiwarn-validationfailed-keytoolong": "Der Schlüssel ist zu lang. Es sind nicht mehr als $1 Bytes erlaubt.",
index 6838e54..e1ba665 100644 (file)
        "apihelp-query+recentchanges-param-limit": "How many total changes to return.",
        "apihelp-query+recentchanges-param-type": "Which types of changes to show.",
        "apihelp-query+recentchanges-param-toponly": "Only list changes which are the latest revision.",
+       "apihelp-query+recentchanges-param-title": "Filter entries to those related to a page.",
        "apihelp-query+recentchanges-param-generaterevisions": "When being used as a generator, generate revision IDs rather than titles. Recent change entries without associated revision IDs (e.g. most log entries) will generate nothing.",
        "apihelp-query+recentchanges-example-simple": "List recent changes.",
        "apihelp-query+recentchanges-example-generator": "Get page info about recent unpatrolled changes.",
        "api-help-parameters": "{{PLURAL:$1|Parameter|Parameters}}:",
        "api-help-param-deprecated": "Deprecated.",
        "api-help-param-required": "This parameter is required.",
+       "api-help-param-templated": "This is a [[Special:ApiHelp/main#main/templatedparams|templated parameter]]. When making the request, $2.",
+       "api-help-param-templated-var-first": "<var>&#x7B;$1&#x7D;</var> in the parameter's name should be replaced with values of <var>$2</var>",
+       "api-help-param-templated-var": "<var>&#x7B;$1&#x7D;</var> with values of <var>$2</var>",
        "api-help-datatypes-header": "Data types",
        "api-help-datatypes": "Input to MediaWiki should be NFC-normalized UTF-8. MediaWiki may attempt to convert other input, but this may cause some operations (such as [[Special:ApiHelp/edit|edits]] with MD5 checks) to fail.\n\nSome parameter types in API requests need further explanation:\n;boolean\n:Boolean parameters work like HTML checkboxes: if the parameter is specified, regardless of value, it is considered true. For a false value, omit the parameter entirely.\n;timestamp\n:Timestamps may be specified in several formats. ISO 8601 date and time is recommended. All times are in UTC, any included timezone is ignored.\n:* ISO 8601 date and time, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (punctuation and <kbd>Z</kbd> are optional)\n:* ISO 8601 date and time with (ignored) fractional seconds, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (dashes, colons, and <kbd>Z</kbd> are optional)\n:* MediaWiki format, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* Generic numeric format, <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (optional timezone of <kbd>GMT</kbd>, <kbd>+<var>##</var></kbd>, or <kbd>-<var>##</var></kbd> is ignored)\n:* EXIF format, <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:*RFC 2822 format (timezone may be omitted), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* RFC 850 format (timezone may be omitted), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* C ctime format, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* Seconds since 1970-01-01T00:00:00Z as a 1 to 13 digit integer (excluding <kbd>0</kbd>)\n:* The string <kbd>now</kbd>\n;alternative multiple-value separator\n:Parameters that take multiple values are normally submitted with the values separated using the pipe character, e.g. <kbd>param=value1|value2</kbd> or <kbd>param=value1%7Cvalue2</kbd>. If a value must contain the pipe character, use U+001F (Unit Separator) as the separator ''and'' prefix the value with U+001F, e.g. <kbd>param=%1Fvalue1%1Fvalue2</kbd>.",
+       "api-help-templatedparams-header": "Templated parameters",
+       "api-help-templatedparams": "Templated parameters support cases where an API module needs a value for each value of some other parameter. For example, if there were an API module to request fruit, it might have a parameter <var>fruits</var> to specify which fruits are being requested and a templated parameter <var>{fruit}-quantity</var> to specify how many of each fruit to request. An API client that wants 1 apple, 5 bananas, and 20 strawberries could then make a request like <kbd>fruits=apples|bananas|strawberries&apples-quantity=1&bananas-quantity=5&strawberries-quantity=20</kbd>.",
        "api-help-param-type-limit": "Type: integer or <kbd>max</kbd>",
        "api-help-param-type-integer": "Type: {{PLURAL:$1|1=integer|2=list of integers}}",
        "api-help-param-type-boolean": "Type: boolean ([[Special:ApiHelp/main#main/datatypes|details]])",
        "apierror-templateexpansion-notwikitext": "Template expansion is only supported for wikitext content. $1 uses content model $2.",
        "apierror-timeout": "The server did not respond within the expected time.",
        "apierror-toofewexpiries": "$1 expiry {{PLURAL:$1|timestamp was|timestamps were}} provided where $2 {{PLURAL:$2|was|were}} needed.",
+       "apierror-toomanyvalues": "Too many values supplied for parameter <var>$1</var>. The limit is $2.",
        "apierror-unknownaction": "The action specified, <kbd>$1</kbd>, is not recognized.",
        "apierror-unknownerror-editpage": "Unknown EditPage error: $1.",
        "apierror-unknownerror-nocode": "Unknown error.",
        "apiwarn-difftohidden": "Couldn't diff to r$1: content is hidden.",
        "apiwarn-errorprinterfailed": "Error printer failed. Will retry without params.",
        "apiwarn-errorprinterfailed-ex": "Error printer failed (will retry without params): $1",
+       "apiwarn-ignoring-invalid-templated-value": "Ignoring value <kbd>$2</kbd> in <var>$1</var> when processing templated parameters.",
        "apiwarn-invalidcategory": "\"$1\" is not a category.",
        "apiwarn-invalidtitle": "\"$1\" is not a valid title.",
        "apiwarn-invalidxmlstylesheetext": "Stylesheet should have <code>.xsl</code> extension.",
        "apiwarn-redirectsandrevids": "Redirect resolution cannot be used together with the <var>revids</var> parameter. Any redirects the <var>revids</var> point to have not been resolved.",
        "apiwarn-tokennotallowed": "Action \"$1\" is not allowed for the current user.",
        "apiwarn-tokens-origin": "Tokens may not be obtained when the same-origin policy is not applied.",
-       "apiwarn-toomanyvalues": "Too many values supplied for parameter <var>$1</var>. The limit is $2.",
        "apiwarn-truncatedresult": "This result was truncated because it would otherwise be larger than the limit of $1 bytes.",
        "apiwarn-unclearnowtimestamp": "Passing \"$2\" for timestamp parameter <var>$1</var> has been deprecated. If for some reason you need to explicitly specify the current time without calculating it client-side, use <kbd>now</kbd>.",
        "apiwarn-unrecognizedvalues": "Unrecognized {{PLURAL:$3|value|values}} for parameter <var>$1</var>: $2.",
index 5be4703..8328006 100644 (file)
@@ -30,7 +30,8 @@
                        "Fortega",
                        "Luzcaru",
                        "Javiersanp",
-                       "KATRINE1992"
+                       "KATRINE1992",
+                       "Adjen"
                ]
        },
        "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Documentation]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailing list]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API Announcements]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bugs & requests]\n</div>\n<strong>Status:</strong> Todas las funciones mostradas en esta página deberían estar funcionando, pero la API aún está en desarrollo activo, y puede cambiar en cualquier momento. Suscribase a [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce mailing list] para aviso de actualizaciones.\n\n<strong>Erroneous requests:</strong> Cuando se envían solicitudes erróneas a la API, se enviará un encabezado HTTP con la clave \"MediaWiki-API-Error\" y, luego, el valor del encabezado y el código de error devuelto se establecerán en el mismo valor. Para más información ver [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Errors and warnings]].\n\n<strong>Testing:</strong> Para facilitar la comprobación de las solicitudes de API, consulte [[Special:ApiSandbox]].",
        "apihelp-query+recentchanges-param-limit": "Cuántos cambios en total se devolverán.",
        "apihelp-query+recentchanges-param-type": "Cuántos tipos de cambios se mostrarán.",
        "apihelp-query+recentchanges-param-toponly": "Enumerar solo las modificaciones que sean las últimas revisiones.",
+       "apihelp-query+recentchanges-param-title": "Filtrar entradas mostrando solo aquellas relacionadas con una página.",
        "apihelp-query+recentchanges-param-generaterevisions": "Cuando se utilice como generador, genera identificadores de revisión en lugar de títulos. Las entradas en la lista de cambios recientes que no tengan identificador de revisión asociado (por ejemplo, la mayoría de las entradas de registro) no generarán nada.",
        "apihelp-query+recentchanges-example-simple": "Lista de cambios recientes.",
        "apihelp-query+recentchanges-example-generator": "Obtener información de página de cambios recientes no patrullados.",
        "apierror-badparameter": "Valor no válido para el parámetro <var>$1</var>.",
        "apierror-badquery": "La consulta no es válida.",
        "apierror-badtimestamp": "Valor no válido \"$2\" para el parámetro de marca de tiempo <var>$1</var>.",
+       "apierror-badtoken": "La ficha CSRF no es válida.",
        "apierror-badupload": "El parámetro de subida de archivo <var>$1</var> no es una subida de archivo. Asegúrate de usar <code>multipart/form-data</code> para tu POST e introduce un nombre de archivo en la cabecera <code>Content-Disposition</code>.",
        "apierror-badurl": "Valor no válido \"$2\" para el parámetro de URL <var>$1</var>.",
        "apierror-baduser": "Valor no válido \"$2\" para el parámetro de usuario <var>$1</var>.",
        "apierror-systemblocked": "Has sido bloqueado automáticamente por el software MediaWiki.",
        "apierror-templateexpansion-notwikitext": "La expansión de plantillas solo es compatible con el contenido en wikitexto. $1 usa el modelo de contenido $2.",
        "apierror-timeout": "El servidor no respondió en el plazo previsto.",
+       "apierror-toomanyvalues": "Se proporcionaron demasiados valores al parámetro <var>$1</var>. El límite es de $2.",
        "apierror-unknownaction": "La acción especificada, <kbd>$1</kbd>, no está reconocida.",
        "apierror-unknownerror-editpage": "Error de EditPage desconocido: $1.",
        "apierror-unknownerror-nocode": "Error desconocido.",
index 5ce2331..37ee993 100644 (file)
        "apihelp-query+recentchanges-param-limit": "Combien de modifications renvoyer au total.",
        "apihelp-query+recentchanges-param-type": "Quels types de modification afficher.",
        "apihelp-query+recentchanges-param-toponly": "Lister uniquement les modifications qui sont de la dernière révision.",
+       "apihelp-query+recentchanges-param-title": "Filtrer les entrées vers celles relatives à une page.",
        "apihelp-query+recentchanges-param-generaterevisions": "Utilisé comme générateur, générer des IDs de révision plutôt que des titres.\nLes entrées de modification récentes sans IDs de révision associé (par ex. la plupart des entrées de journaux) ne généreront rien.",
        "apihelp-query+recentchanges-example-simple": "Lister les modifications récentes",
        "apihelp-query+recentchanges-example-generator": "Obtenir l’information de page sur les modifications récentes non relues.",
        "api-help-parameters": "{{PLURAL:$1|Paramètre|Paramètres}} :",
        "api-help-param-deprecated": "Désuet.",
        "api-help-param-required": "Ce paramètre est obligatoire.",
+       "api-help-param-templated": "Ceci est un [[Special:ApiHelp/main#main/templatedparams|paramètre de modèle]]. En faisant une requête, $2.",
+       "api-help-param-templated-var-first": "<var>&#x7B;$1&#x7D;</var> dans le nom du paramètre doit être remplacé par des valeurs de <var>$2</var>",
+       "api-help-param-templated-var": "<var>&#x7B;$1&#x7D;</var> par les valeurs de <var>$2</var>",
        "api-help-datatypes-header": "Type de données",
        "api-help-datatypes": "Les entrées dans MédiaWiki doivent être en UTF-8 à la norme NFC. MédiaWiki peut tenter de convertir d’autres types d’entrée, mais cela peut faire échouer certaines opérations (comme les [[Special:ApiHelp/edit|modifications]] avec contrôles MD5) to fail.\n\nCertains types de paramètre dans les requêtes de l’API nécessitent plus d’explication :\n;boolean\n:Les paramètres booléens fonctionnent comme des cases à cocher HTML : si le paramètre est spécifié, quelle que soit sa valeur, il est considéré comme vrai. Pour une valeur fausse, enlever complètement le paramètre.\n;timestamp\n:Les horodatages peuvent être spécifiés sous différentes formes. Date et heure ISO 8601 est recommandé. Toutes les heures sont en UTC, tout fuseau horaire inclus est ignoré.\n:* Date et heure ISO 8601, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (la ponctuation et <kbd>Z</kbd> sont facultatifs)\n:* Date et heure ISO 8601 avec fractions de seconde (ignorées), <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (tirets, deux-points et <kbd>Z</kbd> sont facultatifs)\n:* Format MédiaWiki, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* Format numérique générique, <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (fuseau horaire facultatif en <kbd>GMT</kbd>, <kbd>+<var>##</var></kbd>, ou <kbd>-<var>##</var></kbd> sont ignorés)\n:* Format EXIF, <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:*Format RFC 2822 (le fuseau horaire est facultatif), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Format RFC 850 (le fuseau horaire est facultatif), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Format ctime C, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* Secondes depuis 1970-01-01T00:00:00Z sous forme d’entier de 1 à 13 chiffres (sans <kbd>0</kbd>)\n:* La chaîne <kbd>now</kbd>",
+       "api-help-templatedparams-header": "Paramètres de modèle",
+       "api-help-templatedparams": "Les paramètres de modèle supportent les cas où un module d’API a besoin d’une valeur pour chaque valeur d’un autre paramètre quelconque. Par exemple, s’il y avait un module d’API pour demander un fruit, il pourrait avoir un paramètre <var>fruits</var> pour spécifier quels fruits sont demandés et un paramètre de modèle <var>{fruit}-quantité</var> pour spécifier la quantité demandée de chaque fruit. Un client de l’API qui voudrait une pomme, cinq bananes et vingt fraises pourrait alors faire une requête comme <kbd>fruits=pommes|bananes|fraises&pommes-quantité=1&bananes-quantité=5&fraises-quantité=20</kbd>.",
        "api-help-param-type-limit": "Type : entier ou <kbd>max</kbd>",
        "api-help-param-type-integer": "Type : {{PLURAL:$1|1=entier|2=liste d’entiers}}",
        "api-help-param-type-boolean": "Type : booléen ([[Special:ApiHelp/main#main/datatypes|détails]])",
        "apierror-templateexpansion-notwikitext": "Le développement du modèle n'est effectif que sur un contenu wikitext. $1 utilise le modèle de contenu $2.",
        "apierror-timeout": "Le serveur n’a pas répondu dans le délai imparti.",
        "apierror-toofewexpiries": "$1 {{PLURAL:$1|horodatage d’expiration a été fourni|horodatages d’expiration ont été fournis}} alors que $2 {{PLURAL:$2|était attendu|étaient attendus}}.",
+       "apierror-toomanyvalues": "Trop de valeurs fournies pour le paramètre <var>$1</var>. La  limite est $2.",
        "apierror-unknownaction": "L'action spécifiée, <kbd>$1</kbd>, n'est pas reconnue.",
        "apierror-unknownerror-editpage": "Erreur inconnue EditPage: $1.",
        "apierror-unknownerror-nocode": "Erreur inconnue.",
        "apiwarn-difftohidden": "Impossible de faire un diff avec r$1 : le contenu est masqué.",
        "apiwarn-errorprinterfailed": "Erreur échec imprimante. Nouvel essai sans paramètres.",
        "apiwarn-errorprinterfailed-ex": "Erreur d’échec de l’impression (réessayera sans paramètres) : $1",
+       "apiwarn-ignoring-invalid-templated-value": "Ignorer la valeur <kbd>$2</kbd> dans <var>$1</var> en traitant les paramètres de modèle.",
        "apiwarn-invalidcategory": "« $1 » n'est pas une catégorie.",
        "apiwarn-invalidtitle": "« $1 » n’est pas un titre valide.",
        "apiwarn-invalidxmlstylesheetext": "Une feuille de style doit avoir une extension <code>.xsl</code>.",
        "apiwarn-redirectsandrevids": "La résolution de la redirection ne peut pas être utilisée avec le paramètre <var>revids</var>. Toutes les redirections vers lesquelles pointent <var>revids</var> n’ont pas été résolues.",
        "apiwarn-tokennotallowed": "L'action « $1 » n'est pas autorisée pour l'utilisateur actuel.",
        "apiwarn-tokens-origin": "Les jetons ne peuvent pas être obtenus quand la politique de même origine n’est pas appliquée.",
-       "apiwarn-toomanyvalues": "Trop de valeurs fournies pour le paramètre <var>$1</var>. La  limite est $2.",
        "apiwarn-truncatedresult": "Ce résultat a été tronqué parce que sinon, il dépasserait la limite de $1 octets.",
        "apiwarn-unclearnowtimestamp": "Passer « $2 » comme paramètre d’horodatage <var>$1</var> a été rendu désuet. Si, pour une raison quelconque, vous avez besoin de spécifier explicitement l’heure courante sans la recalculer du côté client, utilisez <kbd>now</kbd>.",
        "apiwarn-unrecognizedvalues": "{{PLURAL:$3|Valeur non reconnue|Valeurs non reconnues}} pour le paramètre <var>$1</var> : $2.",
index 1f2b028..1731323 100644 (file)
        "apierror-systemblocked": "Foi bloqueado automaticamente polo software MediaWiki.",
        "apierror-templateexpansion-notwikitext": "A expansión de modelos só é compatible co contido en wikitexto. $1 usa o modelo de contido $2.",
        "apierror-timeout": "O servidor non respondeu no tempo esperado.",
+       "apierror-toomanyvalues": "Demasiados valores para o parámetro <var>$1</var>. O límite é $2.",
        "apierror-unknownaction": "A acción especificada, <kbd>$1</kbd>, non está recoñecida.",
        "apierror-unknownerror-editpage": "Erro descoñecido EditPageː $1.",
        "apierror-unknownerror-nocode": "Erro descoñecido.",
        "apiwarn-notfile": "\"$1\" non é un ficheiro.",
        "apiwarn-parse-nocontentmodel": "Non se proporcionou <var>title</var> nin <var>contentmodel</var>, asúmese $1.",
        "apiwarn-tokennotallowed": "A acción \"$1\" non está permitida para o usuario actual.",
-       "apiwarn-toomanyvalues": "Demasiados valores para o parámetro <var>$1</var>. O límite é $2.",
        "apiwarn-truncatedresult": "Truncouse este resultado porque doutra maneira sobrepasaría o límite de $1 bytes.",
        "apiwarn-unrecognizedvalues": "{{PLURAL:$3|Valor non recoñecido|Valores non recoñecidos}} para o parámetro <var>$1</var>: $2.",
        "apiwarn-unsupportedarray": "O parámetro <var>$1</var> usa unha sintaxe PHP de matriz que non está soportada.",
index 097d510..b53c052 100644 (file)
        "apihelp-query+allimages-param-sha1base36": "גיבוב SHA1 של התמונה בבסיס 36 (הבסיס בו נעשה שימוש במדיה־ויקי).",
        "apihelp-query+allimages-param-user": "להחזיר רק קבצים שהועלו על־ידי המשתמש הזה. יכול לשמש רק עם $1sort=timestamp. לא יכול לשמש יחד עם $1filterbots.",
        "apihelp-query+allimages-param-filterbots": "איך לסנן קבצים שמעלים בוטים. יכול לשמש רק עם $1sort=timestamp. לא יכול לשמש יחד עם $1user.",
-       "apihelp-query+allimages-param-mime": "×\90×\99×\9c×\95 ×¡×\95×\92×\99 MIME ×\9c×\97×\91פש, ×\9c×\9eש×\9c <kbd>image/jpeg</kbd>.",
+       "apihelp-query+allimages-param-mime": "אילו סוגי MIME לחפש, למשל <kbd>image/jpeg</kbd>.",
        "apihelp-query+allimages-param-limit": "כמה תמונות להחזיר בסך הכול.",
        "apihelp-query+allimages-example-B": "הצגת רשימה של קבצים שמתחילים באות <kbd>B</kbd>.",
        "apihelp-query+allimages-example-recent": "הצגת רשימת קבצים שהועלו לאחרונה, דומה ל־[[Special:NewFiles]].",
        "apihelp-query+categories-paramvalue-prop-hidden": "תיוג קטגוריות שהוסתרו באמצעות <code>_&#95;HIDDENCAT_&#95;</code>.",
        "apihelp-query+categories-param-show": "איזה סוג של קטגוריות להציג.",
        "apihelp-query+categories-param-limit": "כמה קטגוריות להחזיר.",
-       "apihelp-query+categories-param-categories": "×\9cרש×\95×\9d ×¨×§ ×\90ת ×\94ק×\98×\92×\95ר×\99×\95ת ×\94×\90×\9c×\95. ×©×\99×\9e×\95ש×\99 ×\9c×\91×\93×\99ק×\94 ×¢ם דף מסוים נמצא בקטגוריה מסוימת.",
+       "apihelp-query+categories-param-categories": "×\9cרש×\95×\9d ×¨×§ ×\90ת ×\94ק×\98×\92×\95ר×\99×\95ת ×\94×\90×\9c×\95. ×©×\99×\9e×\95ש×\99 ×\9c×\91×\93×\99ק×\94 ×\90ם דף מסוים נמצא בקטגוריה מסוימת.",
        "apihelp-query+categories-param-dir": "באיזה כיוון לרשום.",
        "apihelp-query+categories-example-simple": "קבלת רשימת קטגוריות שהם <kbd>Albert Einstein</kbd> שייך אליהן.",
        "apihelp-query+categories-example-generator": "קבלת מידע על כל הקטגוריות שמשמשות בדף <kbd>Albert Einstein</kbd>.",
        "apihelp-query+imageinfo-paramvalue-prop-uploadwarning": "משמש את Special:Upload כדי לקבל מידע על קובץ קיים. לא נועד לשימוש מחוץ לליבת MediaWiki.",
        "apihelp-query+imageinfo-paramvalue-prop-badfile": "מוסיף האם הקובץ נמצא ב־[[MediaWiki:Bad image list]]",
        "apihelp-query+imageinfo-param-limit": "כמה גרסאות של קובץ לכל קובץ.",
-       "apihelp-query+imageinfo-param-start": "×\9e×\90×\99×\96 ×\97×\95ת×\9dÖ¾×\96×\9e×\9f ×\9c×\94ת×\97×\99×\9c רשימה.",
+       "apihelp-query+imageinfo-param-start": "×\9e×\90×\99×\9c×\95 ×ª×\90ר×\99×\9a ×\95שע×\94 ×\9c×\94ת×\97×\99×\9c ×\90ת ×\94רשימה.",
        "apihelp-query+imageinfo-param-end": "באיזה חותם־זמן לסיים את הרשימה.",
        "apihelp-query+imageinfo-param-urlwidth": "אם מוגדר $2prop=url, יוחזר URL לתמונה שגודלה הותאם לרוחב הזה.\nמסיבות של ביצועים, אם האפשרות הזאת משמשת, לא יוחזרו יותר מ־$1 תמונות.",
        "apihelp-query+imageinfo-param-urlheight": "דומה ל־$1urlwidth.",
        "apihelp-query+recentchanges-param-end": "באיזה חותם זמן להפסיק לרשום.",
        "apihelp-query+recentchanges-param-namespace": "לסנן את השינויים רק למרחבי השם האלה.",
        "apihelp-query+recentchanges-param-user": "לרשום רק שינויים של המשתמש הזה.",
-       "apihelp-query+recentchanges-param-excludeuser": "Don't list changes by this user",
+       "apihelp-query+recentchanges-param-excludeuser": "לא לרשום שינויים ממשתמש זה.",
        "apihelp-query+recentchanges-param-tag": "לרשום רק שינויים שמתויגים עם התג הזה.",
        "apihelp-query+recentchanges-param-prop": "לכלול פריטי מידע נוספים:",
        "apihelp-query+recentchanges-paramvalue-prop-user": "הוספת המשתמש האחראי על העריכה ותיוג אם זאת כתובת IP.",
        "apihelp-query+siteinfo-paramvalue-prop-namespacealiases": "רשימת כינויי מרחבי שם רשומים.",
        "apihelp-query+siteinfo-paramvalue-prop-specialpagealiases": "רשימת כינויים דפים מיוחדים.",
        "apihelp-query+siteinfo-paramvalue-prop-magicwords": "רשימות מילות קסם וכינוייהן.",
-       "apihelp-query+siteinfo-paramvalue-prop-statistics": "×\94×\97×\96ר×\96ת ×¡×\98×\98×\99ס×\98×\99ק×\95ת אתר.",
+       "apihelp-query+siteinfo-paramvalue-prop-statistics": "×\94×\97×\96רת ×¡×\98×\98×\99ס×\98×\99ק×\95ת ×©×\9c ×\94אתר.",
        "apihelp-query+siteinfo-paramvalue-prop-interwikimap": "החזרת מפת בינוויקי (אפשר שתהיה מסוננת, אפשר שתהיה מותאמת מקומית באמצעות <var>$1inlanguagecode</var>).",
        "apihelp-query+siteinfo-paramvalue-prop-dbrepllag": "החזרת שרת מסד־נתונים עם שיהוי השכפול הגבוה ביותר.",
        "apihelp-query+siteinfo-paramvalue-prop-usergroups": "החזרת קבוצות משתמשים וההרשאות המשויכות.",
        "apihelp-query+watchlist-param-end": "באיזה חותם זמן להפסיק לרשום.",
        "apihelp-query+watchlist-param-namespace": "סינון שינויים רק למרחבי השם שניתנו.",
        "apihelp-query+watchlist-param-user": "לרשום רק שינויים של המשתמש הזה.",
-       "apihelp-query+watchlist-param-excludeuser": "Don't list changes by this user",
+       "apihelp-query+watchlist-param-excludeuser": "לא לרשום שינויים ממשתמש זה.",
        "apihelp-query+watchlist-param-limit": "כמה תוצאות סך הכול להחזיר בכל בקשה.",
        "apihelp-query+watchlist-param-prop": "אילו מאפיינים נוספים לקבל:",
        "apihelp-query+watchlist-paramvalue-prop-ids": "הוספת מזהי גסה ומזהי דף.",
        "apihelp-rollback-param-title": "שם הדף לשחזור. לא יכול לשמש יחד עם <var>$1pageid</var>.",
        "apihelp-rollback-param-pageid": "מזהה הדף לשחזור. לא יכול לשמש יחד עם <var>$1title</var>.",
        "apihelp-rollback-param-tags": "אילו תגים להחיל על השחזור.",
-       "apihelp-rollback-param-user": "שם המשתמשים שהעריכות שלו תשוחזרנה.",
+       "apihelp-rollback-param-user": "שם המשתמש שהעריכות שלו תשוחזרנה.",
        "apihelp-rollback-param-summary": "תקציר עריכה מותאם. אם ריק, ישמש תקציר לפי בררת מחדל.",
        "apihelp-rollback-param-markbot": "לסמן את העריכות ששוחזרו ואת השחזור בתור עריכות בוט.",
        "apihelp-rollback-param-watchlist": "הוספה או הסרה של הדף ללא תנאי מרשימת המעקב של המשתמש הנוכחי, להשתמש בהעדפות או לא לשנות את המעקב.",
        "apihelp-setnotificationtimestamp-example-page": "אתחול מצב ההודעה עבור <kbd>Main Page</kbd>.",
        "apihelp-setnotificationtimestamp-example-pagetimestamp": "הגדרת חותם־הזמן להודעה ל־<kbd>Main page</kbd> כך שכל העריכות מאז 1 בינואר 2012 מוגדרות בתור כאלה שלא נצפו.",
        "apihelp-setnotificationtimestamp-example-allpages": "אתחול מצב ההודעה עבור דפים במרחב השם <kbd>{{ns:user}}</kbd>.",
-       "apihelp-setpagelanguage-summary": "שנ×\94 ×\90ת ×\94שפ×\94 ×©×\9c ×\93×£",
-       "apihelp-setpagelanguage-extended-description-disabled": "ש×\99× ×\95×\99 ×\94שפ×\94 ×©×\9c ×\93×£ ×\9c×\90 ×\9e×\95רש×\94 ×\91×\95×\95×\99ק×\99 ×\96×\94.\n\n×\94פע×\9c ×\90ת <var>[[mw:Special:MyLanguage/Manual:$wgPageLanguageUseDB|$wgPageLanguageUseDB]]</var> ×¢×\9c ×\9eנת ×\9c×\94שת×\9eש ×\91פע×\95×\9c×\94 ×\96×\95",
+       "apihelp-setpagelanguage-summary": "ש×\99× ×\95×\99 ×\94שפ×\94 ×©×\9c ×\93×£.",
+       "apihelp-setpagelanguage-extended-description-disabled": "×\9c×\90 × ×\99ת×\9f ×\9cשנ×\95ת ×©×¤×\95ת ×©×\9c ×\93פ×\99×\9d ×\91×\90תר ×\94×\95×\95×\99ק×\99 ×\94×\96×\94.\n\n×\99ש ×\9c×\94פע×\99×\9c ×\90ת <var dir=\"ltr\">[[mw:Special:MyLanguage/Manual:$wgPageLanguageUseDB|$wgPageLanguageUseDB]]</var> ×¢×\9cÖ¾×\9eנת ×\9c×\94שת×\9eש ×\91פע×\95×\9c×\94 ×\96×\95.",
        "apihelp-setpagelanguage-param-title": "כותרת הדף שאת שפתו ברצונך לשנות. לא אפשרי להשתמש באפשרות עם <var>$1pageid</var>.",
        "apihelp-setpagelanguage-param-pageid": "מזהה הדף שאת שפתו ברצונך לשנות. לא אפשרי להשתמש באפשרות עם <var>$1title</var>.",
        "apihelp-setpagelanguage-param-lang": "קוד השפה של השפה שאליה צריך לשנות את הדף. יש להשתמש ב־<kbd>default</kbd> כדי לאתחל את הדף לשפת בררת המחדל של הוויקי.",
        "apihelp-phpfm-summary": "לפלוט נתונים בתסדיר PHP מוסדר (עם הדפסה יפה ב־HTML).",
        "apihelp-rawfm-summary": "לפלוט את הנתונים, כולל אלמנטים לניפוי שגיאות, בתסדיר JSON (עם הדפסה יפה ב־HTML).",
        "apihelp-xml-summary": "לפלוט נתונים בתסדיר XML.",
-       "apihelp-xml-param-xslt": "×\90×\9d ×¦×\95×\99×\9f, ×\99ש ×\9c×\94×\95ס×\99×£ ×\90ת ×©×\9d ×\94×\93×£ ×\9b×\92×\99×\9c×\99×\95×\9f ×¢×\99צ×\95×\91 XSL. ×¢×\9c ×\94ער×\9a ×\9c×\94×\99×\95ת ×\9b×\95תרת ×\91 {{ns:MediaWiki}} ×\91×\9eר×\97×\91 ×©×\9d ×\94×\9eשת×\9eש, ×\94×\9eסת×\99×\99×\9d ×\91-  <code>.xsl</code>.",
+       "apihelp-xml-param-xslt": "×\90×\9d ×¦×\95×\99×\9f, ×\94×\93×£ ×\99ת×\95×\95סף ×\9b×\92×\99×\9c×\99×\95×\9f XSL. ×\94ער×\9a ×\97×\99×\99×\91 ×\9c×\94×\99×\95ת ×\9b×\95תרת ×\91×\9eר×\97×\91 ×\94ש×\9d \"{{ns:MediaWiki}}\" ×©×\9eסת×\99×\99×\9eת ×\91Ö¾<code dir=\"ltr\">.xsl</code>.",
        "apihelp-xml-param-includexmlnamespace": "אם זה צוין, מוסיף מרחב שם של XML.",
        "apihelp-xmlfm-summary": "לפלוט נתונים בתסדיר XML (עם הדפסה יפה ב־HTML).",
        "api-format-title": "תוצאה של API של מדיה־ויקי",
        "api-help-parameters": "{{PLURAL:$1|פרמטר|פרמטרים}}:",
        "api-help-param-deprecated": "מיושן.",
        "api-help-param-required": "פרמטר זה נדרש.",
+       "api-help-param-templated": "זהו  [[Special:ApiHelp/main#main/templatedparams|פרמטר בתבנית]]. בעת ביצוע הבקשה, $2.",
+       "api-help-param-templated-var-first": "יש להחליף את הטקסט <var>&#x7B;$1&#x7D;</var> (בשם הפרמטר) עם הערכים של הפרמטר <var>$2</var>",
+       "api-help-param-templated-var": "<var>&#x7B;$1&#x7D;</var> עם הערכים של הפרמטר <var>$2</var>",
        "api-help-datatypes-header": "סוגי נתונים",
        "api-help-datatypes": "קלט למדיה־ויקי צריך להיות בקידוד UTF-8 מנורמל ב־NFC. מדיה־ויקי יכולה לנסות להמיר קלט אחר, אבל זה עלול לגרום לפעולות מסוימות (כגון [[Special:ApiHelp/edit|עריכות]] עם בדיקות MD5) להיכשל.\n\nחלק מסוגי הפרמטרים בבקשות API דורשים הסבר נוסף:\n;בוליאני (boolean)\n:פרמטרים בוליאניים עובדים כמו תיבות סימון של HTML: אם הפרמטר צוין, בלי קשר לערך שלו, הוא אמת (true). בשביל ערך שקר (false), יש להשמיט את הפרמטר לגמרי.\n;חותם־זמן (timestamp)\n:אפשר לכתוב חותמי־זמן במספר תסדירים. תאריך ושעה לפי ISO 8601 הוא הדבר המומלת. כל הזמנים מצוינים ב־ UTC, לא תהיה השפעה לשום אזור זמן שיצוין.\n:* תאריך ושעה לפי ISO 8601‏, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (לא חובה לכתוב פיסוק ו־<kbd>Z</kbd>)\n:* תאריך ושעה לפי ISO 8601 עם חלקי שנייה (שלא תהיה להם שום השפעה), <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (לא חובה לכתוב קווים מפרידים, נקודתיים ו־<kbd>Z</kbd>)\n:* תסדיר MediaWiki‏, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* תסדיר מספרי כללי, <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (לאזור זמן אופציונלי של <kbd>GMT</kbd>‏, <kbd dir=\"ltr\">+<var>##</var></kbd>, או <kbd dir=\"ltr\">-<var>##</var></kbd> אין השפעה)\n:* תסדיר EXIF‏, <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* תסדיר RFC 2822 (אפשר להשמיט את אזור הזמן), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* תסדיר RFC 850 (אפשר להשמיט את אזור הזמן), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* תסדיר C ctime‏, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* שניות מאז 1970-01-01T00:00:00Z בתור מספר שלך בין 1 ל־13 (לא כולל <kbd>0</kbd>)\n:* המחרוזת <kbd>now</kbd>\n;מפריד ערכים מרובים חלופי\n:פרמטרים שלוקחים ערכים מרובים בדרך־כלל נשלחים עם הערכים מופרדים באמצעות תו מקל, למשל <kbd>param=value1|value2</kbd> או <kbd>param=value1%7Cvalue2</kbd>. אם הערך צריך להכיל את תו המקל, יש להשתמש ב־U+001F (מפריד יחידות) בתור המפריד ''וגם'' להוסיף לתחילת הערך U+001F, למשל <kbd>param=%1Fvalue1%1Fvalue2</kbd>.",
+       "api-help-templatedparams-header": "פרמטרים בתבניות",
+       "api-help-templatedparams": "התכונה \"פרמטרים בתבניות\" תומכת במקרים שבהם מודול של API זקוק לערך כלשהו עבור ערכים של פרמטרים אחרים. למשל, אם היה מודול API לבקשת פרי, ייתכן שהוא היה זקוק לפרמטר בשם <var>פירות</var> על־מנת לציין מהם הפירות המבוקשים, ולפרמטר בתבנית בשם <var>{פרי}-כמות</var> על־מנת לציין את הכמות של כל פרי עבור הבקשה. לשם כך, לקוח API שמעוניין לקבל תפוח אחד, 5 בננות ו־20 תותים יכול היה ליצור בקשה בסגנון <kbd>פירות=תפוחים|בננות|תותים&תפוחים-כמות=1&בננות-כמות=5&תותים-כמות=20</kbd>.",
        "api-help-param-type-limit": "סוג: מספר שלם או <kbd>max</kbd>",
        "api-help-param-type-integer": "סוג: {{PLURAL:$1|1=מספר שלם|2=רשימת מספרים שלמים}}",
        "api-help-param-type-boolean": "סוג: בוליאני ([[Special:ApiHelp/main#main/datatypes|פרטים]])",
        "apierror-templateexpansion-notwikitext": "הרחבת תבניות נתמכת רק בתוכן קוד ויקי (wikitext). $1 משתמש במודל התוכן $2.",
        "apierror-timeout": "השרת לא השיב בזמן המצופה.",
        "apierror-toofewexpiries": "{{PLURAL:$1|ניתן חותם זמן תפוגה אחד|ניתנו $1 חותמי זמן תפוגה}} כאשר {{PLURAL:$2|היה נחוץ אחד|היו נחוצים $1}}.",
+       "apierror-toomanyvalues": "יותר מדי ערכים סופקו לפרמטר <var>$1</var>. המגבלה היא $2.",
        "apierror-unknownaction": "הפעולה שניתנה, <kbd>$1</kbd>, אינה מוכרת.",
        "apierror-unknownerror-editpage": "שגיאת EditPage בלתי־ידועה: $1.",
        "apierror-unknownerror-nocode": "שגיאה בלתי־ידועה.",
        "apierror-writeapidenied": "אין לך הרשאה לערוך את הוויקי הזה דרך ה־API.",
        "apiwarn-alldeletedrevisions-performance": "לביצועים טובים יותר בעת יצירת כותרת, יש להשתמש ב־<kbd>$1dir=newer</kbd>.",
        "apiwarn-badurlparam": "לא היה אפשר לפענח את <var>$1urlparam</var> עבור $2. משתמשים רק ב־width ו־height.",
-       "apiwarn-badutf8": "×\94ער×\9a ×\94ער×\9a ×©×\94×\95×¢×\91ר ×\9cÖ¾<var>$1</var> ×\9e×\9b×\99×\9c × ×ª×\95× ×\99×\9d ×\91×\9cת×\99־תק×\99× ×\99×\9d ×\90×\95 ×\91×\9cת×\99Ö¾×\9e× ×\95ר×\9e×\9c×\99×\9d. × ×ª×\95× ×\99×\9d ×\98קס×\98 ×\90×\9e×\95ר×\99×\9d ×\9c×\94×\99×\95ת ×ª×§×\99× ×\99×\9d, ×\9e× ×\95ר×\9e×\9c×\99 NFC ×\9c×\9c×\90 ×ª×\95×\95×\99 ×\91קר×\94 C0 ×\9c×\9e×¢×\98 HT (\\t)â\80\8f, LF (\\n), ×\95Ö¾CR (\\r).",
+       "apiwarn-badutf8": "×\94ער×\9a ×©×\94×\95×¢×\91ר ×\9cÖ¾<var>$1</var> ×\9e×\9b×\99×\9c × ×ª×\95× ×\99×\9d ×\91×\9cת×\99־תק×\99× ×\99×\9d ×\90×\95 ×\91×\9cת×\99Ö¾×\9e× ×\95ר×\9e×\9c×\99×\9d. × ×ª×\95× ×\99×\9d ×\98קס×\98 ×\90×\9e×\95ר×\99×\9d ×\9c×\94×\99×\95ת ×ª×§×\99× ×\99×\9d, ×\9e× ×\95ר×\9e×\9c×\99 NFC ×\95×\9c×\9c×\90 ×ª×\95×\95×\99 ×\91קר×\94 C0 ×\9c×\9e×¢×\98 <span dir=\"ltr\">HT (\\t)</span>&rlm;, <span dir=\"ltr\">LF (\\n)</span>&rlm; ×\95Ö¾<span dir=\"ltr\">CR (\\r)</span>.",
        "apiwarn-checktoken-percentencoding": "נא לבדוק שסימנים כמו \"+\" באסימון מקודדים עם אחוזים בצורה נכונה ב־URL.",
        "apiwarn-compare-nocontentmodel": "לא היה אפשר לקבוע את מודל התוכן, נניח שזה $1.",
        "apiwarn-deprecation-deletedrevs": "<kbd>list=deletedrevs</kbd> הוצהר בתור מיושן. נא להשתמש ב־ <kbd>prop=deletedrevisions</kbd> או ב־<kbd>list=alldeletedrevisions</kbd> במקום זה.",
        "apiwarn-difftohidden": "לא היה אפשר לעשות השוואה עם גרסה $1: התוכן מוסתר.",
        "apiwarn-errorprinterfailed": "מדפיס השגיאות לא עבד. ינסה שוב ללא פרמטרים.",
        "apiwarn-errorprinterfailed-ex": "מדפיס השגיאות לא עבד (ינסה שוב ללא פרמטרים): $1",
+       "apiwarn-ignoring-invalid-templated-value": "לא ייעשה שימוש בערך <kbd>$2</kbd> שבפרמטר <var>$1</var> בעת עיבוד הפרמטרים בתבנית.",
        "apiwarn-invalidcategory": "\"$1\" אינה קטגוריה.",
        "apiwarn-invalidtitle": "\"$1\" אינה כותרת תקינה.",
-       "apiwarn-invalidxmlstylesheetext": "לגיליון הסגנונות אמור להיות הסיומת <code dir=\"ltr\">.xsl</code>.",
+       "apiwarn-invalidxmlstylesheetext": "לגיליון הסגנונות אמורה להיות הסיומת <code dir=\"ltr\">.xsl</code>.",
        "apiwarn-invalidxmlstylesheet": "ניתן גיליון סגנונות שאינו תקין או אינו קיים.",
        "apiwarn-invalidxmlstylesheetns": "גיליון הסגנונות אמור להיות במרחב השם {{ns:MediaWiki}}.",
        "apiwarn-moduleswithoutvars": "המאפיין <kbd>modules</kbd> לא הוגדר, אבל לא <kbd>jsconfigvars</kbd> או <kbd>encodedjsconfigvars</kbd>. משתני הגדרות נחוצים בשביל שימוש נכון במודולים.",
        "apiwarn-redirectsandrevids": "פתרון הפניות לא יכול לשמש יחד עם הפרמטר <var>revids</var>. הפניות ש־<var>revids</var> מצביע אליהן לא נפתרו.",
        "apiwarn-tokennotallowed": "הפעולה \"$1\" אינה מותרת למשתמש הנוכחי.",
        "apiwarn-tokens-origin": "לא ניתן לקבל אסימונים כשמדיניות המקור הזהה אינה חלה.",
-       "apiwarn-toomanyvalues": "יותר מדי ערכים סופקו לפרמטר <var>$1</var>. המגבלה היא $2.",
        "apiwarn-truncatedresult": "התוצאה נחתכה כי אחרת היא הייתה ארוכה מהמגבלה של $1 בתים.",
        "apiwarn-unclearnowtimestamp": "העברת \"$2\" בתור פרמטר חותם־זמן <var>$1</var> הוצהרה בתור מיושנת. אם מסיבה כלשהי אתם צריכים להגדיר במפורש את הזמן הנוכחי ללא חישובו בצד הלקוח, יש להשתמש ב־<kbd>now</kbd>.",
-       "apiwarn-unrecognizedvalues": "לפרמטר <var>$1</var> היתנ ג{{PLURAL:$3|ניתן ערך בלתי־ידוע|ניתנו ערכים בלתי־ידועים}}: $2.",
+       "apiwarn-unrecognizedvalues": "לפרמטר <var>$1</var> {{PLURAL:$3|ניתן ערך בלתי־ידוע|ניתנו ערכים בלתי־ידועים}}: $2.",
        "apiwarn-unsupportedarray": "הפרמטר <var>$1</var> משתמש בתחביר מערכים שאינו נתמך ב־PHP.",
        "apiwarn-urlparamwidth": "התעלמות מרוחב (width) שהוגדר ב־<var>$1urlparam</var> (ערך: $2) לטובת רוחב שנגזר מ־<var>$1urlwidth</var>/<var>$1urlheight</var> (ערך: $3).",
        "apiwarn-validationfailed-badchars": "תווים בלתי־תקינים במפתח (מותרים רק <code>a-z</code>‏, <code>A-Z</code>‏, <code>0-9</code>‏, <code>_</code>, ו־<code>-</code>).",
index 38d2901..575715f 100644 (file)
        "api-help-parameters": "{{PLURAL:$1|Parametro|Parametri}}:",
        "api-help-param-deprecated": "Deprecato.",
        "api-help-param-required": "Questo parametro è obbligatorio.",
+       "api-help-param-templated-var": "<var>&#x7B;$1&#x7D;</var> con valori di <var>$2</var>",
        "api-help-datatypes-header": "Tipi di dato",
+       "api-help-templatedparams-header": "Parametri template",
        "api-help-param-type-limit": "Tipo: intero o <kbd>max</kbd>",
        "api-help-param-type-integer": "Tipo: {{PLURAL:$1|1=intero|2=elenco di interi}}",
        "api-help-param-type-boolean": "Tipo: booleano ([[Special:ApiHelp/main#main/datatypes|dettagli]])",
        "apierror-maxchars": "Il parametro <var>$1</var> non può essere più lungo di $2 {{PLURAL:$2|carattere|caratteri}}",
        "apierror-nosuchuserid": "Non c'è alcun utente con ID $1.",
        "apierror-timeout": "Il server non ha risposto entro il tempo previsto.",
+       "apierror-toomanyvalues": "Troppi valori forniti per il parametro <var>$1</ var>. Il limite è $2.",
        "api-credits-header": "Crediti"
 }
index 354e75c..222a20c 100644 (file)
        "api-help-parameters": "{{PLURAL:$1|변수}}:",
        "api-help-param-deprecated": "구식입니다.",
        "api-help-param-required": "이 변수는 필수 입력 사항입니다.",
+       "api-help-param-templated": "이것은 [[Special:ApiHelp/main#main/templatedparams|틀 변수]]입니다. 요청하실 때 $2.",
        "api-help-datatypes-header": "데이터 유형",
        "api-help-datatypes": "API 요청 내 몇몇 매개변수형에 대해 더 자세히 설명해보겠습니다:\n;boolean\n:Boolean 매개변수들은 HTML 체크박스처럼 동작합니다: 만약 매개변수가 지정되었다면, 값에 상관없이 참의 값으로 여겨집니다. 거짓값은 매개변수 전체를 생략하세요.\n;timestamp\n:타임스탬프들은 여러 형식으로 표현될 수 있으나 ISO 8601 날짜와 시간이 추천됩니다. 모든 시간은 UTC이어야 하며, 포함된 시간대는 모두 무시됩니다.\n:* ISO 8601 날짜와 시간, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (구두점과 <kbd>Z</kbd>는 선택입니다.)\n:* ISO 8601 날짜와 시간과 (무시되는) 소수 초, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (대시, 콜론과 <kbd>Z</kbd>는 선택입니다.)\n:* 미디어위키 형식, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* 일반적인 수 형식 <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (<kbd>GMT</kbd>, <kbd>+<var>##</var></kbd>, 또는 <kbd>-<var>##</var></kbd>와 같은 선택적 시간대는 무시됩니다)\n:*RFC 2822 형식 (시간대는 생략될 수 있음), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* RFC 850 형식 (시간대는 생략될 수 있음), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* C ctime 형식, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* 1부터 13자리까지의 숫자로 표현된 1970-01-01T00:00:00Z부터 흐른 시간(초) (<kbd>0</kbd>을 제외)\n:* 문자열 <kbd>now</kbd>",
+       "api-help-templatedparams-header": "틀 변수",
        "api-help-param-type-limit": "유형: 정수 또는 <kbd>max</kbd>",
        "api-help-param-type-integer": "유형: {{PLURAL:$1|1=정수|2=정수 목록}}",
        "api-help-param-type-boolean": "유형: 불리언 ([[Special:ApiHelp/main#main/datatypes|자세한 정보]])",
        "apierror-stashwrongowner": "잘못된 소유자: $1",
        "apierror-systemblocked": "당신은 미디어위키에 의해서 자동으로 차단되었습니다.",
        "apierror-timeout": "서버가 예측된 시간 내에 응답하지 않았습니다.",
+       "apierror-toomanyvalues": "<var>$1</var> 변수에 너무 많은 값이 지정되었습니다. 제한은 $2입니다.",
        "apierror-unknownerror-editpage": "알 수 없는 EditPage 오류: $1.",
        "apierror-unknownerror-nocode": "알 수 없는 오류.",
        "apierror-unknownerror": "알 수 없는 오류: \"$1\"",
index 8591eba..9d43533 100644 (file)
        "apierror-specialpage-cantexecute": "Nie masz uprawnień, aby zobaczyć wyniki tej strony specjalnej.",
        "apierror-stashwrongowner": "Nieprawidłowy właściciel: $1",
        "apierror-timeout": "Serwer nie odpowiedział w spodziewanym czasie.",
+       "apierror-toomanyvalues": "Podano zbyt wiele wartości dla parametru <var>$1</var>. Ograniczenie do $2.",
        "apierror-unknownerror-nocode": "Nieznany błąd.",
        "apierror-unknownerror": "Nieznany błąd: „$1”.",
        "apierror-unknownformat": "Nierozpoznany format „$1”.",
        "apiwarn-invalidtitle": "„$1” nie jest poprawnym tytułem.",
        "apiwarn-notfile": "„$1” nie jest plikiem.",
        "apiwarn-tokennotallowed": "Działanie „$1” jest niedozwolone dla bieżącego użytkownika.",
-       "apiwarn-toomanyvalues": "Podano zbyt wiele wartości dla parametru <var>$1</var>. Ograniczenie do $2.",
        "apiwarn-validationfailed-keytoolong": "klucz zbyt długi (dozwolone nie więcej niż $1 bajtów).",
        "apiwarn-validationfailed": "Błąd walidacji dla <kbd>$1</kbd>: $2",
        "apiwarn-wgDebugAPI": "<strong>Ostrzeżenie o zabezpieczeniach</strong>: włączone jest <var>$wgDebugAPI</var>.",
index 1445647..65c3cff 100644 (file)
        "apihelp-query+recentchanges-param-limit": "Quantas alterações a serem retornadas.",
        "apihelp-query+recentchanges-param-type": "Quais tipos de mudanças mostrar.",
        "apihelp-query+recentchanges-param-toponly": "Somente lista as alterações que são as últimas revisões.",
+       "apihelp-query+recentchanges-param-title": "Filtre as entradas para aquelas relacionadas a uma página.",
        "apihelp-query+recentchanges-param-generaterevisions": "Quando usado como gerador, gere IDs de revisão em vez de títulos. As entradas de alterações recentes sem IDs de revisão associadas (por exemplo, a maioria das entradas de log) não gerarão nada.",
        "apihelp-query+recentchanges-example-simple": "Listar mudanças recentes.",
        "apihelp-query+recentchanges-example-generator": "Obter informações da página sobre as mudanças recentes não patrulhadas.",
        "api-help-parameters": "{{PLURAL:$1|Parâmetro|Parâmetros}}:",
        "api-help-param-deprecated": "Obsoleto.",
        "api-help-param-required": "Este parâmetro é obrigatório.",
+       "api-help-param-templated": "Este parâmetro é um [[Special:ApiHelp/main#main/templatedparams|parâmetro de predefinição]]. Ao fazer o pedido, $2.",
+       "api-help-param-templated-var-first": "<var>&#x7B;$1&#x7D;</var> no nome do parâmetro deve ser substituído com os valores de <var>$2</var>",
+       "api-help-param-templated-var": "<var>&#x7B;$1&#x7D;</var> com valores de <var>$2</var>",
        "api-help-datatypes-header": "Tipos de dados",
        "api-help-datatypes": "A entrada para MediaWiki deve ser UTF-8 normalizada pelo NFC. O MediaWiki pode tentar converter outra entrada, mas isso pode causar a falha de algumas operações (como [[Special:ApiHelp/edit|editar]] com verificações MD5).\n\nAlguns tipos de parâmetros em solicitações de API precisam de uma explicação adicional:\n;boolean\n:Os parâmetros booleanos funcionam como caixas de seleção HTML: se o parâmetro for especificado, independentemente do valor, é considerado verdadeiro. Para um valor falso, omita o parâmetro inteiramente.\n;timestamp\n: As marcas de tempo podem ser especificadas em vários formatos. É recomendada a data e a hora ISO 8601. Todos os horários estão em UTC, qualquer fuso horário incluído é ignorado.\n:* Data e hora ISO 8601, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (pontuação e <kbd>Z</kbd> são opcionais)\n:* ISO 8601 data e hora com segundos fracionados (ignorados), <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (traços, dois pontos e <kbd>Z</kbd> são opcionais)\n:* Formato MediaWiki, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* Formato numérico genérico, <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (fuso horário opcional de <kbd>GMT</kbd>, <kbd>+<var>##</var></kbd> ou <kbd>-<var>##</var></kbd> é ignorado)\n:* Formato EXIF, <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Formato RFC 2822 (o fuso horário pode ser omitido), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Formato RFC 850 (fuso horário Pode ser omitido), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* C ctime format, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* Segundos desde 1970-01-01T00:00:00Z como um inteiro de 1 a 13 dígitos (excluindo <kbd>0</kbd>)\n:* A string <kbd>now</kbd>\n; valor múltiplo alternativo separador\n: Os parâmetros que levam vários valores são normalmente enviados com os valores separados usando o caractere do pipe, por exemplo <kbd>param=value1|value2</kbd> ou <kbd>param=value1%7Cvalue2</kbd>. Se um valor deve conter o caractere de pipe, use U+001F (separador de unidade) como o separador ''and'' prefixa o valor com U+001F, por exemplo, <kbd>param=%1Fvalue1%1Fvalue2</kbd>.",
+       "api-help-templatedparams-header": "Parâmetros da predefinição",
+       "api-help-templatedparams": "Os parâmetros modelados usam-se nos casos em que um módulo da API necessita de um valor para cada valor de um outro parâmetro. Por exemplo, se existisse um módulo da API para encomendar fruta, poderia ter um parâmetro <var>frutas</var> para especificar as frutas que estão a ser encomendadas e um parâmetro modelado <var>quantidade-de-{fruta}</var> para especificar quanto de cada fruta. Um cliente da API que pretenda 1 maçã, 5 bananas e 20 morangos pode então fazer um pedido como <kbd>frutas=maçãs|bananas|morangos&quantidade-de-maçãs=1&quantidade-de-bananas=5&quantidade-de-morangos=20</kbd>.",
        "api-help-param-type-limit": "Tipo: inteiro ou <kbd>max</kbd>",
        "api-help-param-type-integer": "Tipo: {{PLURAL:$1|1=inteiro|2=lista de inteiros}}",
        "api-help-param-type-boolean": "Tipo: boleano ([[Special:ApiHelp/main#main/datatypes|details]])",
        "apierror-templateexpansion-notwikitext": "A expansão da predefinição só é suportada pelo conteúdo do texto wiki. $1 usa o modelo de conteúdo $2.",
        "apierror-timeout": "O servidor não respondeu dentro do tempo esperado.",
        "apierror-toofewexpiries": "{{PLURAL:$1|Foi fornecida $1 data e hora|Foram fornecidas $1 datas e horas}} de expiração quando {{PLURAL:$2|era necessária|eram necessárias}} $2.",
+       "apierror-toomanyvalues": "Muitos valores são fornecidos para o parâmetro <var>$1</var>. O limite é de $2.",
        "apierror-unknownaction": "A ação especificada, <kbd>$1</kbd>, não é reconhecida.",
        "apierror-unknownerror-editpage": "Erro EditPage desconhecido: $1.",
        "apierror-unknownerror-nocode": "Erro desconhecido.",
        "apiwarn-difftohidden": "Não foi possível diferenciar r$1: o conteúdo está oculto.",
        "apiwarn-errorprinterfailed": "Falha na impressora de erro. Repetirá sem parâmetros.",
        "apiwarn-errorprinterfailed-ex": "Falha na impressora de erro (repetirá sem parâmetros): $1",
+       "apiwarn-ignoring-invalid-templated-value": "Ignorando o valor <kbd>$2</kbd> em <var>$1</var> ao processar parâmetros de predefinição.",
        "apiwarn-invalidcategory": "\"$1\" não é uma categoria.",
        "apiwarn-invalidtitle": "\"$1\" não é um título válido.",
        "apiwarn-invalidxmlstylesheetext": "Stylesheet deve ter extensão <code>.xsl</code>.",
        "apiwarn-redirectsandrevids": "A resolução de redirecionamento não pode ser usada em conjunto com o parâmetro <var>revids</var>. Qualquer redirecionamento <var>revids</var> apontando para não foi resolvido.",
        "apiwarn-tokennotallowed": "A ação \"$1\" não é permitida para o usuário atual.",
        "apiwarn-tokens-origin": "Os tokens não podem ser obtidos quando a política de origem não é aplicada.",
-       "apiwarn-toomanyvalues": "Muitos valores são fornecidos para o parâmetro <var>$1</var>. O limite é de $2.",
        "apiwarn-truncatedresult": "Esse resultado foi truncado porque, de outra forma, seria maior do que o limite de $1 bytes.",
        "apiwarn-unclearnowtimestamp": "Passar \"$2\" para o parâmetro timestamp <var>$1</var> está obsoleto. Se, por algum motivo, você precisa especificar explicitamente o tempo atual sem calcular o lado do cliente, use <kbd>now</kbd>.",
        "apiwarn-unrecognizedvalues": "{{PLURAL:$3|Valor não reconhecido para o parâmetro|Valores não reconhecidos para o parâmetro}} <var>$1</var>: $2.",
index 2a81d29..0f159fb 100644 (file)
        "apihelp-query+recentchanges-param-limit": "O número total de mudanças a serem devolvidas.",
        "apihelp-query+recentchanges-param-type": "Os tipos de mudanças a serem mostradas.",
        "apihelp-query+recentchanges-param-toponly": "Listar só as alterações que são a revisão mais recente.",
+       "apihelp-query+recentchanges-param-title": "Filtrar as entradas para produzir só as relacionadas com uma página.",
        "apihelp-query+recentchanges-param-generaterevisions": "Ao ser usado como gerador, gerar identificadores de revisões em vez de títulos. As entradas das mudanças recentes que não tenham identificadores de revisão associados (por exemplo, a maioria das entradas do registo) não geram nada.",
        "apihelp-query+recentchanges-example-simple": "Listar as mudanças recentes.",
        "apihelp-query+recentchanges-example-generator": "Obter informação de página acerca das mudanças recentes não patrulhadas.",
        "api-help-parameters": "{{PLURAL:$1|Parâmetro|Parâmetros}}:",
        "api-help-param-deprecated": "Obsoleto.",
        "api-help-param-required": "Este parâmetro é obrigatório.",
+       "api-help-param-templated": "Este parâmetro é um [[Special:ApiHelp/main#main/templatedparams|parâmetro modelado]]. Ao fazer o pedido, $2.",
+       "api-help-param-templated-var-first": "<var>&#x7B;$1&#x7D;</var> no nome do parâmetro deve ser substituído com os valores de <var>$2</var>",
+       "api-help-param-templated-var": "<var>&#x7B;$1&#x7D;</var> com valores de <var>$2</var>",
        "api-help-datatypes-header": "Tipo de dados",
        "api-help-datatypes": "O formato de entrada para o MediaWiki deve ser UTF-8, normalizado de acordo com a norma NFC. O MediaWiki pode converter outros tipos de entrada, mas esta conversão pode originar a falha de algumas operações (tais como as [[Special:ApiHelp/edit|edições]] com verificações MD5).\n\nAlguns tipos de parâmetros nos pedidos à API necessitam de mais explicações:\n;boolean\n:Os parâmetros booleanos funcionam como as caixas de seleção HTML: se o parâmetro for especificado, independentemente do seu valor, é considerado verdadeiro. Para um valor falso, omitir o parâmetro completo.\n;timestamp\n:As datas e horas podem ser especificadas em vários formatos. É recomendado o formato ISO 8601. Todas as horas estão em UTC, qualquer inclusão do fuso horário é ignorada.\n:* Data e hora ISO 8601, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (pontuação e <kbd>Z</kbd> são opcionais)\n:* Data e hora ISO 8601 com segundos fracionários (estes são ignorados), <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (traços, dois pontos e <kbd>Z</kbd> são opcionais)\n:* Formato do MediaWiki, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* Formato numérico genérico, <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (fuso horário opcional <kbd>GMT</kbd>, <kbd>+<var>##</var></kbd>, ou <kbd>-<var>##</var></kbd> são ignorados)\n:* Formato EXIF, <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:*Formato RFC 2822 (o fuso horário pode ser omitido), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Formato RFC 850 (o fuso horário pode ser omitido), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Formato C ctime, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* Segundos desde 1970-01-01T00:00:00Z como um inteiro de 1 a 13 algarismos (excluindo <kbd>0</kbd>)\n:* O texto <kbd>now</kbd>\n;separador alternativo de valores múltiplos\n:Os parâmetros que aceitam vários valores são normalmente fornecidos com os valores separados por uma barra vertical (''pipe''), por exemplo <kbd>parâmetro=valor1|valor2</kbd> ou <kbd>parâmetro=valor1%7Cvalor2</kbd>. Se um valor contém a barra vertical, use como separador o U+001F (Separador de Unidades) ''e'' prefixe o valor com U+001F, isto é, <kbd>parâmetro=%1Fvalor1%1Fvalor2</kbd>.",
+       "api-help-templatedparams-header": "Parâmetros modelados",
+       "api-help-templatedparams": "Os parâmetros modelados usam-se nos casos em que um módulo da API necessita de um valor para cada valor de um outro parâmetro. Por exemplo, se existisse um módulo da API para encomendar fruta, poderia ter um parâmetro <var>frutas</var> para especificar as frutas que estão a ser encomendadas e um parâmetro modelado <var>quantidade-de-{fruta}</var> para especificar quanto de cada fruta. Um cliente da API que pretenda 1 maçã, 5 bananas e 20 morangos pode então fazer um pedido como <kbd>frutas=maçãs|bananas|morangos&quantidade-de-maçãs=1&quantidade-de-bananas=5&quantidade-de-morangos=20</kbd>.",
        "api-help-param-type-limit": "Tipo: inteiro ou <kbd>max</kbd>",
        "api-help-param-type-integer": "Tipo: {{PLURAL:$1|1=inteiro|2=lista de números inteiros}}",
        "api-help-param-type-boolean": "Tipo: booleano ([[Special:ApiHelp/main#main/datatypes|detalhes]])",
        "apierror-templateexpansion-notwikitext": "A expansão de predefinições só é suportada para conteúdo em texto wiki. A página $1 usa o modelo de conteúdo $2.",
        "apierror-timeout": "O servidor não respondeu no prazo esperado.",
        "apierror-toofewexpiries": "{{PLURAL:$1|Foi fornecida $1 data e hora|Foram fornecidas $1 datas e horas}} de expiração quando {{PLURAL:$2|era necessária|eram necessárias}} $2.",
+       "apierror-toomanyvalues": "Foram fornecidos demasiados valores para o parâmetro <var>$1</var>. O limite é $2.",
        "apierror-unknownaction": "A operação especificada, <kbd>$1</kbd>, não é reconhecida.",
        "apierror-unknownerror-editpage": "Erro EditPage desconhecido: $1.",
        "apierror-unknownerror-nocode": "Erro desconhecido.",
        "apiwarn-difftohidden": "Não foi possível criar uma lista das diferenças em relação à r$1: o conteúdo está ocultado.",
        "apiwarn-errorprinterfailed": "A impressora de erros falhou. Será feita nova tentativa sem parâmetros.",
        "apiwarn-errorprinterfailed-ex": "A impressora de erros falhou (será feita nova tentativa sem parâmetros): $1",
+       "apiwarn-ignoring-invalid-templated-value": "A ignorar o valor <kbd>$2</kbd> em <var>$1</var> ao processar parâmetros modelados.",
        "apiwarn-invalidcategory": "\"$1\" não é uma categoria.",
        "apiwarn-invalidtitle": "\"$1\" não é um título válido.",
        "apiwarn-invalidxmlstylesheetext": "Uma folha de estilos deve ter a extensão <code>.xsl</code>.",
        "apiwarn-redirectsandrevids": "Resolução de redirecionamentos não pode ser usada em conjunto com o parâmetro <var>revids</var>. Quaisquer redirecionamentos para os quais <var>revids</var> aponta não foram resolvidos.",
        "apiwarn-tokennotallowed": "A operação \"$1\" não é permitida para o utilizador atual.",
        "apiwarn-tokens-origin": "Não é possível obter chaves quando a norma da mesma origem não é aplicada.",
-       "apiwarn-toomanyvalues": "Foram fornecidos demasiados valores para o parâmetro <var>$1</var>. O limite é $2.",
        "apiwarn-truncatedresult": "Este resultado foi truncado porque ultrapassaria o limite de $1 bytes.",
        "apiwarn-unclearnowtimestamp": "A passagem de \"$2\" no parâmetro de data e hora <var>$1</var> foi tornada obsoleta. Se, por qualquer razão, precisa de especificar de forma explícita a hora atual sem a calcular no lado do cliente, use <kbd>now</kbd>.",
        "apiwarn-unrecognizedvalues": "{{PLURAL:$3|Valor não reconhecido|Valores não reconhecidos}} para o parâmetro <var>$1</var>: $2.",
index 594bf8e..3fcf499 100644 (file)
        "apihelp-query+recentchanges-param-limit": "{{doc-apihelp-param|query+recentchanges|limit}}",
        "apihelp-query+recentchanges-param-type": "{{doc-apihelp-param|query+recentchanges|type}}",
        "apihelp-query+recentchanges-param-toponly": "{{doc-apihelp-param|query+recentchanges|toponly}}",
+       "apihelp-query+recentchanges-param-title": "{{doc-apihelp-param|query+recentchanges|title}}",
        "apihelp-query+recentchanges-param-generaterevisions": "{{doc-apihelp-param|query+recentchanges|generaterevisions}}",
        "apihelp-query+recentchanges-example-simple": "{{doc-apihelp-example|query+recentchanges}}",
        "apihelp-query+recentchanges-example-generator": "{{doc-apihelp-example|query+recentchanges}}",
        "api-help-parameters": "Label for the API help parameters section\n\nParameters:\n* $1 - Number of parameters to be displayed\n{{Identical|Parameter}}",
        "api-help-param-deprecated": "Displayed in the API help for any deprecated parameter\n{{Identical|Deprecated}}",
        "api-help-param-required": "Displayed in the API help for any required parameter",
+       "api-help-param-templated": "Displayed in the API help for any templated parameter.\n\nParameters:\n* $1 - Count of template variables in the parameter name.\n* $2 - A list, composed using {{msg-mw|comma-separator}} and {{msg-mw|and}}, of the template variables in the parameter name. The first is formatted using {{msg-mw|api-help-param-templated-var-first|notext=1}} and the rest use {{msg-mw|api-help-param-templated-var|notext=1}}.\n\nSee also:\n* {{msg-mw|api-help-param-templated-var-first}}\n* {{msg-mw|api-help-param-templated-var}}",
+       "api-help-param-templated-var-first": "Used with {{msg-mw|api-help-param-templated|notext=1}} to display templated parameter replacement variables. See that message for context.\n\nParameters:\n* $1 - Variable.\n* $2 - Parameter from which values are taken.\n\nSee also:\n* {{msg-mw|api-help-param-templated}}\n* {{msg-mw|api-help-param-templated-var}}",
+       "api-help-param-templated-var": "Used with {{msg-mw|api-help-param-templated|notext=1}} to display templated parameter replacement variables. See that message for context.\n\nParameters:\n* $1 - Variable.\n* $2 - Parameter from which values are taken.\n\nSee also:\n* {{msg-mw|api-help-param-templated}}\n* {{msg-mw|api-help-param-templated-var-first}}",
        "api-help-datatypes-header": "Header for the data type section in the API help output",
        "api-help-datatypes": "{{technical}} {{doc-important|Do not translate or reformat dates inside <nowiki><kbd></kbd></nowiki> or <nowiki><var></var></nowiki> tags}} Documentation of certain API data types\nSee also:\n* [[Special:PrefixIndex/MediaWiki:api-help-param-type]]",
+       "api-help-templatedparams-header": "Header for the \"templated parameters\" section in the API help output.",
+       "api-help-templatedparams": "{{technical}} {{doc-important|Unlike in other API messages, feel free to localize the words \"fruit\", \"fruits\", \"quantity\", \"apples\", \"bananas\", and \"strawberries\" in this message even when inside <nowiki><kbd></kbd></nowiki> or <nowiki><var></var></nowiki> tags. Do not change the punctuation, only the words.}} Documentation for the \"templated parameters\" feature.",
        "api-help-param-type-limit": "{{technical}} {{doc-important|Do not translate text inside &lt;kbd&gt; tags}} Used to indicate that a parameter is a \"limit\" type. Parameters:\n* $1 - Always 1.\nSee also:\n* {{msg-mw|api-help-datatypes}}\n* [[Special:PrefixIndex/MediaWiki:api-help-param-type]]",
        "api-help-param-type-integer": "{{technical}} Used to indicate that a parameter is an integer or list of integers. Parameters:\n* $1 - 1 if the parameter takes one value, 2 if the parameter takes a list of values.\nSee also:\n* {{msg-mw|api-help-datatypes}}\n* [[Special:PrefixIndex/MediaWiki:api-help-param-type]]",
        "api-help-param-type-boolean": "{{technical}} {{doc-important|Do not translate <code>Special:ApiHelp</code> in this message.}} Used to indicate that a parameter is a boolean. Parameters:\n* $1 - Always 1.\nSee also:\n* {{msg-mw|api-help-datatypes}}\n* [[Special:PrefixIndex/MediaWiki:api-help-param-type]]",
        "apierror-templateexpansion-notwikitext": "{{doc-apierror}}\n\nParameters:\n* $1 - Page title.\n* $2 - Content model.",
        "apierror-timeout": "{{doc-apierror}}\nAPI error message that can be used for client side localisation of API errors.",
        "apierror-toofewexpiries": "{{doc-apierror}}\n\nParameters:\n* $1 - Number provided.\n* $2 - Number needed.",
+       "apierror-toomanyvalues": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter name.\n* $2 - Maximum number of values allowed.",
        "apierror-unknownaction": "{{doc-apierror}}\n\nParameters:\n* $1 - Action provided.",
        "apierror-unknownerror-editpage": "{{doc-apierror}}\n\nParameters:\n* $1 - Error code (an integer).",
        "apierror-unknownerror-nocode": "{{doc-apierror}}",
        "apiwarn-difftohidden": "{{doc-apierror}}\n\nParameters:\n* $1 - Revision ID number.\n\n\"r\" is short for \"revision\". You may translate it.",
        "apiwarn-errorprinterfailed": "{{doc-apierror}}",
        "apiwarn-errorprinterfailed-ex": "{{doc-apierror}}\n\nParameters:\n* $1 - Exception message, which may already end in punctuation. Probably in English.",
+       "apiwarn-ignoring-invalid-templated-value": "{{doc-apierror}}\n\nParameters:\n* $1 - Target parameter having a bad value.\n* $2 - The bad value being ignored.",
        "apiwarn-invalidcategory": "{{doc-apierror}}\n\nParameters:\n* $1 - Supplied category name.",
        "apiwarn-invalidtitle": "{{doc-apierror}}\n\nParameters:\n* $1 - Supplied title.",
        "apiwarn-invalidxmlstylesheetext": "{{doc-apierror}}",
        "apiwarn-redirectsandrevids": "{{doc-apierror}}",
        "apiwarn-tokennotallowed": "{{doc-apierror}}\n\nParameters:\n* $1 - Token type being requested, typically named after the action requiring the token.",
        "apiwarn-tokens-origin": "{{doc-apierror}}",
-       "apiwarn-toomanyvalues": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter name.\n* $2 - Maximum number of values allowed.",
        "apiwarn-truncatedresult": "{{doc-apierror}}\n\nParameters:\n* $1 - Size limit in bytes.",
        "apiwarn-unclearnowtimestamp": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter name.\n* $2 - Supplied value.",
        "apiwarn-unrecognizedvalues": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter name.\n* $2 - List of unknown values supplied.\n* $3 - Number of unknown values.",
index 7c8c169..91aac43 100644 (file)
@@ -30,7 +30,9 @@
                        "Jack who built the house",
                        "Mouse21",
                        "Happy13241",
-                       "Ole Yves"
+                       "Ole Yves",
+                       "AttemptToCallNil",
+                       "Movses"
                ]
        },
        "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Документация]]\n* [[mw:Special:MyLanguage/API:FAQ|ЧаВО]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Почтовая рассылка]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Новости API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Ошибки и запросы]\n</div>\n<strong>Статус:</strong> MediaWiki API — зрелый и стабильный интерфейс, активно поддерживаемый и улучшаемый. Мы стараемся избегать ломающих изменений, однако изредка они могут быть необходимы. Подпишитесь на [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ почтовую рассылку mediawiki-api-announce], чтобы быть в курсе обновлений.\n\n<strong>Ошибочные запросы:</strong> Если API получает запрос с ошибкой, вернётся заголовок HTTP с ключом «MediaWiki-API-Error», после чего значение заголовка и код ошибки будут отправлены обратно и установлены в то же значение. Более подробную информацию см. [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Ошибки и предупреждения]].\n\n<p class=\"mw-apisandbox-link\"><strong>Тестирование:</strong> для удобства тестирования API-запросов, см. [[Special:ApiSandbox]].</p>",
@@ -45,7 +47,7 @@
        "apihelp-main-param-servedby": "Включить в результаты имя хоста, обработавшего запрос.",
        "apihelp-main-param-curtimestamp": "Включить в результат временную метку.",
        "apihelp-main-param-responselanginfo": "Включить языки, использованные для <var>uselang</var> и <var>errorlang</var>, в результат.",
-       "apihelp-main-param-origin": "Ð\9fÑ\80и Ð¾Ð±Ñ\80аÑ\89ении Ðº API Ñ\81 Ð¸Ñ\81полÑ\8cзованием ÐºÑ\80оÑ\81Ñ\81-доменного AJAX-запÑ\80оÑ\81а (CORS), Ð·Ð°Ð´Ð°Ð¹Ñ\82е Ð¿Ð°Ñ\80амеÑ\82Ñ\80Ñ\83 Ð·Ð½Ð°Ñ\87ение Ð¸Ñ\81Ñ\85одного Ð´Ð¾Ð¼ÐµÐ½Ð°. Ð\9eн должен быть включён в любой предварительный запрос и таким образом должен быть частью URI-запроса (не тела POST).\n\nДля аутентифицированных запросов он должен точно соответствовать одному из источников в заголовке <code>Origin</code>, так что он должен быть задан наподобие <kbd>https://ru.wikipedia.org</kbd> или <kbd>https://meta.wikimedia.org</kbd>. Если параметр не соответствует заголовку <code>Origin</code>, будет возвращён ответ с кодом ошибки 403. Если параметр соответствует заголовку <code>Origin</code>, и источник находится в белом списке, будут установлены заголовки <code>Access-Control-Allow-Origin</code> и <code>Access-Control-Allow-Credentials</code>.\n\nДля неаутентифицированных запросов укажите значение <kbd>*</kbd>. В результате заголовок <code>Access-Control-Allow-Origin</code> будет установлен, но <code>Access-Control-Allow-Credentials</code> примет значение <code>false</code> и все пользовательские данные будут ограничены.",
+       "apihelp-main-param-origin": "Ð\9fÑ\80и Ð¾Ð±Ñ\80аÑ\89ении Ðº API Ñ\81 Ð¸Ñ\81полÑ\8cзованием ÐºÑ\80оÑ\81Ñ\81-доменного AJAX-запÑ\80оÑ\81а (CORS), Ð·Ð°Ð´Ð°Ð¹Ñ\82е Ð¿Ð°Ñ\80амеÑ\82Ñ\80Ñ\83 Ð·Ð½Ð°Ñ\87ение Ð¸Ñ\81Ñ\85одного Ð´Ð¾Ð¼ÐµÐ½Ð°. Ð­Ñ\82оÑ\82 Ð¿Ð°Ñ\80амеÑ\82Ñ\80 должен быть включён в любой предварительный запрос и таким образом должен быть частью URI-запроса (не тела POST).\n\nДля аутентифицированных запросов он должен точно соответствовать одному из источников в заголовке <code>Origin</code>, так что он должен быть задан наподобие <kbd>https://ru.wikipedia.org</kbd> или <kbd>https://meta.wikimedia.org</kbd>. Если параметр не соответствует заголовку <code>Origin</code>, будет возвращён ответ с кодом ошибки 403. Если параметр соответствует заголовку <code>Origin</code>, и источник находится в белом списке, будут установлены заголовки <code>Access-Control-Allow-Origin</code> и <code>Access-Control-Allow-Credentials</code>.\n\nДля неаутентифицированных запросов укажите значение <kbd>*</kbd>. В результате заголовок <code>Access-Control-Allow-Origin</code> будет установлен, но <code>Access-Control-Allow-Credentials</code> примет значение <code>false</code> и все пользовательские данные будут ограничены.",
        "apihelp-main-param-uselang": "Язык, используемый для перевода сообщений. Запрос <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> с <kbd>siprop=languages</kbd> возвращает список кодов языков; укажите <kbd>user</kbd>, чтобы использовать текущие языковые настройки участника, или <kbd>content</kbd> для использования основного языка этой вики.",
        "apihelp-main-param-errorformat": "Формат, используемый для вывода текста предупреждений и ошибок.\n; plaintext: Вики-текст с удалёнными HTML-тегами и замещёнными мнемониками.\n; wikitext: Нераспарсенный вики-текст.\n; html: HTML.\n; raw: Ключ сообщения и параметры.\n; none: Без текстового вывода, только коды ошибок.\n; bc: Формат, используемый до MediaWiki 1.29. <var>errorlang</var> и <var>errorsuselocal</var> игнорируются.",
        "apihelp-main-param-errorlang": "Язык, используемый для вывода предупреждений и сообщений об ошибках. Запрос <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> с <kbd>siprop=languages</kbd> возвращает список кодов языков; укажите <kbd>content</kbd> для использования основного языка этой вики, или <kbd>uselang</kbd> для использования того же значения, что и в параметре <var>uselang</var>.",
        "apihelp-block-summary": "Блокировка участника.",
        "apihelp-block-param-user": "Имя участника, IP-адрес или диапазон IP-адресов, которые вы хотите заблокировать. Нельзя использовать вместе с <var>$1userid</var>",
        "apihelp-block-param-userid": "Идентификатор блокируемого участника. Нельзя использовать одновременно с <var>$1user</var>.",
-       "apihelp-block-param-expiry": "Время истечения срока действия. Может быть относительными (например, <kbd>5 months</kbd> или <kbd>2 weeks</kbd>) или абсолютными (например, <kbd>2014-09-18T12:34:56Z</kbd>). Если задано <kbd>infinite</kbd>, <kbd>indefinite</kbd>, или <kbd>never</kbd>, блок никогда не истечёт.",
+       "apihelp-block-param-expiry": "Время истечения срока действия. Может быть относительным (например, <kbd>5 months</kbd> или <kbd>2 weeks</kbd>) или абсолютным (например, <kbd>2014-09-18T12:34:56Z</kbd>). Если задано <kbd>infinite</kbd>, <kbd>indefinite</kbd> или <kbd>never</kbd>, блокировка никогда не истечёт.",
        "apihelp-block-param-reason": "Причина блокировки.",
        "apihelp-block-param-anononly": "Заблокировать только анонимных участников (т. е. запретить анонимные правки для этого IP-адреса).",
        "apihelp-block-param-nocreate": "Запретить создание учётных записей.",
        "apihelp-block-param-autoblock": "Автоматически блокировать последний использованный IP-адрес и все последующие, с которых будут совершаться попытки авторизации.",
        "apihelp-block-param-noemail": "Запретить участнику отправлять электронную почту через интерфейс вики. (Требуется право <code>blockemail</code>).",
        "apihelp-block-param-hidename": "Скрыть имя участника из журнала блокировок. (Требуется право <code>hideuser</code>).",
-       "apihelp-block-param-allowusertalk": "Ð\9fозволÑ\8fеÑ\82 Ñ\83Ñ\87аÑ\81Ñ\82никам Ñ\80едакÑ\82иÑ\80оваÑ\82Ñ\8c Ð¸Ñ\85 Ñ\81обÑ\81Ñ\82веннÑ\8bе Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\8b обсуждения (зависит от <var>[[mw:Special:MyLanguage/Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
+       "apihelp-block-param-allowusertalk": "РазÑ\80еÑ\88иÑ\82Ñ\8c Ñ\83Ñ\87аÑ\81Ñ\82никÑ\83 Ñ\80едакÑ\82иÑ\80оваÑ\82Ñ\8c Ñ\81воÑ\8e Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 обсуждения (зависит от <var>[[mw:Special:MyLanguage/Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
        "apihelp-block-param-reblock": "Если участник уже заблокирован, перезаписать существующую блокировку.",
-       "apihelp-block-param-watchuser": "Следить за страницей участника или IP-участника и страницей обсуждения.",
+       "apihelp-block-param-watchuser": "Следить за страницей участника и соответствующей страницей обсуждения, принадлежащей участнику или IP-адресу.",
        "apihelp-block-param-tags": "Изменить метки записи в журнале блокировок.",
-       "apihelp-block-example-ip-simple": "Заблокировать IP-адрес <kbd>192.0.2.5</kbd> на три дня с причиной <kbd>First strike</kbd>.",
+       "apihelp-block-example-ip-simple": "Заблокировать IP-адрес <kbd>192.0.2.5</kbd> на три дня по причине <kbd>First strike</kbd>.",
        "apihelp-block-example-user-complex": "Бессрочно заблокировать участника <kbd>Vandal</kbd> по причине <kbd>Vandalism</kbd> и предотвратить создание новых аккаунтов и отправку электронной почты.",
        "apihelp-changeauthenticationdata-summary": "Смена параметров аутентификации для текущего участника.",
        "apihelp-changeauthenticationdata-example-password": "Попытаться изменить текущий пароль участника на <kbd>ExamplePassword</kbd>.",
        "apihelp-clearhasmsg-example-1": "Очистить флаг <code>hasmsg</code> для текущего участника.",
        "apihelp-clientlogin-summary": "Вход в вики с помощью интерактивного потока.",
        "apihelp-clientlogin-example-login": "Начать вход в вики в качестве участника <kbd>Example</kbd> с паролем <kbd>ExamplePassword</kbd>.",
-       "apihelp-clientlogin-example-login2": "Продолжить вход после ответа <samp>UI</samp> для двухфакторной авторизации, предоставив <kbd>987654</kbd> в качестве токена <var>OATHToken</var>.",
+       "apihelp-clientlogin-example-login2": "Продолжить вход после ответа <samp>UI</samp> для двухфакторной аутентификации, предоставив <kbd>987654</kbd> в качестве токена <var>OATHToken</var>.",
        "apihelp-compare-summary": "Получение разницы между двумя страницами.",
        "apihelp-compare-extended-description": "Номер версии, заголовок страницы, её идентификатор, текст, или относительная сноска должна быть задана как для «from», так и для «to».",
        "apihelp-compare-param-fromtitle": "Заголовок первой сравниваемой страницы.",
        "apihelp-compare-param-fromid": "Идентификатор первой сравниваемой страницы.",
        "apihelp-compare-param-fromrev": "Первая сравниваемая версия.",
        "apihelp-compare-param-fromtext": "Используйте этот текст вместо содержимого версии, заданной <var>fromtitle</var>, <var>fromid</var> или <var>fromrev</var>.",
-       "apihelp-compare-param-fromsection": "Использовать только указанную секцию из содержимого 'from'.",
+       "apihelp-compare-param-fromsection": "Использовать только указанную секцию из содержимого «from».",
        "apihelp-compare-param-frompst": "Выполнить преобразование перед записью правки (PST) над <var>fromtext</var>.",
        "apihelp-compare-param-fromcontentmodel": "Модель содержимого <var>fromtext</var>. Если не задана, будет угадана по другим параметрам.",
        "apihelp-compare-param-fromcontentformat": "Формат сериализации содержимого <var>fromtext</var>.",
        "apihelp-compare-param-totitle": "Заголовок второй сравниваемой страницы.",
        "apihelp-compare-param-toid": "Идентификатор второй сравниваемой страницы.",
        "apihelp-compare-param-torev": "Вторая сравниваемая версия.",
-       "apihelp-compare-param-torelative": "Использовать версию, относящуюся к определённой<var>fromtitle</var>, <var>fromid</var> или <var>fromrev</var> Все другие опции 'to' будут проигнорированы.",
+       "apihelp-compare-param-torelative": "Использовать версию, относящуюся к определённой <var>fromtitle</var>, <var>fromid</var> или <var>fromrev</var>. Все другие опции 'to' будут проигнорированы.",
        "apihelp-compare-param-totext": "Используйте этот текст вместо содержимого версии, заданной <var>totitle</var>, <var>toid</var> или <var>torev</var>.",
-       "apihelp-compare-param-tosection": "Использовать только указанную секцию из содержимого 'to'.",
+       "apihelp-compare-param-tosection": "Использовать только указанную секцию из содержимого «to».",
        "apihelp-compare-param-topst": "Выполнить преобразование перед записью правки (PST) над <var>totext</var>.",
        "apihelp-compare-param-tocontentmodel": "Модель содержимого <var>totext</var>. Если не задана, будет угадана по другим параметрам.",
        "apihelp-compare-param-tocontentformat": "Формат сериализации содержимого <var>totext</var>.",
        "apihelp-compare-param-prop": "Какую информацию получить.",
-       "apihelp-compare-paramvalue-prop-diff": "HTML разницы.",
-       "apihelp-compare-paramvalue-prop-diffsize": "Размер HTML разницы в байтах.",
-       "apihelp-compare-paramvalue-prop-rel": "Идентификаторы предыдущей к 'from' и следующей за 'to' версий.",
-       "apihelp-compare-paramvalue-prop-ids": "Идентификаторы страниц и версий 'from' и 'to'.",
-       "apihelp-compare-paramvalue-prop-title": "Названия страниц для версий 'from' и 'to'.",
-       "apihelp-compare-paramvalue-prop-user": "Имя и идентификатор участника для версий 'from' и 'to'.",
-       "apihelp-compare-paramvalue-prop-comment": "Описания правок для версий 'from' и 'to'.",
-       "apihelp-compare-paramvalue-prop-parsedcomment": "Распарсенные описания правок для версий 'from' и 'to'.",
-       "apihelp-compare-paramvalue-prop-size": "Размер версий 'from' и 'to'.",
+       "apihelp-compare-paramvalue-prop-diff": "HTML-код разницы.",
+       "apihelp-compare-paramvalue-prop-diffsize": "Размер HTML-кода разницы в байтах.",
+       "apihelp-compare-paramvalue-prop-rel": "Идентификаторы предыдущей к «from» и следующей за «to» версий.",
+       "apihelp-compare-paramvalue-prop-ids": "Идентификаторы страниц и версий «from» и «to».",
+       "apihelp-compare-paramvalue-prop-title": "Названия страниц для версий «from» и «to».",
+       "apihelp-compare-paramvalue-prop-user": "Имя и идентификатор участника для версий «from» и «to».",
+       "apihelp-compare-paramvalue-prop-comment": "Описания правок для версий «from» и «to».",
+       "apihelp-compare-paramvalue-prop-parsedcomment": "Распарсенные описания правок для версий «from» и «to».",
+       "apihelp-compare-paramvalue-prop-size": "Размер версий «from» и «to».",
        "apihelp-compare-example-1": "Создать разницу между версиями 1 и 2.",
        "apihelp-createaccount-summary": "Создание новой учётной записи.",
        "apihelp-createaccount-param-preservestate": "Если запрос <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> возвращает true для <samp>hasprimarypreservedstate</samp>, то запросы, отмеченные как <samp>primary-required</samp>, должны быть пропущены. Если запрос возвращает непустое значение поля <samp>preservedusername</samp>, то это значение должно быть использовано в параметре <samp>username</var>.",
        "apihelp-createaccount-example-mail": "Создать участника <kbd>testmailuser</kbd> и прислать на электронную почту случайно сгенерированный пароль.",
        "apihelp-cspreport-summary": "Используется браузерами, чтобы сообщать о нарушениях политики безопасности (CSP). Этот модуль никогда не должен использоваться, за исключением случаев автоматического использования совместимыми с CSP браузерами.",
        "apihelp-cspreport-param-reportonly": "Отметить как доклад от политики мониторинга, не от принудительной политики",
-       "apihelp-cspreport-param-source": "Что сгенерировало заголовок SCP, вызвавший этот доклад",
+       "apihelp-cspreport-param-source": "Что сгенерировало заголовок CSP, вызвавший этот доклад",
        "apihelp-delete-summary": "Удаление страницы.",
        "apihelp-delete-param-title": "Заголовок удаляемой страницы. Нельзя использовать одновременно с <var>$1pageid</var>.",
        "apihelp-delete-param-pageid": "Идентификатор удаляемой страницы. Нельзя использовать одновременно с <var>$1title</var>.",
        "apihelp-delete-param-unwatch": "Удалить страницу из списка наблюдения текущего участника.",
        "apihelp-delete-param-oldimage": "Название старого удаляемого изображения, предоставляемое [[Special:ApiHelp/query+imageinfo|action=query&prop=imageinfo&iiprop=archivename]].",
        "apihelp-delete-example-simple": "Удалить <kbd>Main Page</kbd>.",
-       "apihelp-delete-example-reason": "Удалить <kbd>Main Page</kbd> с причиной <kbd>Preparing for move</kbd>.",
-       "apihelp-disabled-summary": "Этот модуль был отключен.",
+       "apihelp-delete-example-reason": "Удалить <kbd>Main Page</kbd> по причине <kbd>Preparing for move</kbd>.",
+       "apihelp-disabled-summary": "Этот модуль был отключён.",
        "apihelp-edit-summary": "Создание и редактирование страниц.",
        "apihelp-edit-param-title": "Название редактируемой страницы. Нельзя использовать одновременно с <var>$1pageid</var>.",
        "apihelp-edit-param-pageid": "Идентификатор редактируемой страницы. Нельзя использовать одновременно с <var>$1title</var>.",
        "apihelp-edit-param-minor": "Малая правка.",
        "apihelp-edit-param-notminor": "Не малая правка.",
        "apihelp-edit-param-bot": "Пометить правку как сделанную ботом.",
-       "apihelp-edit-param-basetimestamp": "Ð\92Ñ\80еменнаÑ\8f Ð¼ÐµÑ\82ка редактируемой версии, используется для обнаружения конфликтов редактирования. Может быть получена посредством [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]].",
+       "apihelp-edit-param-basetimestamp": "Ð\9cеÑ\82ка Ð²Ñ\80емени редактируемой версии, используется для обнаружения конфликтов редактирования. Может быть получена посредством [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]].",
        "apihelp-edit-param-starttimestamp": "Метка времени начала редактирования, используется для обнаружения конфликтов редактирования. Необходимое значение может быть получено с помощью <var>[[Special:ApiHelp/main|curtimestamp]]</var> в начале редактирования (то есть, после загрузки содержимого редактируемой страницы).",
        "apihelp-edit-param-recreate": "Игнорировать предупреждение о том, что страница была удалена во время редактирования.",
        "apihelp-edit-param-createonly": "Не редактировать страницу, если она уже существует.",
        "apihelp-edit-param-watch": "Добавить страницу в список наблюдения текущего участника.",
        "apihelp-edit-param-unwatch": "Удалить страницу из списка наблюдения текущего участника.",
        "apihelp-edit-param-watchlist": "Безусловно добавить или удалить страницу из списка наблюдения текущего участника, использовать настройки или не менять наблюдение.",
-       "apihelp-edit-param-md5": "MD5-хеш параметра $1text, или конкатенации параметров $1prependtext и $1apendtext. Если задан, правка не будет выполнена, если хеш некорректен.",
+       "apihelp-edit-param-md5": "MD5-хеш параметра $1text, или конкатенации параметров $1prependtext и $1apendtext. Если задан, правка не будет выполнена при несовпадении хеша.",
        "apihelp-edit-param-prependtext": "Добавить этот текст в начало страницы. Переопределяет $1text.",
        "apihelp-edit-param-appendtext": "Добавить этот текст в конец страницы. Переопределяет $text.\n\nДля создания нового раздела, используйте $1section=new, а не этот параметр.",
        "apihelp-edit-param-undo": "Отменить это изменение. Переопределяет $text, $1prependtext и $1appendtext.",
        "apihelp-expandtemplates-paramvalue-prop-volatile": "Является ли вывод нестабильным и следует ли отказаться от его повторного использования где-либо на странице.",
        "apihelp-expandtemplates-paramvalue-prop-ttl": "Максимальное время, по прошествии которого кэш результата должен быть признан недействительным.",
        "apihelp-expandtemplates-paramvalue-prop-modules": "Любые модули ResourceLoader, запрашиваемые функциями парсера на добавление в результат. Одновременно с <kbd>modules</kbd> должен быть запрошен либо <kbd>jsconfigvars</kbd>, либо <kbd>encodedjsconfigvars</kbd>.",
-       "apihelp-expandtemplates-paramvalue-prop-jsconfigvars": "Возвращает переменные JavaScript с данными настроек для этой страницы",
-       "apihelp-expandtemplates-paramvalue-prop-encodedjsconfigvars": "Возвращает переменные JavaScript с данными настроек для этой страницы в виде JSON-строки.",
-       "apihelp-expandtemplates-paramvalue-prop-parsetree": "Дерево парсинга XML входных данных.",
+       "apihelp-expandtemplates-paramvalue-prop-jsconfigvars": "Возвращает переменные конфигурации JavaScript, свойственные именно этой странице.",
+       "apihelp-expandtemplates-paramvalue-prop-encodedjsconfigvars": "Возвращает переменные конфигурации JavaScript, свойственные именно этой странице, в виде JSON-строки.",
+       "apihelp-expandtemplates-paramvalue-prop-parsetree": "Дерево синтаксического разбора XML входных данных.",
        "apihelp-expandtemplates-param-includecomments": "Нужно ли включать комментарии HTML в результат.",
-       "apihelp-expandtemplates-param-generatexml": "Создать дерево парсинга XML (заменено $1prop=parsetree).",
+       "apihelp-expandtemplates-param-generatexml": "Создать дерево синтаксического разбора XML (заменено $1prop=parsetree).",
        "apihelp-expandtemplates-example-simple": "Развернуть вики-текст <kbd><nowiki>{{Project:Sandbox}}</nowiki></kbd>.",
        "apihelp-feedcontributions-summary": "Возвращает ленту с вкладом участников.",
        "apihelp-feedcontributions-param-feedformat": "Формат ленты.",
        "apihelp-feedrecentchanges-param-associated": "Включить связанное (обсуждения или основное) пространство имён.",
        "apihelp-feedrecentchanges-param-days": "Сколькими днями ограничить результат.",
        "apihelp-feedrecentchanges-param-limit": "Максимальное число возвращаемых результатов.",
-       "apihelp-feedrecentchanges-param-from": "Показать изменения с тех пор.",
+       "apihelp-feedrecentchanges-param-from": "Показать изменения, сделанные после этого момента.",
        "apihelp-feedrecentchanges-param-hideminor": "Скрыть малые правки.",
        "apihelp-feedrecentchanges-param-hidebots": "Скрыть правки ботов.",
        "apihelp-feedrecentchanges-param-hideanons": "Скрыть правки анонимных участников.",
        "apihelp-imagerotate-example-simple": "Повернуть <kbd>File:Example.png</kbd> на <kbd>90</kbd> градусов.",
        "apihelp-imagerotate-example-generator": "Повернуть все изображения в <kbd>Category:Flip</kbd> на <kbd>180</kbd> градусов.",
        "apihelp-import-summary": "Импорт страницы из другой вики или XML-файла.",
-       "apihelp-import-extended-description": "Обратите внимание, что HTTP POST-запрос должен быть осуществлён как загрузка файла (то есть, с использованием многотомных данных) при отправки файла через параметр <var>xml</var>.",
+       "apihelp-import-extended-description": "Обратите внимание, что HTTP POST-запрос должен быть осуществлён как загрузка файла (то есть с использованием многотомных данных <code>multipart/form-data</code>) при отправке файла через параметр <var>xml</var>.",
        "apihelp-import-param-summary": "Описание записи журнала импорта.",
        "apihelp-import-param-xml": "Загруженный XML-файл.",
        "apihelp-import-param-interwikiprefix": "Для загруженных импортов: префикс интервики для неизвестных имён участников (а также известных, если задан <var>$1assignknownusers</var>).",
        "apihelp-import-param-templates": "Для импорта из других вики: также импортировать все включённые шаблоны.",
        "apihelp-import-param-namespace": "Импортировать в это пространство имён. Не может быть использовано одновременно с <var>$1rootpage</var>.",
        "apihelp-import-param-rootpage": "Импортировать в качестве подстраницы данной страницы. Не может быть использовано одновременно с <var>$1namespace</var>.",
-       "apihelp-import-param-tags": "Ð\98змениÑ\82Ñ\8c Ð¼ÐµÑ\82ки Ð·Ð°Ð¿Ð¸Ñ\81и Ð² Ð¶Ñ\83Ñ\80нале Ð¸Ð¼Ð¿Ð¾Ñ\80Ñ\82а Ð¸ нулевой правки в импортируемых страницах.",
+       "apihelp-import-param-tags": "Ð\9cеÑ\82ки, ÐºÐ¾Ñ\82оÑ\80Ñ\8bе Ñ\81ледÑ\83еÑ\82 Ñ\83казаÑ\82Ñ\8c Ñ\83 Ð·Ð°Ð¿Ð¸Ñ\81и Ð² Ð¶Ñ\83Ñ\80нале Ð¸Ð¼Ð¿Ð¾Ñ\80Ñ\82а Ð¸ Ñ\83 нулевой правки в импортируемых страницах.",
        "apihelp-import-example-import": "Импортировать [[meta:Help:ParserFunctions]] с полной историей правок в пространство имён 100.",
        "apihelp-linkaccount-summary": "Связать аккаунт третьей стороны с текущим участником.",
        "apihelp-linkaccount-example-link": "Начать связывание аккаунта с <kbd>Example</kdb>.",
        "apihelp-login-param-domain": "Домен (необязательно).",
        "apihelp-login-param-token": "Токен входа, полученный при первом запросе.",
        "apihelp-login-example-gettoken": "Получить токен входа.",
-       "apihelp-login-example-login": "Войти",
+       "apihelp-login-example-login": "Войти.",
        "apihelp-logout-summary": "Выйти и очистить данные сессии.",
-       "apihelp-logout-example-logout": "Ð\92Ñ\8bйÑ\82и Ð¸Ð· Ñ\82екÑ\83Ñ\89его Ñ\83Ñ\87аÑ\81Ñ\82ника.",
+       "apihelp-logout-example-logout": "Ð\92Ñ\8bйÑ\82и Ð¸Ð· Ñ\82екÑ\83Ñ\89ей Ñ\83Ñ\87Ñ\91Ñ\82ной Ð·Ð°Ð¿Ð¸Ñ\81и.",
        "apihelp-managetags-summary": "Осуществление задач, связанных с изменением меток.",
        "apihelp-managetags-param-operation": "Какую операцию выполнить:\n;create: Создать новую метку для ручного использования.\n;delete: Удалить метку из базы данных, что включает в себя удаление метки со всех версий и записей журналов, где она использовалось.\n;activate: Активировать изменение метки, позволив участникам устанавливать её вручную.\n;deactivate: Деактивировать изменение метки, запретив участникам устанавливать её вручную.",
        "apihelp-managetags-param-tag": "Создаваемая, удаляемая, активируемая или деактивируемая метка. Создаваемая метка должна не существовать. Удаляемая метка должна существовать. Активируемая метка должна существовать и не быть использованной в каком-либо расширении. Деактивируемая метка должна существовать и быть заданной вручную.",
        "apihelp-query+info-paramvalue-prop-readable": "Может ли участник просматривать эту страницу.",
        "apihelp-query+info-paramvalue-prop-preload": "Текст, возвращённый EditFormPreloadText.",
        "apihelp-query+info-paramvalue-prop-displaytitle": "Возвращает стиль отображения заголовка страницы.",
+       "apihelp-query+info-paramvalue-prop-varianttitles": "Выдаёт отображаемый заголовок во всех вариантах языка контента сайта.",
        "apihelp-query+info-param-testactions": "Проверить, может ли текущий участник провести указанные действия над страницей.",
        "apihelp-query+info-param-token": "Вместо этого используйте [[Special:ApiHelp/query+tokens|action=query&meta=tokens]].",
        "apihelp-query+info-example-simple": "Получить информацию о странице <kbd>Main Page</kbd>.",
        "apihelp-query+recentchanges-param-limit": "Сколько правок вернуть.",
        "apihelp-query+recentchanges-param-type": "Какие типы правок показать.",
        "apihelp-query+recentchanges-param-toponly": "Перечислять только последние правки страниц.",
+       "apihelp-query+recentchanges-param-title": "Вернуть записи, связанные со страницей.",
        "apihelp-query+recentchanges-param-generaterevisions": "При использовании в качестве генератора, генерировать идентификаторы версий вместо их названий. Записи последних изменений без привязанного идентификатора версии (например, большинство записей журналов) не сгенерируют ничего.",
        "apihelp-query+recentchanges-example-simple": "Список последних изменений.",
        "apihelp-query+recentchanges-example-generator": "Получить информацию о последних страницах с неотпатрулированными изменениями.",
        "api-help-parameters": "Параметр{{PLURAL:$1||ы}}:",
        "api-help-param-deprecated": "Устарело.",
        "api-help-param-required": "Это обязательный параметр.",
+       "api-help-param-templated": "Это [[Special:ApiHelp/main#main/templatedparams|шаблонный параметр]]. При отправке запроса $2.",
+       "api-help-param-templated-var-first": "<var>&#x7B;$1&#x7D;</var> в названии параметра должно быть заменено значениями <var>$2</var>",
+       "api-help-param-templated-var": "<var>&#x7B;$1&#x7D;</var> — значениями <var>$2</var>",
        "api-help-datatypes-header": "Типы данных",
        "api-help-datatypes": "Ввод в MediaWiki должен быть NFC-нормализованным UTF-8. MediaWiki может попытаться преобразовать другой ввод, но это приведёт к провалу некоторых операций (таких, как [[Special:ApiHelp/edit|редактирование]] со сверкой MD5).\n\nНекоторые типы параметров в запросах API требуют дополнительных пояснений:\n;логический\n:Логические параметры работают как флажки (checkboxes) в HTML: если параметр задан, независимо от его значения, он воспринимается за истину. Для передачи ложного значения просто опустите параметр.\n;временные метки\n:Временные метки могут быть заданы в нескольких форматах. Рекомендуемым является дата и время ISO 8601. Всё время считается в UTC, любые включённые часовые пояса игнорируются.\n:* Дата и время ISO 8601: <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (знаки препинания и <kbd>Z</kbd> необязательны)\n:* Дата и время ISO 8601 с (игнорируемой) дробной частью секунд: <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (дефисы, двоеточия и <kbd>Z</kbd> необязательны)\n:* Формат MediaWiki: <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* Общий числовой формат: <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (необязательный часовой пояс <kbd>GMT</kbd>, <kbd>+<var>##</var></kbd> или <kbd>-<var>##</var></kbd> игнорируется)\n:* Формат EXIF: <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Формат RFC 2822 (часовой пояс может быть опущен): <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Формат RFC 850 (часовой пояс может быть опущен): <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Формат ctime языка программирования C: <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* Количество секунд, прошедших с 1970-01-01T00:00:00Z, в виде челого числа с от 1 до 13 знаками (исключая <kbd>0</kbd>)\n:* Строка <kbd>now</kbd>\n;альтернативный разделитель значений\n:Параметры, принимающие несколько значений, обычно отправляются со значениями, разделёнными с помощью символа пайпа, например, <kbd>param=value1|value2</kbd> или <kbd>param=value1%7Cvalue2</kbd>. Если значение должно содержать символ пайпа, используйте U+001F (Unit Separator) в качестве разделителя ''и'' добавьте в начало значения U+001F, например, <kbd>param=%1Fvalue1%1Fvalue2</kbd>.",
+       "api-help-templatedparams-header": "Шаблонные параметры",
+       "api-help-templatedparams": "Шаблонные параметры используются в случаях, когда модулю API нужно получить по параметру со значением на каждое значение другого параметра. Например, если бы был модуль API, запрашивающий фрукты, у него мог бы быть параметр <var>фрукты</var>, указывающий, какие фрукты запрашиваются, и шаблонный параметр <var>{фрукт}-в-количестве</var>, указывающий, сколько фруктов каждого вида запросить. Клиент API, который хочет запросить 1 яблоко, 5 бананов и 20 апельсинов, мог бы тогда сделать запрос наподобие <kbd>фрукты=яблоки|бананы|апельсины&яблоки-в-количестве=1&бананы-в-количестве=5&апельсины-в-количестве=20</kbd>.",
        "api-help-param-type-limit": "Тип: целое число или <kbd>max</kbd>",
        "api-help-param-type-integer": "Тип: {{PLURAL:$1|1=целое число|2=список целых чисел}}",
        "api-help-param-type-boolean": "Тип: логический ([[Special:ApiHelp/main#main/datatypes|подробнее]])",
        "apierror-templateexpansion-notwikitext": "Раскрытие шаблонов разрешено только для вики-текстового содержимого. $1 использует модель содержимого $2.",
        "apierror-timeout": "Сервер не ответил за ожидаемое время.",
        "apierror-toofewexpiries": "Задано $1 {{PLURAL:$1|временная метка|временные метки|временных меток}} истечения, необходимо $2.",
+       "apierror-toomanyvalues": "Слишком много значений передано параметру <var>$1</var>. Максимальное число — $2.",
        "apierror-unknownaction": "Заданное действие, <kbd>$1</kbd>, не распознано.",
        "apierror-unknownerror-editpage": "Неизвестная ошибка EditPage: $1.",
        "apierror-unknownerror-nocode": "Неизвестная ошибка.",
        "apiwarn-difftohidden": "Невозможно сравнить с r$1: содержимое скрыто.",
        "apiwarn-errorprinterfailed": "Сборщик ошибок упал. Будет совершена повторная попытка без параметров.",
        "apiwarn-errorprinterfailed-ex": "Сборщик ошибок упал (будет совершена повторная попытка без параметров): $1",
+       "apiwarn-ignoring-invalid-templated-value": "При обработке шаблонных параметров значение <kbd>$2</kbd> параметра <var>$1</var> проигнорировано.",
        "apiwarn-invalidcategory": "«$1» не является категорией.",
        "apiwarn-invalidtitle": "«$1» не является некорректным заголовком.",
        "apiwarn-invalidxmlstylesheetext": "Таблицы стилей должны иметь расширение <code>.xsl</code>.",
        "apiwarn-redirectsandrevids": "Раскрытие перенаправлений не может быть использовано вместе с параметром <var>revids</var>. Все перенаправления на точку <var>revids</var> не должны быть раскрыты.",
        "apiwarn-tokennotallowed": "Действие «$1» не разрешено для текущего участника.",
        "apiwarn-tokens-origin": "Токены не могут быть получены, пока не применено правило ограничения домена.",
-       "apiwarn-toomanyvalues": "Слишком много значений передано параметру <var>$1</var>. Максимальное число — $2.",
        "apiwarn-truncatedresult": "Результат был усечён, поскольку в противном случае он был бы больше лимита в $1 {{PLURAL:$1|байт|байта|байт}}.",
        "apiwarn-unclearnowtimestamp": "Передача «$2» в качестве параметра временной метки <var>$1</var> устарело. Если по какой-то причине вы хотите прямо указать текущее время без вычисления его на стороне клиента, используйте <kbd>now</kbd>.",
        "apiwarn-unrecognizedvalues": "{{PLURAL:$3|Нераспознанное значение|Нераспознанные значения}} параметра <var>$1</var>: $2.",
index bc0b365..1d2e22a 100644 (file)
        "apierror-templateexpansion-notwikitext": "Розширення шаблонів підтримується лише для вмісту у форматі вікірозмітки. $1 використовує контентну модель $2.",
        "apierror-timeout": "Сервер не відповів протягом відведеного на це часу.",
        "apierror-toofewexpiries": "$1 {{PLURAL:$1|мітка часу завершення була надана|мітки часу завершення були надані|міток часу завершення було надано}}, тоді як {{PLURAL:$2|потрібна була $2 така мітка|потрібні були $2 таких мітки|потрібно було $2 таких міток}}.",
+       "apierror-toomanyvalues": "Надто багато значень задано для параметра <var>$1</var>. Ліміт становить $2.",
        "apierror-unknownaction": "Вказана дія, <kbd>$1</kbd>, нерозпізнана.",
        "apierror-unknownerror-editpage": "Невідома помилка EditPage: $1.",
        "apierror-unknownerror-nocode": "Невідома помилка.",
        "apiwarn-redirectsandrevids": "Вирішення перенаправлень не може використовуватись разом з параметром <var>revids</var>. Усі перенаправлення, на які вказує <var>revids</var>, не було вирішено.",
        "apiwarn-tokennotallowed": "Дія «$1» недозволена для поточного користувача.",
        "apiwarn-tokens-origin": "Токени не можна отримати, поки не застосована політика одного походження.",
-       "apiwarn-toomanyvalues": "Надто багато значень задано для параметра <var>$1</var>. Ліміт становить $2.",
        "apiwarn-truncatedresult": "Цей результат було скорочено, оскільки інакше він перевищив би ліміт у $1 байтів.",
        "apiwarn-unclearnowtimestamp": "Вказування «$2» для параметра мітки часу <var>$1</var> є застарілим. Якщо з якоїсь причини Вам треба чітко вказати поточний час без вираховування його з боку клієнта, використайте <kbd>now</kbd>.",
        "apiwarn-unrecognizedvalues": "{{PLURAL:$3|Нерозпізнане|Нерозпізнані}} значення для параметра <var>$1</var>: $2.",
index fba891b..a58888b 100644 (file)
@@ -23,7 +23,8 @@
                        "Myy730",
                        "D41D8CD98F",
                        "Umherirrender",
-                       "NeverBehave"
+                       "NeverBehave",
+                       "Wbxshiori"
                ]
        },
        "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|文档]]\n* [[mw:Special:MyLanguage/API:FAQ|常见问题]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api 邮件列表]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API公告]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R 程序错误与功能请求]\n</div>\n<strong>状态信息:</strong>MediaWiki API是一个成熟稳定的,不断受到支持和改进的界面。尽管我们尽力避免,但偶尔也需要作出重大更新;请订阅[https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mediawiki-api-announce 邮件列表]以便获得更新通知。\n\n<strong>错误请求:</strong>当API收到错误请求时,HTTP header将会返回一个包含\"MediaWiki-API-Error\"的值,随后header的值与error code将会送回并设置为相同的值。详细信息请参阅[[mw:Special:MyLanguage/API:Errors_and_warnings|API:错误与警告]]。\n\n<p class=\"mw-apisandbox-link\"><strong>测试中:</strong>测试API请求的易用性,请参见[[Special:ApiSandbox]]。</p>",
        "api-help-parameters": "{{PLURAL:$1|参数}}:",
        "api-help-param-deprecated": "已弃用。",
        "api-help-param-required": "这个参数是必须的。",
+       "api-help-param-templated": "这是一个[[Special:ApiHelp/main#main/templatedparams|模板参数]]。当做出请求时,$2。",
+       "api-help-param-templated-var-first": "参数名中的<var>&#x7B;$1&#x7D;</var>应替换为<var>$2</var>的值",
+       "api-help-param-templated-var": "<var>&#x7B;$1&#x7D;</var>与<var>$2</var>的值",
        "api-help-datatypes-header": "数据类型",
        "api-help-datatypes": "至MediaWiki的输入应为NFC标准化的UTF-8。MediaWiki可以尝试转换其他输入,但这可能导致一些操作失败(例如带MD5校验[[Special:ApiHelp/edit|编辑]])。\n\n一些在API请求中的参数类型需要更进一步解释:\n;boolean\n:布尔参数就像HTML复选框一样工作:如果指定参数,无论何值都被认为是真。如果要假值,则可完全忽略参数。\n;timestamp\n:时间戳可被指定为很多格式。推荐使用ISO 8601日期和时间标准。所有时间为UTC时间,包含的任何时区会被忽略。\n:* ISO 8601日期和时间,<kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd>(标点和<kbd>Z</kbd>是可选项)\n:* 带小数秒(会被忽略)的ISO 8601日期和时间,<kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd>(破折号、冒号和<kbd>Z</kbd>是可选的)\n:* MediaWiki格式,<kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* 一般数字格式,<kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>(<kbd>GMT</kbd>、<kbd>+<var>##</var></kbd>或<kbd>-<var>##</var></kbd>的可选时区会被忽略)\n:* EXIF格式,<kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* RFC 2822格式(时区可省略),<kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* RFC 850格式(时区可省略),<kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* C ctime格式,<kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* 从1970-01-01T00:00:00Z开始的秒数,作为1到13位数的整数(除了<kbd>0</kbd>)\n:* 字符串<kbd>now</kbd>\n;替代多值分隔符\n:使用多个值的参数通常会与管道符号分隔的值一起提交,例如<kbd>param=value1|value2</kbd>或<kbd>param=value1%7Cvalue2</kbd>。如果值必须包含管道符号,使用U+001F(单位分隔符)作为分隔符,''并''在值前加前缀U+001F,例如<kbd>param=%1Fvalue1%1Fvalue2</kbd>。",
+       "api-help-templatedparams-header": "模板参数",
+       "api-help-templatedparams": "模板参数支持API模块需要为每个其他参数赋值的情况。例如如果有API模块请求水果,它会有参数<var>水果</var>指定请求的水果,以及模板参数<var>{水果}-数量</var>以指定每种水果请求多少。需要1个苹果、5个香蕉和20个草莓的API客户端可以做出类似<kbd>水果=苹果|香蕉|草莓&苹果-数量=1&香蕉-数量=5&草莓-数量=20</kbd>的请求。",
        "api-help-param-type-limit": "类型:整数或<kbd>max</kbd>",
        "api-help-param-type-integer": "类型:{{PLURAL:$1|1=整数|2=整数列表}}",
        "api-help-param-type-boolean": "类型:布尔值([[Special:ApiHelp/main#main/datatypes|详细信息]])",
        "api-help-authmanager-general-usage": "使用此模块的一般程序是:\n# 通过<kbd>amirequestsfor=$4</kbd>取得来自<kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>的可用字段,和来自<kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>的<kbd>$5</kbd>令牌。\n# 向用户显示字段,并获得其提交的内容。\n# 发送(POST)至此模块,提供<var>$1returnurl</var>及任何相关字段。\n# 在响应中检查<samp>status</samp>。\n#* 如果您收到了<samp>PASS</samp>(成功)或<samp>FAIL</samp>(失败),则认为操作结束。成功与否如上句所示。\n#* 如果您收到了<samp>UI</samp>,向用户显示新字段,并再次获取其提交的内容。然后再次使用<var>$1continue</var>,向本模块提交相关字段,并重复第四步。\n#* 如果您收到了<samp>REDIRECT</samp>,将用户指向<samp>redirecttarget</samp>中的目标,等待其返回<var>$1returnurl</var>。然后再次使用<var>$1continue</var>,向本模块提交返回URL中提供的一切字段,并重复第四步。\n#* 如果您收到了<samp>RESTART</samp>,这意味着身份验证正常运作,但我们没有链接的用户账户。您可以将此看做<samp>UI</samp>或<samp>FAIL</samp>。",
        "api-help-authmanagerhelper-requests": "只使用这些身份验证请求,通过返回自<kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>的<samp>id</samp>与<kbd>amirequestsfor=$1</kbd>,或来自此模块之前的响应。",
        "api-help-authmanagerhelper-request": "使用此身份验证请求,通过返回自<kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>的<samp>id</samp>与<kbd>amirequestsfor=$1</kbd>。",
-       "api-help-authmanagerhelper-messageformat": "返回消息使用的格式。",
+       "api-help-authmanagerhelper-messageformat": "用于返回消息的格式。",
        "api-help-authmanagerhelper-mergerequestfields": "合并用于所有身份验证请求的字段信息至一个数组中。",
        "api-help-authmanagerhelper-preservestate": "从之前失败的登录尝试中保持状态,如果可能。",
        "api-help-authmanagerhelper-returnurl": "为第三方身份验证流返回URL,必须为绝对值。需要此值或<var>$1continue</var>两者之一。\n\n在接收<samp>REDIRECT</samp>响应时,您将代表性的打开浏览器或web视图到特定用于第三方身份验证流的<samp>redirecttarget</samp> URL。当它完成时,第三方将发生浏览器或web视图至此URL。您应当提取任何来自URL的查询或POST参数,并作为<var>$1continue</var>请求传递至此API模块。",
        "apierror-templateexpansion-notwikitext": "模板展开只支持wiki文本内容。$1使用内容模型$2。",
        "apierror-timeout": "服务器没有在预期时间内响应。",
        "apierror-toofewexpiries": "提供了$1个逾期{{PLURAL:$1|时间戳}},实际则需要$2个。",
+       "apierror-toomanyvalues": "为参数<var>$1</var>提供了太多值。限制为$2。",
        "apierror-unknownaction": "指定的操作<kbd>$1</kbd>不被承认。",
        "apierror-unknownerror-editpage": "未知的编辑页面错误:$1。",
        "apierror-unknownerror-nocode": "未知错误。",
        "apiwarn-difftohidden": "不能与r$1做差异比较:内容被隐藏。",
        "apiwarn-errorprinterfailed": "错误打印失败。将在没有参数的前提下重试。",
        "apiwarn-errorprinterfailed-ex": "错误打印失败(将在没有参数的前提下重试):$1",
+       "apiwarn-ignoring-invalid-templated-value": "当处理模板参数时,忽略<var>$1</var>中的值<kbd>$2</kbd>。",
        "apiwarn-invalidcategory": "“$1”不是一个分类。",
        "apiwarn-invalidtitle": "“$1”不是一个有效的标题。",
        "apiwarn-invalidxmlstylesheetext": "样式表应拥有<code>.xsl</code>扩展名。",
        "apiwarn-redirectsandrevids": "重定向解决方案不能与<var>revids</var>参数一起使用。任何<var>revids</var>所指向的重定向都未被解决。",
        "apiwarn-tokennotallowed": "操作“$1”不允许当前用户使用。",
        "apiwarn-tokens-origin": "在未应用同来源方针时,令牌可能无法获得。",
-       "apiwarn-toomanyvalues": "参数<var>$1</var>指定了太多的值。上限为$2。",
        "apiwarn-truncatedresult": "此结果被缩短,否则其将大于$1字节的限制。",
        "apiwarn-unclearnowtimestamp": "为时间戳参数<var>$1</var>传递“$2”已被弃用。如因某些原因您需要明确指定当前时间而不计算客户端,请使用<kbd>now</kbd>。",
        "apiwarn-unrecognizedvalues": "参数<var>$1</var>有无法识别的{{PLURAL:$3|值}}:$2。",
index ebf998b..30a685b 100644 (file)
        "apihelp-query+search-param-limit": "要回傳的頁面總數。",
        "apihelp-query+stashimageinfo-summary": "回傳多筆儲藏檔案的檔案資訊。",
        "apihelp-query+stashimageinfo-example-simple": "回傳儲藏檔案的檔案資訊。",
-       "apihelp-query+tags-summary": "列出更改標籤。",
+       "apihelp-query+tags-summary": "列出變更標記。",
        "apihelp-query+templates-summary": "回傳指定頁面中所有引用的頁面。",
        "apihelp-query+templates-param-limit": "要回傳的模板數量。",
        "apihelp-query+tokens-param-type": "要求的權杖類型。",
        "apihelp-unblock-param-reason": "解除封鎖的原因。",
        "apihelp-unblock-example-id": "解除封銷 ID #<kbd>105</kbd>。",
        "apihelp-undelete-param-reason": "還原的原因。",
-       "apihelp-userrights-summary": "更改一位使用者的群組成員。",
+       "apihelp-userrights-summary": "變更一位使用者的群組成員。",
        "apihelp-userrights-param-user": "用戶名。",
        "apihelp-userrights-param-userid": "用戶ID。",
        "apihelp-userrights-param-add": "加入使用者至這些群組;若已是成員,則更新失效時間。",
        "apihelp-xmlfm-summary": "使用 XML 格式輸出資料 (使用 HTML 格式顯示)。",
        "api-format-title": "MediaWiki API 結果",
        "api-format-prettyprint-header": "這是$1格式的HTML呈現。HTML適合用於除錯,但不適合應用程式使用。\n\n指定<var>format</var>參數以更改輸出格式。要檢視$1格式的非HTML呈現,設定<kbd>format=$2</kbd>。\n\n參考 [[mw:Special:MyLanguage/API|完整說明文件]] 或 [[Special:ApiHelp/main|API說明]] 以取得更多資訊。",
+       "api-format-prettyprint-header-only-html": "這是用來除錯的HTML呈現,不適合實際應用。\n\n參見[[mw:Special:MyLanguage/API|完整文件]]或[[Special:ApiHelp/main|API幫助]]以取得更多資訊。",
+       "api-format-prettyprint-header-hyperlinked": "這是$1格式的HTML實現。HTML對除錯很有用,但不適合應用程式使用。\n\n指定<var>format</var>參數以更改輸出格式。要查看$1格式的非HTML實現,設置[$3 <kbd>format=$2</kbd>]。\n\n參見[[mw:API|完整文件]],或[[Special:ApiHelp/main|API幫助]]以獲取更多信息。",
+       "api-format-prettyprint-status": "此回應將會傳回HTTP狀態$1 $2。",
        "api-pageset-param-titles": "要使用的標題清單。",
        "api-pageset-param-pageids": "要使用的頁面 ID 清單。",
        "api-pageset-param-revids": "要使用的修訂 ID 清單。",
        "api-help-lead": "此頁為自動產生的 MediaWiki API 說明文件頁面。\n\n說明文件與範例:https://www.mediawiki.org/wiki/API",
        "api-help-main-header": "主要模組",
        "api-help-flag-deprecated": "此模組已停用。",
+       "api-help-flag-internal": "<strong>此模組是內部的或不穩定的。</strong>它的操作可能更改而不另行通知。",
        "api-help-flag-readrights": "此模組需要讀取權限。",
        "api-help-flag-writerights": "此模組需要寫入權限。",
        "api-help-flag-mustbeposted": "此模組僅接受 POST 請求。",
+       "api-help-flag-generator": "此模組可作為產生器使用。",
+       "api-help-license": "協定:[[$1|$2]]",
+       "api-help-license-noname": "協定:[[$1|查看連結]]",
+       "api-help-license-unknown": "協定:<span class=\"apihelp-unknown\">未知</span>",
        "api-help-parameters": "{{PLURAL:$1|參數}}:",
        "api-help-param-deprecated": "已停用。",
        "api-help-param-required": "此參數為必填。",
+       "api-help-datatypes-header": "資料類型",
+       "api-help-datatypes": "至MediaWiki的輸入值應為NFC標準化的UTF-8。MediaWiki可以嘗試轉換其他輸入值,但這可能導致一些操作失敗(例如附帶MD5檢查的[[Special:ApiHelp/edit|編輯]])。\n\n一些在API請求中的參數類型需要更進一步解釋:\n;boolean\n:布林參數產生作用就像HTML複選框一樣:如果參數被指定,無論何值都被視為真(true)。如果要假值(false),則必須省略參數。\n;timestamp\n:時間戳記可被指定為多種格式。推荐使用ISO 8601日期和時間標準。所有時間為UTC時間,包含的任何時區都會被忽略。\n:* ISO 8601日期和時間,<kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd>(標點和<kbd>Z</kbd>為選用)\n:* 帶小數秒(會被忽略)的ISO 8601日期和時間,<kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd>(破折號、冒號和<kbd>Z</kbd>為選用)\n:* MediaWiki格式,<kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* 一般數字格式,<kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>(<kbd>GMT</kbd>、<kbd>+<var>##</var></kbd>或<kbd>-<var>##</var></kbd>的選用時區會被忽略)\n:* EXIF格式,<kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* RFC 2822格式(時區可省略),<kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* RFC 850格式(時區可省略),<kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* C ctime格式,<kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* 從1970-01-01T00:00:00Z開始的秒數,作為1到13位數的整數(除了<kbd>0</kbd>)\n:* 字串<kbd>now</kbd>\n;替代多值分隔符號\n:使用多個值的參數通常會與垂直線符號(|)分隔的值一起提交,例如<kbd>param=value1|value2</kbd>或<kbd>param=value1%7Cvalue2</kbd>。如果值必須包含垂直線符號,使用U+001F(單位分隔符號)作為分隔符號,''並且''在值前加前綴U+001F,例如<kbd>param=%1Fvalue1%1Fvalue2</kbd>。",
+       "api-help-param-type-limit": "類型:整數或<kbd>max</kbd>",
+       "api-help-param-type-integer": "類型:{{PLURAL:$1|1=整數|2=整數列表}}",
+       "api-help-param-type-boolean": "類型:布林值([[Special:ApiHelp/main#main/datatypes|詳細資訊]])",
+       "api-help-param-type-timestamp": "類型:{{PLURAL:$1|1=時間戳記|2=時間戳記列表}}([[Special:ApiHelp/main#main/datatypes|允許格式]])",
+       "api-help-param-type-user": "類型:{{PLURAL:$1|1=使用者名稱|2=使用者名稱列表}}",
        "api-help-param-list": "{{PLURAL:$1|1=單值|2=多值 (以 <kbd>{{!}}</kbd> 或 [[Special:ApiHelp/main#main/datatypes|alternative]] 分隔)}}:$2",
        "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=必須空白|可以空白,或 $2}}",
        "api-help-param-limit": "不允許超過 $1。",
        "api-help-param-upload": "必須使用 multipart/form-data 以檔案上傳的方式傳送。",
        "api-help-param-multi-separate": "將幾個值以 <kbd>|</kbd> 或 [[Special:ApiHelp/main#main/datatypes|alternative]] 分隔。",
        "api-help-param-multi-max": "上限值為 {{PLURAL:$1|$1}} (機器人為 {{PLURAL:$2|$2}})。",
+       "api-help-param-multi-all": "要指定所有值,請使用<kbd>$1</kbd>。",
        "api-help-param-default": "預設值:$1",
        "api-help-param-default-empty": "預設值:<span class=\"apihelp-empty\">(空)</span>",
        "api-help-param-token": "自 [[Special:ApiHelp/query+tokens|action=query&meta=tokens]] 接收的 \"$1\" 密鑰。",
+       "api-help-param-token-webui": "為顧及相容性,web UI中使用的代碼(Token)也是可接受的。",
+       "api-help-param-disabled-in-miser-mode": "因[[mw:Special:MyLanguage/Manual:$wgMiserMode|miser模式]]而被停用。",
+       "api-help-param-limited-in-miser-mode": "<strong>注意:</strong>因[[mw:Special:MyLanguage/Manual:$wgMiserMode|miser模式]],使用這個可能導致繼續以前傳回少於<var>$1limit</var>筆結果;極端情況下可能不會傳回任何结果。",
+       "api-help-param-direction": "列舉的方向:\n;newer:最舊的優先。注意:$1start應在$1end之前。\n;older:最新的優先(預設)。注意:$1start應在$1end之後。",
+       "api-help-param-continue": "當有更多結果可用時,使用這個繼續。",
        "api-help-param-no-description": "<span class=\"apihelp-empty\">(無描述)</span>",
        "api-help-examples": "{{PLURAL:$1|範例}}:",
        "api-help-permissions": "{{PLURAL:$1|權限}}:",
        "api-help-permissions-granted-to": "{{PLURAL:$1|已授權給}}: $2",
+       "api-help-open-in-apisandbox": "<small>[在沙盒中開啟]</small>",
        "api-help-authmanager-general-usage": "使用此模組的一般程式是:\n# 通過<kbd>amirequestsfor=$4</kbd>取得來自<kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>的可用欄位,和來自<kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>的<kbd>$5</kbd>令牌。\n# 向用戶顯示欄位,並獲得其提交的內容。\n# 提交(POST)至此模組,提供<var>$1returnurl</var>及任何相關欄位。\n# 在回应中檢查<samp>status</samp>。\n#* 如果您收到了<samp>PASS</samp>(成功)或<samp>FAIL</samp>(失敗),則認為操作結束。成功與否如上句所示。\n#* 如果您收到了<samp>UI</samp>,向用戶顯示新欄位,並再次獲取其提交的內容。然後再次使用<var>$1continue</var>,向本模組提交相關欄位,並重復第四步。\n#* 如果您收到了<samp>REDIRECT</samp>,將使用者指向<samp>redirecttarget</samp>中的目標,等待其返回<var>$1returnurl</var>。然後再次使用<var>$1continue</var>,向本模組提交返回URL中提供的一切欄位,並重復第四步。\n#* 如果您收到了<samp>RESTART</samp>,這意味著身份驗證正常運作,但我們沒有連結的使用者賬戶。您可以將此看做<samp>UI</samp>或<samp>FAIL</samp>。",
+       "api-help-authmanagerhelper-requests": "只使用這些身份驗證請求,透過自<kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>回傳的<samp>id</samp>與<kbd>amirequestsfor=$1</kbd>,或來自此模組之前的回應。",
+       "api-help-authmanagerhelper-request": "使用此身份驗證請求,透過自<kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>回傳的<samp>id</samp>與<kbd>amirequestsfor=$1</kbd>。",
+       "api-help-authmanagerhelper-messageformat": "用於回傳訊息的格式。",
+       "api-help-authmanagerhelper-mergerequestfields": "將用於所有身份驗證請求的欄位資訊合併至一個陣列中。",
+       "api-help-authmanagerhelper-preservestate": "從之前失敗的登入嘗試中保持狀態,如果可能。",
+       "api-help-authmanagerhelper-returnurl": "為第三方身份驗證流程傳回URL,必須為絕對值。需要此值或<var>$1continue</var>兩者之一。\n\n在接收<samp>REDIRECT</samp>回應時,一般狀況下您將打開瀏覽器或網站瀏覽功能到特定的<samp>redirecttarget</samp> URL以進行第三方身份驗證流程。當它完成時,第三方會將瀏覽器或網站瀏覽功能送至此URL。您應當提取任何來自URL的查詢或POST參數,並將之作為<var>$1continue</var>請求傳遞至此API模組。",
+       "api-help-authmanagerhelper-continue": "此請求是在先前的<samp>UI</samp>或<samp>REDIRECT</samp>回應之後的後續動作。必須為此值或<var>$1returnurl</var>。",
+       "api-help-authmanagerhelper-additional-params": "此模組允許額外參數,取決於可用的身份驗證請求。使用<kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>与<kbd>amirequestsfor=$1</kbd>(或之前來自此模組的回應,如果合適)以決定可用請求及其使用的欄位。",
        "apierror-missingparam": "<var>$1</var>參數必須被設定。",
        "apierror-mustbeloggedin-changeauth": "必須登入,才能變更身分核對資取。",
        "apierror-mustbeloggedin-removeauth": "必須登入,才能移除身分核對資取。",
index 3125bd3..717b592 100644 (file)
@@ -138,7 +138,7 @@ class Throttler implements LoggerAwareInterface {
                                $this->logRejection( [
                                        'throttle' => $this->type,
                                        'index' => $index,
-                                       'ip' => $ipKey,
+                                       'ipKey' => $ipKey,
                                        'username' => $username,
                                        'count' => $count,
                                        'expiry' => $expiry,
@@ -193,7 +193,7 @@ class Throttler implements LoggerAwareInterface {
 
        protected function logRejection( array $context ) {
                $logMsg = 'Throttle {throttle} hit, throttled for {expiry} seconds due to {count} attempts '
-                       . 'from username {username} and IP {ip}';
+                       . 'from username {username} and IP {ipKey}';
 
                // If we are hitting a throttle for >= warningLimit attempts, it is much more likely to be
                // an attack than someone simply forgetting their password, so log it at a higher level.
index e77e251..b2a91c2 100644 (file)
@@ -18,7 +18,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  *
  * @file
- * @license GNU GPL v2 or later
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
 
index 8ce21f5..e8c3a99 100644 (file)
@@ -279,7 +279,8 @@ class RCCacheEntryFactory {
                } else {
                        $userLink = Linker::userLink(
                                $cacheEntry->mAttribs['rc_user'],
-                               $cacheEntry->mAttribs['rc_user_text']
+                               $cacheEntry->mAttribs['rc_user_text'],
+                               ExternalUserNames::getLocal( $cacheEntry->mAttribs['rc_user_text'] )
                        );
                }
 
index 30cae5a..f52dcae 100644 (file)
@@ -63,8 +63,6 @@ abstract class Collation {
                                return new CollationCkb;
                        case 'xx-uca-et':
                                return new CollationEt;
-                       case 'xx-uca-fa':
-                               return new CollationFa;
                        case 'uppercase-ab':
                                return new AbkhazUppercaseCollation;
                        case 'uppercase-ba':
diff --git a/includes/collation/CollationFa.php b/includes/collation/CollationFa.php
deleted file mode 100644 (file)
index 7410886..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-<?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
- */
-
-/**
- * Temporary workaround for incorrect collation of Persian language ('fa') in ICU 52 (bug T139110).
- *
- * Replace with other letters that appear in an okish spot in the alphabet
- *
- *  - Characters 'و' 'ا' (often appear at the beginning of words)
- *  - Characters 'ٲ' 'ٳ' (may appear at the beginning of words in loanwords)
- *
- * @since 1.29
- */
-class CollationFa extends IcuCollation {
-
-       // Really hacky - replace with stuff from other blocks.
-       private $override = [
-               // U+0627 ARABIC LETTER ALEF => U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE
-               "\xd8\xa7" => "\xd8\xa3",
-               // U+0648 ARABIC LETTER WAW => U+0649 ARABIC LETTER ALEF MAKSURA
-               "\xd9\x88" => "\xd9\x89",
-               // U+0672 ARABIC LETTER ALEF WITH WAVY HAMZA ABOVE => U+F3001 (private use area)
-               "\xd9\xb2" => "\xF3\xB3\x80\x81",
-               // U+0673 ARABIC LETTER ALEF WITH WAVY HAMZA BELOW => U+F3002 (private use area)
-               "\xd9\xb3" => "\xF3\xB3\x80\x82",
-       ];
-
-       public function __construct() {
-               parent::__construct( 'fa' );
-       }
-
-       public function getSortKey( $string ) {
-               $modified = strtr( $string, $this->override );
-               return parent::getSortKey( $modified );
-       }
-
-       public function getFirstLetter( $string ) {
-               if ( isset( $this->override[substr( $string, 0, 2 )] ) ) {
-                       return substr( $string, 0, 2 );
-               }
-               return parent::getFirstLetter( $string );
-       }
-}
index 36efdb3..d6ab0ff 100644 (file)
@@ -333,7 +333,7 @@ class IcuCollation extends Collation {
                                static::class,
                                $this->locale,
                                $this->digitTransformLanguage->getCode(),
-                               self::getICUVersion(),
+                               INTL_ICU_VERSION,
                                self::FIRST_LETTER_VERSION
                        );
                        $this->firstLetterData = $cache->getWithSetCallback( $cacheKey, $cache::TTL_WEEK, function () {
@@ -384,9 +384,17 @@ class IcuCollation extends Collation {
                foreach ( $letters as $letter ) {
                        $key = $this->getPrimarySortKey( $letter );
                        if ( isset( $letterMap[$key] ) ) {
-                               // Primary collision
-                               // Keep whichever one sorts first in the main collator
-                               if ( $this->mainCollator->compare( $letter, $letterMap[$key] ) < 0 ) {
+                               // Primary collision (two characters with the same sort position).
+                               // Keep whichever one sorts first in the main collator.
+                               $comp = $this->mainCollator->compare( $letter, $letterMap[$key] );
+                               wfDebug( "Primary collision '$letter' '{$letterMap[$key]}' (comparison: $comp)\n" );
+                               // If that also has a collision, use codepoint as a tiebreaker.
+                               if ( $comp === 0 ) {
+                                       // TODO Use <=> operator when PHP 7 is allowed.
+                                       $comp = UtfNormal\Utils::utf8ToCodepoint( $letter ) -
+                                               UtfNormal\Utils::utf8ToCodepoint( $letterMap[$key] );
+                               }
+                               if ( $comp < 0 ) {
                                        $letterMap[$key] = $letter;
                                }
                        } else {
@@ -520,18 +528,15 @@ class IcuCollation extends Collation {
         * 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 54561
-        * https://bugs.php.net/bug.php?id=54561). This function will return
-        * false on older PHPs.
-        *
-        * TODO: Remove the backwards-compatibility as MediaWiki now requires
-        * higher levels of PHP.
+        * documented, but see https://bugs.php.net/bug.php?id=54561.
         *
         * @since 1.21
-        * @return string|bool
+        * @deprecated since 1.32, use INTL_ICU_VERSION directly
+        * @return string
         */
        static function getICUVersion() {
-               return defined( 'INTL_ICU_VERSION' ) ? INTL_ICU_VERSION : false;
+               wfDeprecated( __METHOD__, '1.32' );
+               return INTL_ICU_VERSION;
        }
 
        /**
@@ -542,7 +547,7 @@ class IcuCollation extends Collation {
         * @return string|bool
         */
        static function getUnicodeVersionForICU() {
-               $icuVersion = self::getICUVersion();
+               $icuVersion = INTL_ICU_VERSION;
                if ( !$icuVersion ) {
                        return false;
                }
@@ -550,6 +555,8 @@ class IcuCollation extends Collation {
                $versionPrefix = substr( $icuVersion, 0, 3 );
                // Source: http://site.icu-project.org/download
                $map = [
+                       '61.' => '10.0',
+                       '60.' => '10.0',
                        '59.' => '9.0',
                        '58.' => '9.0',
                        '57.' => '8.0',
diff --git a/includes/compat/Timestamp.php b/includes/compat/Timestamp.php
deleted file mode 100644 (file)
index 63b87ae..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-<?php
-// This file is loaded by composer.json#autoload.files instead of autoload.php,
-// because PHP's class loader does not support autoloading an alias for a class that
-// isn't already loaded. See also AutoLoaderTest and ClassCollector.
-
-// By using an autoload file, this will trigger directly at runtime outside any class
-// loading context. This file will then register the alias and, as class_alias() does
-// by default, it will trigger a plain autoload for the destination class.
-
-// The below uses a namespaced class reference, to to avoid being seen by ClassCollector,
-// which would otherwise add it to autoload.php, after which AutoLoaderTest will
-// complain about class_alias() not being in the target class file.
-
-/**
- * @deprecated since 1.29
- * @since 1.20
- */
-class_alias( Wikimedia\Timestamp\TimestampException::class, 'TimestampException' );
index 9b35cad..bce1ea6 100644 (file)
@@ -40,7 +40,7 @@ use UtfNormal\Validator;
  *
  * All functions can be called static.
  *
- * See description of forms at http://www.unicode.org/reports/tr15/
+ * See description of forms at https://www.unicode.org/reports/tr15/
  *
  * @deprecated since 1.25, use UtfNormal\Validator directly
  * @ingroup UtfNormal
@@ -57,6 +57,7 @@ class UtfNormal {
         * @return string a clean, shiny, normalized UTF-8 string
         */
        static function cleanUp( $string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::cleanUp( $string );
        }
 
@@ -69,6 +70,7 @@ class UtfNormal {
         * @return string a UTF-8 string in normal form C
         */
        static function toNFC( $string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::toNFC( $string );
        }
 
@@ -80,6 +82,7 @@ class UtfNormal {
         * @return string a UTF-8 string in normal form D
         */
        static function toNFD( $string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::toNFD( $string );
        }
 
@@ -92,6 +95,7 @@ class UtfNormal {
         * @return string a UTF-8 string in normal form KC
         */
        static function toNFKC( $string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::toNFKC( $string );
        }
 
@@ -104,6 +108,7 @@ class UtfNormal {
         * @return string a UTF-8 string in normal form KD
         */
        static function toNFKD( $string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::toNFKD( $string );
        }
 
@@ -114,6 +119,7 @@ class UtfNormal {
         * @return bool
         */
        static function quickIsNFC( $string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::quickIsNFC( $string );
        }
 
@@ -124,6 +130,7 @@ class UtfNormal {
         * @return bool
         */
        static function quickIsNFCVerify( &$string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::quickIsNFCVerify( $string );
        }
 }
diff --git a/includes/compat/normal/UtfNormalDefines.php b/includes/compat/normal/UtfNormalDefines.php
deleted file mode 100644 (file)
index 38ce855..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-<?php
-/**
- * Backwards-compatability constants which are now provided by the
- * UtfNormal library. They are hardcoded here since they are needed
- * before the composer autoloader is initialized.
- *
- * 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 UtfNormal
- */
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_FIRST', 0xac00 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_LAST', 0xd7a3 );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_LBASE', 0x1100 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_VBASE', 0x1161 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_TBASE', 0x11a7 );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_LCOUNT', 19 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_VCOUNT', 21 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_TCOUNT', 28 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_NCOUNT', UNICODE_HANGUL_VCOUNT * UNICODE_HANGUL_TCOUNT );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_LEND', UNICODE_HANGUL_LBASE + UNICODE_HANGUL_LCOUNT - 1 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_VEND', UNICODE_HANGUL_VBASE + UNICODE_HANGUL_VCOUNT - 1 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_TEND', UNICODE_HANGUL_TBASE + UNICODE_HANGUL_TCOUNT - 1 );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_SURROGATE_FIRST', 0xd800 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_SURROGATE_LAST', 0xdfff );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_MAX', 0x10ffff );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_REPLACEMENT', 0xfffd );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_FIRST', "\xea\xb0\x80" /*codepointToUtf8( UNICODE_HANGUL_FIRST )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_LAST', "\xed\x9e\xa3" /*codepointToUtf8( UNICODE_HANGUL_LAST )*/ );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_LBASE', "\xe1\x84\x80" /*codepointToUtf8( UNICODE_HANGUL_LBASE )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_VBASE', "\xe1\x85\xa1" /*codepointToUtf8( UNICODE_HANGUL_VBASE )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_TBASE', "\xe1\x86\xa7" /*codepointToUtf8( UNICODE_HANGUL_TBASE )*/ );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_LEND', "\xe1\x84\x92" /*codepointToUtf8( UNICODE_HANGUL_LEND )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_VEND', "\xe1\x85\xb5" /*codepointToUtf8( UNICODE_HANGUL_VEND )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_TEND', "\xe1\x87\x82" /*codepointToUtf8( UNICODE_HANGUL_TEND )*/ );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_SURROGATE_FIRST', "\xed\xa0\x80" /*codepointToUtf8( UNICODE_SURROGATE_FIRST )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_SURROGATE_LAST', "\xed\xbf\xbf" /*codepointToUtf8( UNICODE_SURROGATE_LAST )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_MAX', "\xf4\x8f\xbf\xbf" /*codepointToUtf8( UNICODE_MAX )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_REPLACEMENT', "\xef\xbf\xbd" /*codepointToUtf8( UNICODE_REPLACEMENT )*/ );
-# define( 'UTF8_REPLACEMENT', '!' );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_OVERLONG_A', "\xc1\xbf" );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_OVERLONG_B', "\xe0\x9f\xbf" );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_OVERLONG_C', "\xf0\x8f\xbf\xbf" );
-
-# These two ranges are illegal
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_FDD0', "\xef\xb7\x90" /*codepointToUtf8( 0xfdd0 )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_FDEF', "\xef\xb7\xaf" /*codepointToUtf8( 0xfdef )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_FFFE', "\xef\xbf\xbe" /*codepointToUtf8( 0xfffe )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_FFFF', "\xef\xbf\xbf" /*codepointToUtf8( 0xffff )*/ );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HEAD', false );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_TAIL', true );
diff --git a/includes/compat/normal/UtfNormalUtil.php b/includes/compat/normal/UtfNormalUtil.php
deleted file mode 100644 (file)
index 0e29dd0..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-<?php
-/**
- * Some of these functions are adapted from places in MediaWiki.
- * Should probably merge them for consistency.
- *
- * Copyright © 2004 Brion Vibber <brion@pobox.com>
- * https://www.mediawiki.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * 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 UtfNormal
- */
-
-use UtfNormal\Utils;
-
-/**
- * Return UTF-8 sequence for a given Unicode code point.
- *
- * @param int $codepoint
- * @return string
- * @throws InvalidArgumentException if fed out of range data.
- * @public
- * @deprecated since 1.25, use UtfNormal\Utils directly
- */
-function codepointToUtf8( $codepoint ) {
-       wfDeprecated( __FUNCTION__, '1.25' );
-       return Utils::codepointToUtf8( $codepoint );
-}
-
-/**
- * Take a series of space-separated hexadecimal numbers representing
- * Unicode code points and return a UTF-8 string composed of those
- * characters. Used by UTF-8 data generation and testing routines.
- *
- * @param string $sequence
- * @return string
- * @throws InvalidArgumentException if fed out of range data.
- * @private
- * @deprecated since 1.25, use UtfNormal\Utils directly
- */
-function hexSequenceToUtf8( $sequence ) {
-       wfDeprecated( __FUNCTION__, '1.25' );
-       return Utils::hexSequenceToUtf8( $sequence );
-}
-
-/**
- * Take a UTF-8 string and return a space-separated series of hex
- * numbers representing Unicode code points. For debugging.
- *
- * @fixme this is private but extensions + maint scripts are using it
- * @param string $str UTF-8 string.
- * @return string
- * @private
- */
-function utf8ToHexSequence( $str ) {
-       wfDeprecated( __FUNCTION__, '1.25' );
-       $buf = '';
-       foreach ( preg_split( '//u', $str, -1, PREG_SPLIT_NO_EMPTY ) as $cp ) {
-               $buf .= sprintf( '%04x ', UtfNormal\Utils::utf8ToCodepoint( $cp ) );
-       }
-
-       return rtrim( $buf );
-}
-
-/**
- * Determine the Unicode codepoint of a single-character UTF-8 sequence.
- * Does not check for invalid input data.
- *
- * @param string $char
- * @return int
- * @public
- * @deprecated since 1.25, use UtfNormal\Utils directly
- */
-function utf8ToCodepoint( $char ) {
-       wfDeprecated( __FUNCTION__, '1.25' );
-       return Utils::utf8ToCodepoint( $char );
-}
-
-/**
- * Escape a string for inclusion in a PHP single-quoted string literal.
- *
- * @param string $string string to be escaped.
- * @return string escaped string.
- * @public
- * @deprecated since 1.25, use UtfNormal\Utils directly
- */
-function escapeSingleString( $string ) {
-       wfDeprecated( __FUNCTION__, '1.25' );
-       return Utils::escapeSingleString( $string );
-}
index a1943be..b26a479 100644 (file)
@@ -7,7 +7,7 @@ $GLOBALS['IP'] = __DIR__ . '/../../';
 require_once __DIR__ . '/../AutoLoader.php';
 
 /**
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
 class ComposerHookHandler {
index 168336b..6aa0b5b 100644 (file)
@@ -5,7 +5,7 @@ use Composer\Package\Package;
 use Composer\Semver\Constraint\Constraint;
 
 /**
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
 class ComposerPackageModifier {
index 2194bed..52bc0cd 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
 class ComposerVersionNormalizer {
index beac91e..b6ccb53 100644 (file)
@@ -28,7 +28,7 @@ use Wikimedia\Rdbms\LoadBalancer;
  * @file
  * @ingroup Database
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Daniel Kinzler
  */
 abstract class DBAccessBase implements IDBAccessObject {
index 7479841..2189498 100644 (file)
@@ -431,7 +431,8 @@ class MWDebug {
                        // Cannot use OutputPage::addJsConfigVars because those are already outputted
                        // by the time this method is called.
                        $html = ResourceLoader::makeInlineScript(
-                               ResourceLoader::makeConfigSetScript( [ 'debugInfo' => $debugInfo ] )
+                               ResourceLoader::makeConfigSetScript( [ 'debugInfo' => $debugInfo ] ),
+                               $context->getOutput()->getCSPNonce()
                        );
                }
 
index 4ddd151..398df01 100644 (file)
@@ -569,6 +569,7 @@ class LinksUpdate extends DataUpdate implements EnqueueableDataUpdate {
                                        'el_from' => $this->mId,
                                        'el_to' => $url,
                                        'el_index' => $index,
+                                       'el_index_60' => substr( $index, 0, 60 ),
                                ];
                        }
                }
index c078e90..1702264 100644 (file)
@@ -1300,11 +1300,14 @@ class LocalFile extends File {
         * @param User|null $user User object or null to use $wgUser
         * @param string[] $tags Change tags to add to the log entry and page revision.
         *   (This doesn't check $user's permissions.)
+        * @param bool $createNullRevision Set to false to avoid creation of a null revision on file
+        *   upload, see T193621
         * @return Status On success, the value member contains the
         *     archive name, or an empty string if it was a new file.
         */
        function upload( $src, $comment, $pageText, $flags = 0, $props = false,
-               $timestamp = false, $user = null, $tags = []
+               $timestamp = false, $user = null, $tags = [],
+               $createNullRevision = true
        ) {
                if ( $this->getRepo()->getReadOnlyReason() !== false ) {
                        return $this->readOnlyFatalStatus();
@@ -1361,7 +1364,8 @@ class LocalFile extends File {
                                $props,
                                $timestamp,
                                $user,
-                               $tags
+                               $tags,
+                               $createNullRevision
                        );
                        if ( !$uploadStatus->isOK() ) {
                                if ( $uploadStatus->hasMessage( 'filenotfound' ) ) {
@@ -1419,10 +1423,13 @@ class LocalFile extends File {
         * @param string|bool $timestamp
         * @param null|User $user
         * @param string[] $tags
+        * @param bool $createNullRevision Set to false to avoid creation of a null revision on file
+        *   upload, see T193621
         * @return Status
         */
        function recordUpload2(
-               $oldver, $comment, $pageText, $props = false, $timestamp = false, $user = null, $tags = []
+               $oldver, $comment, $pageText, $props = false, $timestamp = false, $user = null, $tags = [],
+               $createNullRevision = true
        ) {
                global $wgCommentTableSchemaMigrationStage, $wgActorTableSchemaMigrationStage;
 
@@ -1662,7 +1669,7 @@ class LocalFile extends File {
                        $formatter->setContext( RequestContext::newExtraneousContext( $descTitle ) );
                        $editSummary = $formatter->getPlainActionText();
 
-                       $nullRevision = Revision::newNullRevision(
+                       $nullRevision = $createNullRevision === false ? null : Revision::newNullRevision(
                                $dbw,
                                $descId,
                                $editSummary,
index ff6cfff..043e0f6 100644 (file)
@@ -50,6 +50,9 @@ use Wikimedia\ObjectFactory;
  *                             if 'class' is not specified, this is used as a map
  *                             through HTMLForm::$typeMappings to get the class name.
  *    'default'             -- default value when the form is displayed
+ *    'nodata'              -- if set (to any value, which casts to true), the data
+ *                             for this field will not be loaded from the actual request. Instead,
+ *                             always the default data is set as the value of this field.
  *    'id'                  -- HTML id attribute
  *    'cssclass'            -- CSS class
  *    'csshelpclass'        -- CSS class used to style help text
@@ -1604,9 +1607,10 @@ class HTMLForm extends ContextSource {
         * @param string $legend Legend text for the fieldset
         * @param string $section The section content in plain Html
         * @param array $attributes Additional attributes for the fieldset
+        * @param bool $isRoot Section is at the root of the tree
         * @return string The fieldset's Html
         */
-       protected function wrapFieldSetSection( $legend, $section, $attributes ) {
+       protected function wrapFieldSetSection( $legend, $section, $attributes, $isRoot ) {
                return Xml::fieldset( $legend, $section, $attributes ) . "\n";
        }
 
@@ -1689,7 +1693,9 @@ class HTMLForm extends ContextSource {
                                        if ( $fieldsetIDPrefix ) {
                                                $attributes['id'] = Sanitizer::escapeIdForAttribute( "$fieldsetIDPrefix$key" );
                                        }
-                                       $subsectionHtml .= $this->wrapFieldSetSection( $legend, $section, $attributes );
+                                       $subsectionHtml .= $this->wrapFieldSetSection(
+                                               $legend, $section, $attributes, $fields === $this->mFieldTree
+                                       );
                                } else {
                                        // Just return the inputs, nothing fancy.
                                        $subsectionHtml .= $section;
index aab8811..5066f28 100644 (file)
@@ -17,6 +17,9 @@ abstract class HTMLFormField {
        protected $mVFormClass = '';
        protected $mHelpClass = false;
        protected $mDefault;
+       /**
+        * @var array|bool|null
+        */
        protected $mOptions = false;
        protected $mOptionsLabelsNotFromMessage = false;
        protected $mHideIf = null;
index ba36888..49cbdee 100644 (file)
@@ -145,7 +145,7 @@ class OOUIHTMLForm extends HTMLForm {
                        [ 'class' => 'mw-htmlform-submit-buttons' ], "\n$buttons" ) . "\n";
        }
 
-       protected function wrapFieldSetSection( $legend, $section, $attributes ) {
+       protected function wrapFieldSetSection( $legend, $section, $attributes, $isRoot ) {
                // to get a user visible effect, wrap the fieldset into a framed panel layout
                $layout = new OOUI\PanelLayout( [
                        'expanded' => false,
index 44bdddb..a8fbed0 100644 (file)
@@ -82,16 +82,7 @@ class CurlHttpRequest extends MWHttpRequest {
                        // Don't interpret POST parameters starting with '@' as file uploads, because this
                        // makes it impossible to POST plain values starting with '@' (and causes security
                        // issues potentially exposing the contents of local files).
-                       // The PHP manual says this option was introduced in PHP 5.5 defaults to true in PHP 5.6,
-                       // but we support lower versions, and the option doesn't exist in HHVM 5.6.99.
-                       if ( defined( 'CURLOPT_SAFE_UPLOAD' ) ) {
-                               $this->curlOptions[CURLOPT_SAFE_UPLOAD] = true;
-                       } elseif ( is_array( $postData ) ) {
-                               // In PHP 5.2 and later, '@' is interpreted as a file upload if POSTFIELDS
-                               // is an array, but not if it's a string. So convert $req['body'] to a string
-                               // for safety.
-                               $postData = wfArrayToCgi( $postData );
-                       }
+                       $this->curlOptions[CURLOPT_SAFE_UPLOAD] = true;
                        $this->curlOptions[CURLOPT_POSTFIELDS] = $postData;
 
                        // Suppress 'Expect: 100-continue' header, as some servers
index 6eff6c9..c0005c5 100644 (file)
@@ -33,7 +33,7 @@ class Http {
         * @param string $method HTTP method. Usually GET/POST
         * @param string $url Full URL to act on. If protocol-relative, will be expanded to an http:// URL
         * @param array $options Options to pass to MWHttpRequest object.
-        *      Possible keys for the array:
+        *      Possible keys for the array:
         *    - timeout             Timeout length in seconds
         *    - connectTimeout      Timeout for connection, in seconds (curl only)
         *    - postData            An array of key-value pairs or a url-encoded form data
index 80f9b68..c5413b3 100644 (file)
@@ -45,8 +45,8 @@ class HttpRequestFactory {
                if ( !Http::$httpEngine ) {
                        Http::$httpEngine = function_exists( 'curl_init' ) ? 'curl' : 'php';
                } elseif ( Http::$httpEngine == 'curl' && !function_exists( 'curl_init' ) ) {
-                       throw new DomainException( __METHOD__ . ': curl (http://php.net/curl) is not installed, but' .
-                          ' Http::$httpEngine is set to "curl"' );
+                       throw new DomainException( __METHOD__ . ': curl (https://secure.php.net/curl) is not ' .
+                          'installed, but Http::$httpEngine is set to "curl"' );
                }
 
                if ( !isset( $options['logger'] ) ) {
@@ -61,7 +61,7 @@ class HttpRequestFactory {
                                        throw new DomainException( __METHOD__ . ': allow_url_fopen ' .
                                           'needs to be enabled for pure PHP http requests to ' .
                                           'work. If possible, curl should be used instead. See ' .
-                                          'http://php.net/curl.'
+                                          'https://secure.php.net/curl.'
                                        );
                                }
                                return new PhpHttpRequest( $url, $options, $caller, Profiler::instance() );
index 0636314..0f499c2 100644 (file)
@@ -46,21 +46,6 @@ class PhpHttpRequest extends MWHttpRequest {
                $certLocations = [];
                if ( $this->caInfo ) {
                        $certLocations = [ 'manual' => $this->caInfo ];
-               } elseif ( version_compare( PHP_VERSION, '5.6.0', '<' ) ) {
-                       // Default locations, based on
-                       // https://www.happyassassin.net/2015/01/12/a-note-about-ssltls-trusted-certificate-stores-and-platforms/
-                       // PHP 5.5 and older doesn't have any defaults, so we try to guess ourselves.
-                       // PHP 5.6+ gets the CA location from OpenSSL as long as it is not set manually,
-                       // so we should leave capath/cafile empty there.
-                       $certLocations = array_filter( [
-                               getenv( 'SSL_CERT_DIR' ),
-                               getenv( 'SSL_CERT_PATH' ),
-                               '/etc/pki/tls/certs/ca-bundle.crt', # Fedora et al
-                               '/etc/ssl/certs',  # Debian et al
-                               '/etc/pki/tls/certs/ca-bundle.trust.crt',
-                               '/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem',
-                               '/System/Library/OpenSSL', # OSX
-                       ] );
                }
 
                foreach ( $certLocations as $key => $cert ) {
index b64114c..95a171b 100644 (file)
@@ -17,6 +17,11 @@ class ImportableUploadRevisionImporter implements UploadRevisionImporter {
         */
        private $enableUploads;
 
+       /**
+        * @var bool
+        */
+       private $shouldCreateNullRevision = true;
+
        /**
         * @param bool $enableUploads
         * @param LoggerInterface $logger
@@ -29,6 +34,16 @@ class ImportableUploadRevisionImporter implements UploadRevisionImporter {
                $this->logger = $logger;
        }
 
+       /**
+        * Setting this to false will deactivate the creation of a null revision as part of the upload
+        * process logging in LocalFile::recordUpload2, see T193621
+        *
+        * @param bool $shouldCreateNullRevision
+        */
+       public function setNullRevisionCreation( $shouldCreateNullRevision ) {
+               $this->shouldCreateNullRevision = $shouldCreateNullRevision;
+       }
+
        /**
         * @return StatusValue
         */
@@ -100,7 +115,9 @@ class ImportableUploadRevisionImporter implements UploadRevisionImporter {
                                $flags,
                                false,
                                $importableRevision->getTimestamp(),
-                               $user
+                               $user,
+                               [],
+                               $this->shouldCreateNullRevision
                        );
                }
 
index 1f6110b..99d7186 100644 (file)
@@ -82,7 +82,7 @@ abstract class DatabaseUpdater {
                PopulateBacklinkNamespace::class,
                FixDefaultJsonContentPages::class,
                CleanupEmptyCategories::class,
-               AddRFCAndPMIDInterwiki::class,
+               AddRFCandPMIDInterwiki::class,
                PopulatePPSortKey::class,
                PopulateIpChanges::class,
        ];
@@ -974,6 +974,31 @@ abstract class DatabaseUpdater {
                return true;
        }
 
+       /**
+        * Run a maintenance script
+        *
+        * This should only be used when the maintenance script must run before
+        * later updates. If later updates don't depend on the script, add it to
+        * DatabaseUpdater::$postDatabaseUpdateMaintenance instead.
+        *
+        * The script's execute() method must return true to indicate successful
+        * completion, and must return false (or throw an exception) to indicate
+        * unsuccessful completion.
+        *
+        * @since 1.32
+        * @param string $class Maintenance subclass
+        * @param string $script Script path and filename, usually "maintenance/fooBar.php"
+        */
+       public function runMaintenance( $class, $script ) {
+               $this->output( "Running $script...\n" );
+               $task = $this->maintenance->runChild( $class );
+               $ok = $task->execute();
+               if ( !$ok ) {
+                       throw new RuntimeException( "Execution of $script did not complete successfully." );
+               }
+               $this->output( "done.\n" );
+       }
+
        /**
         * Set any .htaccess files or equivilent for storage repos
         *
@@ -1287,4 +1312,21 @@ abstract class DatabaseUpdater {
                 }
         }
 
+       /**
+        * Populates the externallinks.el_index_60 field
+        * @since 1.32
+        */
+       protected function populateExternallinksIndex60() {
+               if ( !$this->updateRowExists( 'populate externallinks.el_index_60' ) ) {
+                       $this->output(
+                               "Populating el_index_60 field, printing progress markers. For large\n" .
+                               "databases, you may want to hit Ctrl-C and do this manually with\n" .
+                               "maintenance/populateExternallinksIndex60.php.\n"
+                       );
+                       $task = $this->maintenance->runChild( 'PopulateExternallinksIndex60',
+                               'populateExternallinksIndex60.php' );
+                       $task->execute();
+                       $this->output( "done.\n" );
+               }
+       }
 }
index 1efe5d6..284d5dd 100644 (file)
@@ -990,6 +990,10 @@ abstract class Installer {
                        return true;
                }
 
+               if ( Shell::isDisabled() ) {
+                       return true;
+               }
+
                # Get a list of available locales.
                $result = Shell::command( '/usr/bin/locale', '-a' )
                        ->execute();
@@ -1133,7 +1137,7 @@ abstract class Installer {
                /**
                 * This needs to be updated something that the latest libicu
                 * will properly normalize.  This normalization was found at
-                * http://www.unicode.org/versions/Unicode5.2.0/#Character_Additions
+                * https://www.unicode.org/versions/Unicode5.2.0/#Character_Additions
                 * Note that we use the hex representation to create the code
                 * points in order to avoid any Unicode-destroying during transit.
                 */
@@ -1199,7 +1203,7 @@ abstract class Installer {
                $scriptTypes = [
                        'php' => [
                                "<?php echo 'ex' . 'ec';",
-                               "#!/var/env php5\n<?php echo 'ex' . 'ec';",
+                               "#!/var/env php\n<?php echo 'ex' . 'ec';",
                        ],
                ];
 
index e389135..44b4e30 100644 (file)
@@ -131,6 +131,11 @@ class MssqlUpdater extends DatabaseUpdater {
 
                        // 1.32
                        [ 'addTable', 'change_tag_def', 'patch-change_tag_def.sql' ],
+                       [ 'populateExternallinksIndex60' ],
+                       [ 'modifyfield', 'externallinks', 'el_index_60',
+                               'patch-externallinks-el_index_60-drop-default.sql' ],
+                       [ 'runMaintenance', DeduplicateArchiveRevId::class, 'maintenance/deduplicateArchiveRevId.php' ],
+                       [ 'addField', 'change_tag', 'ct_tag_id', 'patch-change_tag-tag_id.sql' ],
                ];
        }
 
index b4bb194..d70edea 100644 (file)
@@ -351,6 +351,11 @@ class MysqlUpdater extends DatabaseUpdater {
 
                        // 1.32
                        [ 'addTable', 'change_tag_def', 'patch-change_tag_def.sql' ],
+                       [ 'populateExternallinksIndex60' ],
+                       [ 'modifyfield', 'externallinks', 'el_index_60',
+                               'patch-externallinks-el_index_60-drop-default.sql' ],
+                       [ 'runMaintenance', DeduplicateArchiveRevId::class, 'maintenance/deduplicateArchiveRevId.php' ],
+                       [ 'addField', 'change_tag', 'ct_tag_id', 'patch-change_tag-tag_id.sql' ],
                ];
        }
 
index b08e26f..965187a 100644 (file)
@@ -150,6 +150,9 @@ class OracleUpdater extends DatabaseUpdater {
 
                        // 1.32
                        [ 'addTable', 'change_tag_def', 'patch-change_tag_def.sql' ],
+                       [ 'populateExternallinksIndex60' ],
+                       [ 'runMaintenance', DeduplicateArchiveRevId::class, 'maintenance/deduplicateArchiveRevId.php' ],
+                       [ 'addField', 'change_tag', 'ct_tag_id', 'patch-change_tag-tag_id.sql' ],
 
                        // KEEP THIS AT THE BOTTOM!!
                        [ 'doRebuildDuplicateFunction' ],
index c72e206..49419ea 100644 (file)
@@ -572,6 +572,16 @@ class PostgresUpdater extends DatabaseUpdater {
 
                        // 1.32
                        [ 'addTable', 'change_tag_def', 'patch-change_tag_def.sql' ],
+                       [ 'populateExternallinksIndex60' ],
+                       [ 'dropDefault', 'externallinks', 'el_index_60' ],
+                       [ 'runMaintenance', DeduplicateArchiveRevId::class, 'maintenance/deduplicateArchiveRevId.php' ],
+                       [ 'addPgField', 'change_tag', 'ct_tag_id', 'INTEGER NULL' ],
+                       [
+                               'addPgIndex',
+                               'change_tag',
+                               'change_tag_tag_id_id',
+                               '( ct_tag_id, ct_rc_id, ct_rev_id, ct_log_id )'
+                       ],
                ];
        }
 
@@ -907,6 +917,20 @@ END;
                }
        }
 
+       /**
+        * Drop a default value from a field
+        * @since 1.32
+        * @param string $table
+        * @param string $field
+        */
+       protected function dropDefault( $table, $field ) {
+               $info = $this->db->fieldInfo( $table, $field );
+               if ( $info->defaultValue() !== false ) {
+                       $this->output( "Removing '$table.$field' default value\n" );
+                       $this->db->query( "ALTER TABLE $table ALTER $field DROP DEFAULT" );
+               }
+       }
+
        protected function changeNullableField( $table, $field, $null, $update = false ) {
                $fi = $this->db->fieldInfo( $table, $field );
                if ( is_null( $fi ) ) {
index 76e1ca9..2b27d37 100644 (file)
@@ -215,6 +215,11 @@ class SqliteUpdater extends DatabaseUpdater {
 
                        // 1.32
                        [ 'addTable', 'change_tag_def', 'patch-change_tag_def.sql' ],
+                       [ 'populateExternallinksIndex60' ],
+                       [ 'modifyfield', 'externallinks', 'el_index_60',
+                               'patch-externallinks-el_index_60-drop-default.sql' ],
+                       [ 'runMaintenance', DeduplicateArchiveRevId::class, 'maintenance/deduplicateArchiveRevId.php' ],
+                       [ 'addField', 'change_tag', 'ct_tag_id', 'patch-change_tag-tag_id.sql' ],
                ];
        }
 
index bce07d3..846be6c 100644 (file)
@@ -108,7 +108,6 @@ class WebInstallerLanguage extends WebInstallerPage {
                $unwantedLanguageCodes = $wgExtraLanguageCodes +
                        LanguageCode::getDeprecatedCodeMapping();
                $languages = Language::fetchLanguageNames();
-               ksort( $languages );
                foreach ( $languages as $code => $lang ) {
                        if ( isset( $unwantedLanguageCodes[$code] ) ) {
                                continue;
index 81a107d..50c88ae 100644 (file)
@@ -76,7 +76,7 @@ class WebInstallerName extends WebInstallerPage {
                        $this->parent->getTextBox( [
                                'var' => 'wgMetaNamespace',
                                'label' => '', // @todo Needs a label?
-                               'attribs' => [ 'readonly' => 'readonly', 'class' => 'enabledByOther' ]
+                               'attribs' => [ 'class' => 'enabledByOther' ]
                        ] ) .
                        $this->getFieldsetStart( 'config-admin-box' ) .
                        $this->parent->getTextBox( [
index 9d7d0af..b8a2f8f 100644 (file)
        "config-env-bad": "جرى التحقق من البيئة. لا يمكنك تنصيب ميدياويكي.",
        "config-env-php": "بي إتش بي $1 مثبت.",
        "config-env-hhvm": "نصبت HHVM $1.",
+       "config-unicode-using-intl": "باستخدام [https://pecl.php.net/intl امتداد intl PECL] لتسوية يونيكود.",
+       "config-unicode-pure-php-warning": "<strong>تحذير:</strong> لا يتوفر [https://pecl.php.net/intl امتداد intl PECL] للتعامل مع تطبيع يونيكود; حيث يتراجع لإبطاء تنفيذ Pure-Pure;\nإذا كنت تدير موقعا عالي الزيارات، فتجب عليك القراءة قليلا في [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations تطبيع يونيكود].",
+       "config-unicode-update-warning": "<strong>تحذير:</strong> يستخدم الإصدار المثبت من برنامج تطبيع نظام يونيكود إصدارًا قديما من مكتبة [http://site.icu-project.org/ مشروع ICU];\nتجب عليك [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations الترقية] إذا كنت مهتما باستخدام يونيكود.",
+       "config-no-db": "لا يمكن العثور على مشغل قاعدة بيانات مناسب! تحتاج إلى تثبيت مشغل قاعدة بيانات PHP، \n{{PLURAL:$2|نوع قاعدة البيانات التالي مدعوم|أنواع قاعدة البيانات التالية مدعومة}} البيانات التالية مدعومة: $1.\n\nإذا قمت بتجميع PHP بنفسك، فقم بتكوينها مع تمكين عميل قاعدة البيانات، على سبيل المثال، باستخدام <code>./configure --with-mysqli</code>.\nإذا قمت بتثبيت PHP من حزمة Debian أو Ubuntu، فستحتاج أيضا إلى تثبيت، على سبيل المثال، حزمة <code>php5-mysql</code>.",
        "config-outdated-sqlite": "<strong>تحذير:</strong> لديك SQLite $1, which وهو أقل من الحد الأدنى المطلوب للنسخة $2. SQLite سوف يكون غير متوفر.",
-       "config-apc": "تثبيت [http://www.php.net/apc APC]",
-       "config-apcu": "تثبيت [http://www.php.net/apcu APCu]",
-       "config-wincache": "تثبيت [https://www.iis.net/download/WinCacheForPhp WinCache]",
+       "config-no-fts3": "<strong>تحذير:</strong> يتم تجميع SQLite بدون [//sqlite.org/fts3.html FTS3 module]; ستكون ميزات البحث غير متوفرة في هذه الواجهة الخلفية.",
+       "config-pcre-old": "<strong>فادح:</strong> مطلوب PCRE $1 أو أحدث،\nترتبط ثنائية PHP الخاصة بك بـPCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE مزيد من المعلومات].",
+       "config-pcre-no-utf8": "<strong>فادح:</strong> يبدو أن وحدة PCRE في PHP يتم تجميعها بدون دعم PCRE_UTF8، \nيتطلب ميدياويكي دعم UTF-8 ليعمل بشكل صحيح.",
+       "config-memory-raised": "<code>memory_limit</code> في PHP $1 ومرتفعة إلى $2.",
+       "config-memory-bad": "<strong>تحذير:</strong> في PHP <code>memory_limit</code> $1،\nهذا على الارجح منخفض جدا;\nقد يفشل التثبيت!",
+       "config-apc": "تثبيت [https://secure.php.net/apc APC]",
+       "config-apcu": "[https://secure.php.net/apcu APCu] مثبت",
+       "config-wincache": "تثبيت [https://www.iis.net/downloads/microsoft/wincache-extension WinCache]",
+       "config-no-cache-apcu": "<strong>تحذير:</strong> تعذر العثور على [https://secure.php.net/apcu APCu] أو [https://www.iis.net/downloads/microsoft/wincache-extension WinCache];\nكائن التخزين المؤقت غير ممكّّن.",
+       "config-mod-security": "<strong>تحذير:</strong> تم تمكين خادم الويب الخاص بك [https://modsecurity.org/ mod_security]/mod_security2، العديد من التكوينات الشائعة له سوف تتسبب في مشاكل لميدياويكي والبرامج الأخرى التي تسمح للمستخدمين بنشر محتوى عشوائي; \nإذا كان ذلك ممكنا، يجب تعطيل هذا، أو يمكنك الرجوع إلى [https://modsecurity.org/documentation/ توثيق mod_security] أو الاتصال بدعم مضيفك إذا واجهتك أخطاء عشوائية.",
        "config-diff3-bad": "جنو diff3 غير موجود.",
+       "config-git": "العثور على برنامج التحكم في إصدار جت <code>$1</code>.",
+       "config-git-bad": "برنامج التحكم في إصدار جت غير موجود.",
        "config-imagemagick": "تم العثور على ImageMagick: <code>$1</code>.\nسيتم تمكين تصغير الصور إذا قمت بتمكين التحميل.",
+       "config-gd": "وُجِدت مكتبة الرسومات GD المدمجة،\nسيتم تمكين الصورة المصغرة للصورة إذا قمت بتمكين المرفوعات.",
        "config-no-scaling": "لا يمكن أن تجد مكتبة GD أو ImageMagick; سيتم تعطيل تصغير الصور.",
        "config-no-uri": "<strong>خطأ:</strong>  لا يمكن أن تحدد URI الحالي.تم  إحباط التثبيت.",
+       "config-no-cli-uri": "<strong>تحذير:</strong> لم يتم تحديد <code>--scriptpath</code>، باستخدام الافتراضي: <code>$1</code>.",
        "config-using-server": "باستخدام اسم الخادم \"<nowiki>$1</nowiki\".",
        "config-using-uri": "باستخدام URL الخادم \"<nowiki>$1$2</nowiki>\".",
+       "config-uploads-not-safe": "<strong>تحذير:</strong>  الدليل الافتراضي للمرفوعات <code>$1</code> عرضة لتنفيذ سكريبتات عشوائية،\nعلى الرغم من أن ميدياويكي يتحقق من كل الملفات المرفوعة للتهديدات الأمنية، فمن المستحسن بشدة [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security#Upload_security إغلاق هذه الثغرة الأمنية] قبل تمكين المرفوعات.",
+       "config-no-cli-uploads-check": "<strong>تحذير:</strong> لم يتم تحديد الدليل الافتراضي للمرفوعات (<code>$1</code>) للقابلية للتأثر\nلتنفيذ برنامج تعسفي أثناء تثبيت CLI.",
+       "config-brokenlibxml": "يحتوي نظامك على مجموعة من إصدارات PHP وlibxml2 ويمكن أن تسبب فسادا للبيانات في ميدياويكي وتطبيقات الويب الأخرى;\nقم بالترقية إلى libxml2 2.7.3 أو أحدث ([https://bugs.php.net/bug.php؟id=45996 تم تدقيم العلة مع PHP]); \nتم إحباط التثبيت.",
+       "config-suhosin-max-value-length": "تم تثبيت Suhosin وتقييد وسيط GET <code>length</code> إلى $1 بايت،\nسيعمل مكون ResourceLoader في ميدياويكي حول هذا الحد، لكن ذلك سيؤدي إلى انخفاض مستوى الأداء، \nإذا كان ذلك ممكنا، فيجب تعيين <code>suhosin.get.max_value_length</code> على 1024 أو أعلى في <code>php.ini</code>، وتعيين <code>$wgResourceLoaderMaxQueryLength</code> لنفس القيمة في <code>LocalSettings.php</code>.",
+       "config-using-32bit": "<strong>تحذير:</strong> يبدو أن نظامك يعمل مع الأعداد الصحيحة 32 بت، هذا [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit لا يُنصَح به].",
        "config-db-type": "نوع قاعدة البيانات:",
        "config-db-host": "مضيف قاعدة البيانات:",
+       "config-db-host-help": "إذا كان خادم قاعدة البيانات موجودا في خادم مختلف، فأدخل اسم المضيف أو عنوان الآيبي هنا. \n\nإذا كنت تستخدم استضافة ويب مشتركة، فيجب أن يمنحك موفر الاستضافة اسم المضيف الصحيح في وثائقه. \n\nإذا كنت تقوم بالتثبيت على خادم ويندوز واستخدام MySQL، فإن استخدام \"localhost\" قد لا يعمل لاسم الخادم، إذا لم يتم ذلك، فجرب \"127.0.0.1\" لعنوان الآيبي المحلي. \n\nإذا كنت تستخدم PostgreSQL، فاترك هذا الحقل فارغا للاتصال عبر مقبس Unix.",
        "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": "حدِّد هذا الويكي",
        "config-db-name": "اسم قاعدة البيانات",
        "config-db-name-help": "اختر الاسم الذي يعرف الويكي الخاص بك. لا يجب أن يحتوي على مسافات. إذا كنت تستخدم استضافة المواقع المشتركة، مزود الاستضافة إما سيعطيك اسم قاعدة بيانات محددة لاستخدامها أو سيتيح لك إنشاء قواعد بيانات عن طريق لوحة التحكم.",
        "config-db-name-oracle": "سكيما قاعدة البيانات:",
+       "config-db-account-oracle-warn": "هناك ثلاثة سيناريوهات مدعومة لتثبيت Oracle كقاعدة بيانات خلفية: \n\nإذا كنت ترغب في إنشاء حساب قاعدة بيانات كجزء من عملية التثبيت، فيُرجَى تقديم حساب بدور SYSDBA كحساب قاعدة بيانات للتثبيت وتحديد بيانات الاعتماد المطلوبة لحساب الوصول إلى الإنترنت، وإلا يمكنك إما إنشاء حساب الوصول إلى الويب يدويا وتزويد الحساب فقط (إذا كان يتطلب صلاحيات لإنشاء كائنات المخطط) أو توفير حسابين مختلفين، أحدهما له امتيازات إنشاء وامتياز مقيد للدخول إلى الويب. \n\nيمكن العثور على البرنامج النصي لإنشاء حساب له امتيازات مطلوبة في دليل \"maintenance/oracle/\" لهذا التثبيت، ضع في اعتبارك أن استخدام حساب مقيد سيؤدي إلى تعطيل جميع إمكانات الصيانة باستخدام الحساب الافتراضي.",
        "config-db-install-account": "حساب المستخدم للتنصيب",
        "config-db-username": "اسم مستخدم قاعدة البيانات:",
        "config-db-password": "كلمة سر قاعدة البيانات:",
        "config-db-schema-help": "هذا المخطط عادة يكون على ما يرام. غيره إذا كنت تعرف أنك في حاجة إلى هذا فقط.",
        "config-pg-test-error": "لا يمكن الاتصال بقاعدة البيانات <strong>$1</strong>: $2",
        "config-sqlite-dir": "دليل بيانات SQLite:",
+       "config-sqlite-dir-help": "يخزن SQLite جميع البيانات في ملف واحد. \n\nيجب أن يكون الدليل الذي توفره قابلا للكتابة بواسطة خادم الويب أثناء التثبيت. \n\nيجب أن يكون <strong>غير</strong> متاحا عبر الويب؛ هذا هو سبب عدم وضعه في مكان ملفات PHP الخاصة بك. \n\nسيقوم المثبت بكتابة ملف <code>.htaccess</code> معه، ولكن إذا فشل ذلك، يمكن لشخص ما الوصول إلى قاعدة بياناتك الأولية، \nيتضمن ذلك بيانات المستخدم الأولية (عناوين البريد الإلكتروني وكلمات المرور المجزأة) بالإضافة إلى المراجعات المحذوفة والبيانات المحظورة الأخرى على الويكي. \n\nفكر في وضع قاعدة البيانات في مكان آخر تماما، على سبيل المثال في <code>/var/lib/mediawiki/yourwiki</code.",
        "config-oracle-def-ts": "جدولية افتراضية:",
        "config-oracle-temp-ts": "جدولية مؤقتة:",
        "config-type-mysql": "MySQL (أو متوافق)",
        "config-type-oracle": "أوراكل",
        "config-type-mssql": "خادم SQL لميكروسوفت",
        "config-support-info": "ميدياويكي يدعم نظم قواعد البيانات التالية: $1 إذا كنت لا ترى نظام قاعدة البيانات الذي تحاول استخدامه مدرجًا أدناه، اتبع الإرشادات المرتبطة فوق لتمكين الدعم.",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] هو الهدف الأساسي لميدياويكي وأفضل دعم له، يعمل ميدياويكي أيضا مع [{{int:version-db-mariadb-url}} MariaDB] و[{{int:version-db-percona-url}} Percona Server]، وهما متوافقان مع MySQL، ([https://secure.php.net/manual/en/mysqli.installation.php كيفية تجميع PHP مع دعم MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] هو نظام قاعدة بيانات مفتوح المصدر مشهور كبديل لـMySQL ([https://secure.php.net/manual/en/pgsql.installation.php كيفية تجميع PHP مع دعم PostgreSQL])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] هو نظام قاعدة بيانات خفيف مدعوم بشكل جيد. ([https://secure.php.net/manual/en/pdo.installation.php كيفية ترجمة PHP باستخدام دعم SQLite]، يستخدم PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] هي قاعدة بيانات مؤسسة تجارية. ([https://secure.php.net/manual/en/oci8.installation.php كيفية تجميع PHP مع دعم OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] هي قاعدة بيانات مؤسسة تجارية لويندوز. ([https://secure.php.net/manual/en/sqlsrv.installation.php كيفية تجميع PHP مع دعم SQLSRV])",
        "config-header-mysql": "إعدادات MySQL",
        "config-header-postgres": "إعدادات PostgreSQL",
        "config-header-sqlite": "إعدادات SQLite",
        "config-header-mssql": "إعدادات خادم Microsoft SQL",
        "config-invalid-db-type": "نوع قاعدة بيانات غير صحيح",
        "config-missing-db-name": "يجب عليك إدخال قيمة ل\"{{int:config-db-name}}\".",
+       "config-missing-db-host": "يجب إدخال قيمة لـ\"{{int:config-db-host}}\".",
        "config-missing-db-server-oracle": "يجب عليك إدخال قيمة ل\"{{int:config-db-host-oracle}}\".",
+       "config-invalid-db-server-oracle": "TNS قاعدة بيانات غير صالحة \"$1\";\nاستخدم إما \"اسم TNS\" أو سلسلة \"الاتصال السهل\" \"Easy Connect\" ([http://docs.oracle.com/cd/E11882_01/network.112/e10836/naming.htm طرقلتسمية في أوراكل]).",
+       "config-invalid-db-name": "اسم قاعدة بيانات غير صالح \"$1\". \nاستخدم فقط أحرف أسكي (az، AZ) وأرقاما (0-9) وشرطات سفلية (_).",
+       "config-invalid-db-prefix": "بادئة قاعدة بيانات غير صالحة \"$1\". \nاستخدم فقط أحرف أسكي (az، AZ) وأرقاما (0-9) وشرطات سفلية (_).",
        "config-connection-error": "$1.\nتحقق من المضيف، واسم المستخدم وكلمة المرور وحاول مرة أخرى.",
+       "config-invalid-schema": "مخطط غير صالح لميدياويكي \"$1\". \nاستخدم فقط أحرف أسكي (az، AZ) وأرقاما (0-9) وشرطات سفلية (_).",
        "config-db-sys-create-oracle": "المثبت يعتمد باستخدام حساب SYSDBA فقط لإنشاء حساب جديد.",
        "config-db-sys-user-exists-oracle": "حساب المستخدم \"$1\" موجود بالفعل; يمكن استخدام SYSDBA لإنشاء حساب جديد فقط!",
        "config-postgres-old": "PostgreSQL $1 أو لاحق مطلوب. لديك $2.",
        "config-mssql-old": "خادم Microsoft SQL $1 أو لاحق مطلوب. لديك $2.",
+       "config-sqlite-name-help": "اختر اسمًا يعرف الويكي الخاص بك، \nلا تستخدم مسافات أو شرطات، \nسيتم استخدام هذا لاسم ملف البيانات SQLite.",
+       "config-sqlite-parent-unwritable-group": "لا يمكن إنشاء دليل البيانات <code><nowiki>$1</nowiki></code>; لأن الدليل الأصلي <code><nowiki>$2</nowiki></code> غير قابل للكتابة بواسطة خادم الويب، \nحدد المثبت المستخدم الذي يعمل عليه خادم الويب الخاص بك،\nاجعل الدليل <code><nowiki>$3</nowiki></code> قابلا للكتابة بواسطته للمتابعة، \nفي نظام يونكس/لينوكس قم بـ: \n<pre>cd $2\nmkdir $3\nchgrp $4 $3\nchmod g+w $3</pre>",
+       "config-sqlite-parent-unwritable-nogroup": "لا يمكن إنشاء دليل البيانات <code><nowiki>$1</nowiki></code>; لأن الدليل الأصلي <code><nowiki>$2</nowiki></code> غير قابل للكتابة بواسطة خادم الويب، \nتعذر على المثبت تحديد المستخدم الذي يعمل عليه خادم الويب الخاص بك،\nاجعل الدليل <code><nowiki>$3</nowiki></code> قابلا للكتابة بواسطته للمتابعة، \nفي نظام يونكس/لينوكس قم بـ: \n\n<pre>cd $2\nmkdir $3\nchmod a+w $3</pre>",
        "config-sqlite-mkdir-error": "خطأ في إنشاء دليل البيانات \"$1\". تحقق من الموقع وحاول مرة أخرى.",
+       "config-sqlite-dir-unwritable": "غير قادر على الكتابة إلى الدليل \"$1\";\nغيِّر أذوناته حتى يتمكن خادم الويب من الكتابة إليه، وحاول مرة أخرى.",
        "config-sqlite-connection-error": "$1.\nتحقق من اسم دليل البيانات وقواعد البيانات أدناه وحاول مرة أخرى.",
        "config-sqlite-readonly": "الملف <code>$1</code> غير قابل للكتابة.",
        "config-sqlite-cant-create-db": "لا يمكن إنشاء ملف قاعدة البيانات <code>$1</code>.",
+       "config-sqlite-fts3-downgrade": "PHP يفتقد دعم FTS3، تخفيض الجداول.",
        "config-can-upgrade": "هناك جداول ميدياويكي في قاعدة البيانات هذه. للارتقاء بها إلى ميدياويكي $1; انقر على <strong>متابعة</strong>.",
+       "config-upgrade-done": "اكتملت الترقية; \n\nيمكنك الآن [$1 بدء استخدام الويكي الخاص بك]. \n\nإذا كنت ترغب في إعادة إنشاء ملف <code>LocalSettings.php</code>، فانقر فوق الزر أدناه،\n<strong>غير مستحسن</strong> في ما لم تكن تواجه مشاكل مع الويكي الخاص بك.",
+       "config-upgrade-done-no-regenerate": "اكتملت الترقية;\n\nيمكنك الآن [$1 بدء استخدام الويكي الخاص بك].",
        "config-regenerate": "إعادة تكوين LocalSettings.php ←",
        "config-show-table-status": "<code> إظهار جدول الحالة </code> فشل الاستعلام!",
        "config-unknown-collation": "<strong>تحذير:</strong> قاعدة بيانات يستخدم ترتيبا غير معروف.",
        "config-mysql-engine": "محرك التخزين",
        "config-mysql-innodb": "إنو دي بي",
        "config-mysql-myisam": "ماي إسام",
+       "config-mysql-myisam-dep": "<strong>تحذير:</strong> لقد اخترت MyISAM كمحرك تخزين لـMySQL، والذي لا يُنصَح باستخدامه مع ميدياويكي; لأنه:\n* بالكاد يدعم التزامن بسبب قفل الجدول \n* أكثر عرضة للفساد من المحركات الأخرى\n* لا يقوم الكود الأساسي لميدياويكي بمعالجة MyISAM دائما كما يجب\n\nإذا كان تثبيت MySQL يدعم InnoDB، فمن المستحسن جدا أن تختاره بدلا منه، \nإذا كان تثبيت MySQL لا يدعم InnoDB، فربما حان الوقت للترقية.",
+       "config-mysql-only-myisam-dep": "<strong>تحذير:</strong> MyISAMهو محرك التخزين الوحيد المتاح لـMySQL على هذا الجهاز، ولا يُنصَح باستخدامه مع ميدياويكي; لأنه:\n* بالكاد يدعم التزامن بسبب قفل الجدول \n* أكثر عرضة للفساد من المحركات الأخرى\n* لا يقوم الكود الأساسي لميدياويكي بمعالجة MyISAM دائما كما يجب\n\nتثبيت MySQL لا يدعم InnoDB; ربما حان الوقت للترقية.",
+       "config-mysql-engine-help": "<strong>InnoDB</strong> هو دائما الخيار الأفضل; لأنه يحتوي على دعم تزامن جيد.\n\nقد يكون <strong>MyISAM</strong> أسرع في تثبيت المستخدم الفردي أو للقراءة فقط،\nتميل قواعد بيانات MyISAM للتلف أكثر من قواعد بيانات InnoDB.",
        "config-mysql-charset": "مجموعة محارف قاعدة البيانات",
        "config-mysql-binary": "ثنائي",
        "config-mysql-utf8": "يو تي إف-8",
+       "config-mysql-charset-help": "في <strong>الوضع الثنائي</strong>، يقوم ميدياويكي بتخزين نص UTF-8 في قاعدة البيانات في الحقول الثنائية، \nهذا أكثر كفاءة من وضع UTF-8 الخاص بـMySQL، ويسمح لك باستخدام النطاق الكامل لأحرف يونيكود. \n\nفي <strong>وضع UTF-8</strong>، ستعرف MySQL ما هي مجموعة البيانات التي تقوم بها، ويمكنها تقديمها وتحويلها بشكل مناسب، ولكنها لن تسمح لك بتخزين الحروف فوق [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Basic Multilingual Plane].",
        "config-mssql-auth": "نوع الاستيثاق:",
+       "config-mssql-install-auth": "حدد نوع المصادقة الذي سيتم استخدامه للاتصال بقاعدة البيانات أثناء عملية التثبيت. \nإذا حددت \"{{int:config-mssql-windowsauth}}\"، فسيتم استخدام بيانات اعتماد أي مستخدم يعمل عليه خادم الويب.",
+       "config-mssql-web-auth": "حدد نوع المصادقة الذي سيستخدمه خادم الويب للاتصال بخادم قاعدة البيانات، أثناء التشغيل العادي للويكي. \nإذا حددت \"{{int:config-mssql-windowsauth}}\"، فسيتم استخدام بيانات اعتماد أي مستخدم يعمل عليه خادم الويب.",
        "config-mssql-sqlauth": "مصادقة خادم SQL",
        "config-mssql-windowsauth": "مصادقة ويندوز",
        "config-site-name": "اسم الويكي:",
+       "config-site-name-help": "سيظهر هذا في شريط عنوان المتصفح وفي أماكن أخرى مختلفة.",
        "config-site-name-blank": "أدخل اسم موقع.",
        "config-project-namespace": "نطاق المشروع:",
        "config-ns-generic": "المشروع",
        "config-ns-site-name": "مثل اسم الويكي: $1",
        "config-ns-other": "أخرى (حدد)",
        "config-ns-other-default": "ماي ويكي",
+       "config-project-namespace-help": "مثال ويكيبيديا التالي، يبقي العديد من الويكيات صفحات سياساتها منفصلة عن صفحات محتواها، في '''نطاق المشروع'''، \nتبدأ جميع عناوين الصفحات في هذا النطاق ببادئة معينة، والتي يمكنك تحديدها هنا، \nعادة، يتم اشتقاق هذه البادئة من اسم الويكي، ولكنها لا يمكن أن تحتوي على أحرف ترقيم مثل \"#\" أو \":\".",
        "config-ns-invalid": "النطاق المحدد \"<nowiki>$1</nowiki>\" غير صالح.\nحدد نطاق مشروع مختلف.",
        "config-ns-conflict": "النطاق المحدد \"<nowiki>$1</ nowiki>\" يتعارض مع نطاق ميدياويكي الافتراضي. حدد نطاق مشروع مختلف.",
        "config-admin-box": "حساب إداري",
        "config-admin-error-password": "خطأ داخلي عند عند وضع كلمة مرور للإداري \"<nowiki>$1</nowiki>\": <pre>$2</pre>.",
        "config-admin-error-bademail": "لقد قمت بإدخال عنوان البريد الإلكتروني غير صالح.",
        "config-subscribe": "اشترك في [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce نشر إعلانات القائمة البريدية].",
+       "config-subscribe-help": "هذه قائمة بريدية ذات حجم منخفض تُستخدَم لإعلانات الإصدار، بما في ذلك إعلانات الأمان المهمة، \nيجب عليك الاشتراك فيها وتحديث تثبيت ميدياويكي الخاص بك عندما تظهر إصدارات جديدة.",
        "config-subscribe-noemail": "حاولت الاشتراك في القائمة البريدية الخاصة بإصدار إعلانات دون تقديم عنوان بريد إلكتروني. يُرجَى إدخال عنوان بريد إلكتروني إذا كنت ترغب في الاشتراك في القائمة البريدية.",
        "config-pingback": "تبادل البيانات حول هذا التثبيت مع مطوري ميدياويكي.",
+       "config-pingback-help": "إذا قمت بتحديد هذا الخيار، سيقوم ميدياويكي بشكل دوري باختبار https://www.mediawiki.org مع بيانات أساسية حول نسخة ميدياويكي، تتضمن هذه البيانات، على سبيل المثال، نوع النظام وإصدار PHP والواجهة الخلفية لقاعدة البيانات، تشارك مؤسسة ويكيميديا ​​هذه البيانات مع مطوري ميدياويكي للمساعدة في توجيه جهود التطوير المستقبلية، سيتم إرسال البيانات التالية لنظامك:\n<pre>$1</pre>",
        "config-almost-done": "لقد شارفت على الانتهاء! يمكنك الآن تخطي التكوين المتبقي وتثبيت الويكي الآن.",
        "config-optional-continue": "اسألني المزيد من الأسئلة",
        "config-optional-skip": "إنني أشعر بالملل بالفعل، فقط قم بتثبيت الويكي",
        "config-profile-no-anon": "إنشاء الحساب مطلوب",
        "config-profile-fishbowl": "المحررون المخولون فقط",
        "config-profile-private": "ويكي خاص",
+       "config-profile-help": "تعمل الويكيات بشكل أفضل عندما تسمح لأكبر عدد ممكن من الأشخاص بتحريرها قدر الإمكان، \nفي ميدياويكي، من السهل مراجعة التغييرات الأخيرة، وإعادة أي ضرر يحدث من قبل مستخدمين سذج أو ضارين، \n\nومع ذلك، وجد الكثيرون أن ميدياويكي مفيد في مجموعة متنوعة من الأدوار، وفي بعض الأحيان ليس من السهل إقناع الجميع بمزايا طريقة الويكي; \nلذلك لديك الخيار. \n\nيسمح النموذج <strong>{{int:config-profile-wiki}}</strong> لأي شخص بالتحرير، دون تسجيل الدخول. \nويكي بـ<strong>{{int:config-profile-no-anon}}</strong> يوفر مساءلة إضافية، ولكنه قد يمنع المساهمين العاديين. \n\nيسمح السيناريو <strong>{{int:config-profile-fishbowl}}</strong> للمستخدمين المعتمدين بالتحرير، ولكن يمكن للجمهور عرض الصفحات، بما في ذلك التاريخ.\nيتيح <strong>{{int:config-profile-private}}</strong> للمستخدمين المعتمدين فقط عرض الصفحات، مع السماح لنفس المجموعة بالتعديل. \n\nتتوفر تكوينات صلاحيات مستخدم أكثر تعقيدًا بعد التثبيت، راجع [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:User_rights إدخال الدليل ذي الصلة].",
        "config-license": "حقوق النسخ والترخيص:",
        "config-license-none": "لا تذييل ترخيص",
        "config-license-cc-by-sa": "المشاع الإبداعي النسبة للمؤلف المشاركة بالمثل",
        "config-license-gfdl": "رخصة جنو للوثائق الحرة 1.3 أو لاحقة",
        "config-license-pd": "ملكية عامة",
        "config-license-cc-choose": "اختر ترخيص مشاع إبداعي مخصص",
+       "config-license-help": "يضع العديد من الويكيات العامة جميع المساهمات تحت [https://freedomdefined.org/Definition خصة حرة]، \nوهذا يساعد على خلق شعور بالملكية المجتمعية ويشجع على المساهمة طويلة الأجل، \nليس من الضروري عموما استخدام ويكي خاص أو شركة. \n\nإذا كنت تريد أن تكون قادرا على استخدام النص من ويكيبيديا، وتريد أن تكون ويكيبيديا قادرة على قبول النص الذي تم نسخه من الويكي الخاص بك، فيجب عليك اختيار <strong>{{int:config-license-cc-by-sa}}</strong>. \n\nاستخدمت ويكيبيديا في السابق رخصة جنو للوثائق الحرة، \nGFDL هو ترخيص صالح، ولكن من الصعب فهمه، \nمن الصعب أيضا إعادة استخدام المحتوى المرخص بموجب GFDL.",
        "config-email-settings": "إعدادات البريد الإلكتروني",
        "config-enable-email": "تمكين البريد الإلكتروني الصادرة",
-       "config-enable-email-help": "إذا كنت تريد إرسال بريد إلكتروني إلى العمل، [http://www.php.net/manual/en/mail.configuration.php إعدات بريد PHP's] تحتاج لأن يتم تكوينها بشكل صحيح. إذا كنت لا تريد أيا من ميزات البريد الإلكتروني، يمكنك تعطيلها هنا.",
+       "config-enable-email-help": "إذا كنت تريد إرسال بريد إلكتروني إلى العمل، [Config-dbsupport-oracle/manual/en/mail.configuration.php إعدات بريد PHP's] تحتاج لأن يتم تكوينها بشكل صحيح. إذا كنت لا تريد أيا من ميزات البريد الإلكتروني، يمكنك تعطيلها هنا.",
        "config-email-user": "تفعيل البريد الإلكتروني من المستخدم إلى مستخدم آخر",
        "config-email-user-help": "يتيح لكل المستخدمين إرسال رسائل بريد إلكتروني إلى بعضهم البعض إذا فعَّلوا هذا الخيار في تفضيلاتهم.",
        "config-email-usertalk": "فعل إخطارات صفحات نقاش المستخدمين",
        "config-email-watchlist": "تمكين إشعارات قائمة المراقبة",
        "config-email-watchlist-help": "السماح للمستخدمين بالحصول على إشعارات حول صفحاتهم المراقبة إذا كانوا قد مكنوها في تفضيلاتهم.",
        "config-email-auth": "تمكين مصادقة البريد الإلكتروني",
+       "config-email-auth-help": "إذا تم تمكين هذا الخيار، يتعين على المستخدمين تأكيد عنوان بريدهم الإلكتروني باستخدام رابط يتم إرساله إليهم عند تعيينهم أو تغييره. \nيمكن لعناوين البريد الإلكتروني الموثوقة فقط تلقي رسائل البريد الإلكتروني من المستخدمين الآخرين أو تغيير رسائل الإشعارات الإلكترونية. \nيعد تعيين هذا الخيار <strong> موصى به</strong> لمواقع الويكي العامة بسبب احتمال إساءة استخدام ميزات البريد الإلكتروني.",
        "config-email-sender": "عنوان البريد الإلكتروني المُرسِل:",
+       "config-email-sender-help": "أدخل عنوان البريد الإلكتروني لاستخدامه كعنوان المرسل في البريد الإلكتروني الصادر، \nهذا هو المكان الذي سيتم إرساله إلى المستبعد،\nتتطلب العديد من خوادم البريد أن يكون جزء اسم النطاق صالحا على الأقل.",
        "config-upload-settings": "الصور وتحميل الملفات",
        "config-upload-enable": "تمكين تحميل الملفات",
+       "config-upload-help": "من المحتمل أن تؤدي عمليات رفع الملفات إلى تعريض الخادم لمخاطر أمنية. \nلمزيد من المعلومات; اقرأ [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security قسم الأمن] في الدليل. \n\nلتمكين رفع الملفات; قم بتغيير الوضع في الدليل الفرعي <code>الصور</code> تحت الدليل الرئيسي لميدياويكي كي يتمكن خادم الويب من الكتابة إليه، \nثم قم بتمكين هذا الخيار.",
        "config-upload-deleted": "المجلد للملفات المحذوفة:",
+       "config-upload-deleted-help": "اختر دليلا لأرشفة الملفات المحذوفة،\nمن الناحية المثالية، لا يمكن الوصول إلى هذا من الويب.",
        "config-logo": "مسار الشعار:",
+       "config-logo-help": "يحتوي المظهر الافتراضي لميدياويكي على مساحة لشعار 135x160 بكسل فوق قائمة الشريط الجانبي، \nارفع صورة بالحجم المناسب، وأدخل المسار هنا. \n\nيمكنك استخدام <code>$wgStylePath</code> أو <code>$wgScriptPath</code> إذا كان شعارك مرتبطا بتلك المسارات. \n\nإذا كنت لا تريد شعارا، فاترك هذا الصندوق فارغا.",
        "config-instantcommons": "تمكين الاستخدام الفوري لويكيميديا كومنز InstantCommons",
+       "config-instantcommons-help": "[https://www.mediawiki.org/wiki/InstantCommons كومنز الفوري] هي ميزة تسمح للويكي باستخدام الصور والأصوات والوسائط الأخرى الموجودة على موقع [https://commons.wikimedia.org/ ويكيميديا كومنز]،\nمن أجل القيام بذلك; يتطلب ميدياويكي الوصول إلى الإنترنت. \n\nلمزيد من المعلومات حول هذه الميزة، بما في ذلك تعليمات حول كيفية إعدادها لمواقع ويكي بخلاف ويكيميديا كومنز; يُرجَى الرجوع إلى [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgForeignFileRepos الدليل].",
        "config-cc-error": "لم يعطِ منتقي رخصة المشاع الإبداعي أية نتيجة; أدخل اسم الترخيص يدويا.",
        "config-cc-again": "اختر مجددًا",
        "config-cc-not-chosen": "اختر أي ترخيص تريده ثم اضغط على \"متابعة\".",
        "config-advanced-settings": "ضبط متقدم",
        "config-cache-options": "إعدادات التخزين المؤقت الكائن:",
+       "config-cache-help": "يُستخدَم التخزين المؤقت للأداة لتحسين سرعة ميدياويكي عن طريق تخزين البيانات المستخدمة بشكل متكرر، \nيتم تشجيع المواقع المتوسطة والكبيرة إلى حد كبير على تمكينه، وستشاهد المواقع الصغيرة الفوائد أيضا.",
        "config-cache-none": "لا يوجد تخزين مؤقت (هذا لا يزيل أية وظيفة، لكن قد تتأثر السرعة على مواقع الويكي الكبيرة)",
-       "config-cache-accel": "كائن التخزين المؤقت PHP (APC أو APCu أو  XCache أو WinCache)",
+       "config-cache-accel": "كائن التخزين المؤقت PHP (APC أو APCu أو  XCache أو XCache أو WinCache)",
        "config-cache-memcached": "استخدم Memcached (يتطلب إعدادت إضافية)",
        "config-memcached-servers": "خوادم Memcached:",
+       "config-memcached-help": "قائمة عناوين الآيبي لاستخدامها في Memcached،\nيجب تحديد واحد لكل سطر وتحديد المنفذ المراد استخدامه. على سبيل المثال:\n 127.0.0.1:11211\n 192.168.1.25:1234",
+       "config-memcache-needservers": "لقد حددت Memcached كنوع ذاكرة تخزين مؤقت ولكن لم تحدد أية خوادم.",
+       "config-memcache-badip": "لقد أدخلت عنوان آيبي غير صالح لـMemcached: $1.",
+       "config-memcache-noport": "لم تحدد منفذا لاستخدامه في خادم Memcached: $1،\nإذا كنت لا تعرف المنفذ، يكون الافتراضي هو 11211.",
+       "config-memcache-badport": "يجب أن تتراوح أرقام منافذ الذاكرة بين $1 و$2.",
        "config-extensions": "امتدادات",
        "config-extensions-help": "تم الكشف عن الملحقات المذكورة أعلاه في دليل <code>./ملحقاتك</code>، ويمكن أن يتطلب تكوينا إضافيا، ولكن يمكنك تمكينها الآن.",
        "config-skins": "الواجهات",
+       "config-skins-help": "تم اكتشاف المظاهر المدرجة أعلاه في دليل <code>./skins</code>، يجب عليك تمكين واحد على الأقل، واختيار الافتراضي.",
        "config-skins-use-as-default": "استخدم هذه الواجهة كافتراضية",
+       "config-skins-missing": "لم يتم العثور على مظاهر; سيستخدم ميدياويكي مظهرا متراجعا حتى تقوم بتركيب بعض المناسب منها.",
+       "config-skins-must-enable-some": "يجب عليك اختيار واحد على الأقل من المظاهر للتمكين.",
+       "config-skins-must-enable-default": "يجب تمكين المظهر المختار كإعداد افتراضي.",
        "config-install-alreadydone": "<strong>تحذير:</strong> يبدو أنك قد قمت بالفعل بتثبيت ميدياويكي وتحاول تثبيته مرة أخرى. الرجاء التوجه إلى الصفحة التالية.",
        "config-install-begin": "عن طريق الضغط على \"{{int:config-continue}}\"، سوف تبدأ تثبيت ميدياويكي. إذا كنت لا تزال ترغب في إجراء تغييرات، اضغط على \"{{int:config-back}}\".",
        "config-install-step-done": "تم بنجاح",
        "config-install-database": "إنشاء قاعدة البيانات",
        "config-install-schema": "إنشاء السكيما",
        "config-install-pg-schema-not-exist": "مخطط PostgreSQL غير موجود.",
+       "config-install-pg-schema-failed": "فشل إنشاء الجداول;\nتأكد من أن المستخدم \"$1\" يمكن أن يكتب إلى المخطط \"$2\".",
        "config-install-pg-commit": "تنفيذ التغييرات",
        "config-install-pg-plpgsql": "التحقق من لغة PL/pgSQL",
        "config-pg-no-plpgsql": "تحتاج إلى تثبيت لغة PL/pgSQL في قاعدة البيانات $1",
        "config-pg-no-create-privs": "الحساب الذي حددته للتنزيل ليست لديه امتيازات كافية لإنشاء حساب.",
+       "config-pg-not-in-role": "الحساب الذي حددته لمستخدم الويب موجود بالفعل، \nالحساب الذي حددته للتثبيت ليس مستخدما متميزا وليس عضوا في دور مستخدم الويب; لذلك لا يمكنه إنشاء كائنات يملكها مستخدم الويب. \n\nميدياويكي حاليا يتطلب أن تكون الجداول مملوكة من قبل مستخدم الويب; يُرجَى تحديد اسم حساب ويب آخر، أو النقر فوق \"رجوع\" وتحديد مستخدم تثبيت متميز مناسب.",
        "config-install-user": "إنشاء مستخدم قاعدة البيانات",
        "config-install-user-alreadyexists": "المستخدم \"$1\" موجود بالفعل",
        "config-install-user-create-failed": "إنشاء مستخدم \"$1\" فشل:$2",
        "config-install-mainpage-failed": "لم يتمكن من إدراج الصفحة الرئيسية: $1",
        "config-install-done": "<strong>مبروك!</strong>\nلقد قمت بتثبيت ميدياوكي.\n\nقام المثبت بتوليد ملف <code>LocalSettings.php</code>.\nيحتوي هذا الملف على كل تضبيطاتك.\n\nسيتطلب تشغيل الويكي منك تنزيل هذا الملف ووضعه في مجلد التثبيت الخاص بالويكي (نفس المجلد المحتوي على <code>index.php</code>). سيبدأ التنزيل تلقائيا.\n\nلو لم يُعرض عليك التنزيل أو قمت أنت بالغائه، يمكنك تنزيله بالضغط على الوصلة أدناه:\n\n$3\n\n<strong>تنبيه:</strong> لو لم تقم بهذا الآن، لن يكن ملف الضبط متاحا لك لاحقا إذا غادرت التثبيت بدون تنزيله.\n\nعندما تنتهي من وضع الملف بمكانه، يمكنك <strong>[$2 دخول الويكي]</strong>.",
        "config-install-done-path": "<strong>مبروك!</strong>\nلقد قمت بتثبيت ميدياوكي.\n\nقام المثبت بتوليد ملف <code>LocalSettings.php</code>.\nيحتوي هذا الملف على كل تضبيطاتك.\n\nسيتطلب تشغيل الويكي منك تنزيل هذا الملف ووضعه في <code>$4</code> (نفس المجلد المحتوي على index.php). سيبدأ التنزيل تلقائيا.\n\nلو لم يُعرض عليك التنزيل أو قمت أنت بالغائه، يمكنك تنزيله بالضغط على الوصلة أدناه:\n\n$3\n\n<strong>تنبيه:</strong> لو لم تقم بهذا الآن، لن يكن ملف الضبط متاحا لك لاحقا إذا غادرت التثبيت بدون تنزيله.\n\nعندما تنتهي من وضع الملف بمكانه، يمكنك <code>[$2 دخول الويكي]</strong>.",
+       "config-install-success": "لقد تم تثبيت ميدياويكي بنجاح; يمكنك الآن \nزيارة <$1$2> لعرض الويكي الخاص بك. \nإذا كانت لديك أسئلة، فاطلع على قائمة الأسئلة الشائعة: \n<https://www.mediawiki.org/wiki/Manual:FAQ> أو استخدم أحد \nمنتديات الدعم المرتبطة بهذه الصفحة.",
        "config-download-localsettings": "تنزيل <code>LocalSettings.php</code>",
        "config-help": "مساعدة",
        "config-help-tooltip": "اضغط للتوسيع",
        "config-nofile": "لا يمكن العثور على الملف \"$1\". هل حُذف؟",
        "config-extension-link": "هل كنت تعلم أن الويكي الخاصة بك تدعم [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions الامتدادات]؟\n\nيمكنك تصفح [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category الامتدادات حسب التصنيف] أو [https://www.mediawiki.org/wiki/Extension_Matrix مصفوفة الامتدادت] لترى القائمة الكاملة للامتدادات.",
+       "config-skins-screenshots": "$1 (لقطات شاشة: $2)",
+       "config-extensions-requires": "$1 (يتطلب $2)",
        "config-screenshot": "لقطة شاشة",
        "mainpagetext": "<strong>تم تثبيت ميدياويكي بنجاح.</strong>",
-       "mainpagedocfooter": "استشر [https://meta.wikimedia.org/wiki/Help:Contents دليل المستخدم] لمعلومات حول استخدام برنامج الويكي.\n\n== البداية ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings قائمة إعدادات الضبط]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ أسئلة متكررة حول ميدياويكي]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce القائمة البريدية الخاصة بإصدار ميدياويكي]"
+       "mainpagedocfooter": "استشر [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents دليل المستخدم] لمعلومات حول استخدام برنامج الويكي.\n\n== البداية ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings قائمة إعدادات الضبط]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ أسئلة متكررة حول ميدياويكي]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce القائمة البريدية الخاصة بإصدار ميدياويكي]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam تعلم كيفية مكافحة السخام في الويكي الخاص بك]"
 }
index c449110..b640402 100644 (file)
        "config-pcre-no-utf8": "<strong>Erru fatal:</strong> Paez que'l módulu PCRE de PHP foi compiláu ensin el soporte PCRE_UTF8.\nMediaWiki requier compatibilidá con UTF_8 pa furrular correutamente.",
        "config-memory-raised": "El parámetru <code>memory_limit</code> de PHP ye $1. Auméntase a $2.",
        "config-memory-bad": "<strong>Alvertencia:</strong>: el parámetru <code>memory_limit</code> de PHP ye $1.\nProbablemente sía demasiáu baxu.\n¡La instalación puede fallar!",
-       "config-apc": "[http://www.php.net/apc APC] ta instaláu",
-       "config-apcu": "[http://www.php.net/apcu APCu] ta instaláu",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] ta instaláu",
-       "config-no-cache-apcu": "<strong>Atención:</strong> Nun pudo alcontrase [http://www.php.net/apcu APCu] o [http://www.iis.net/download/WinCacheForPhp WinCache].\nLa caché d'oxetos nun ta activada.",
+       "config-apc": "[https://secure.php.net/apc APC] ta instaláu",
+       "config-apcu": "[https://secure.php.net/apcu APCu] ta instaláu",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] ta instaláu",
+       "config-no-cache-apcu": "<strong>Atención:</strong> Nun pudo alcontrase [https://secure.php.net/apcu APCu] o [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nLa caché d'oxetos nun ta activada.",
        "config-mod-security": "<strong>Alvertencia:</strong> El to servidor web tien activáu [https://modsecurity.org/mod_security]/mod_security2 .Munches de les sos configuraciones comunes pueden causar problemes a MediaWiki o otru software que dexe a los usuarios publicar conteníu arbitrario. De ser posible, tendríes de desactivalo. Si non, consulta la  [https://modsecurity.org/documentation/ mod_security documentation] o contacta col alministrador del to servidor si atopes erros aleatorios.",
        "config-diff3-bad": "Nun s'alcontró GNU diff3.",
        "config-git": "Alcontróse'l software de control de versiones Git: <code>$1</code>.",
        "config-type-mysql": "MySQL (o compatible)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki ye compatible colos siguientes sistemes de bases de datos:\n\n$1\n\nSi nun atopes na llista el sistema de base de datos que tas intentando utilizar, sigue les instrucciones enllazaes enriba p'activar la compatibilidá.",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ye un sistema comercial de base de datos empresariales pa Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Cómo compilar PHP con compatibilidá pa SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ye un sistema comercial de base de datos empresariales pa Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Cómo compilar PHP con compatibilidá pa SQLSRV])",
        "config-header-mysql": "Configuración de MySQL",
        "config-header-postgres": "Configuración de PostgreSQL",
        "config-header-sqlite": "Configuración de SQLite",
        "config-license-cc-choose": "Escoyer una llicencia Creative Commons  personalizada",
        "config-email-settings": "Configuración de corréu electrónicu",
        "config-enable-email": "Activar el corréu electrónicu de salida",
-       "config-enable-email-help": "Si quies que'l corréu electrónicu funcione, les [http://www.php.net/manual/en/mail.configuration.php preferencies de corréu de PHP] tienen de tar configuraes correutamente.\nSi nun quies les funciones de corréu electrónicu, puedes desactivales equí.",
+       "config-enable-email-help": "Si quies que'l corréu electrónicu funcione, les [Config-dbsupport-oracle/manual/en/mail.configuration.php preferencies de corréu de PHP] tienen de tar configuraes correutamente.\nSi nun quies les funciones de corréu electrónicu, puedes desactivales equí.",
        "config-email-user": "Activar el corréu electrónicu ente usuarios",
        "config-logo": "URL del logo:",
        "config-instantcommons": "Activar Instant Commons",
index a9c2c7f..f08580f 100644 (file)
@@ -67,9 +67,9 @@
        "config-pcre-no-utf8": "'''Фаталь хата'''. PHP өсөн PCRE модуле  PCRE_UTF8 менән яраҡлыштырылмаған.\nMediaWiki дөрөҫ эшләһен өсөн UTF-8 талап ителә.",
        "config-memory-raised": "Хәтер сикләнгән PHP  (<code>memory_limit</code>)  $1  $2 тиклем арттырылған.",
        "config-memory-bad": "'''Иғтибар:''' PHP күләме <code>memory_limit</code> $1 тәшкил итә.\nБәлки, был саманан тыш аҙҙыр. \nҠуйылыштың уңышһыҙлыҡҡа осрауы бар!",
-       "config-apc": "[http://www.php.net/apc APC] урынлаштырылды",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] урынлыштырылды",
-       "config-no-cache-apcu": "'''Иғтибар:'''  [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] табылманы йәки [http://www.iis.net/download/WinCacheForPhp WinCache].\nОбъекттарҙы кэшлау һүндереләсәк..",
+       "config-apc": "[https://secure.php.net/apc APC] урынлаштырылды",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] урынлыштырылды",
+       "config-no-cache-apcu": "'''Иғтибар:'''  [https://secure.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] табылманы йәки [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nОбъекттарҙы кэшлау һүндереләсәк..",
        "config-mod-security": "<strong>Иғтибар</strong>: һеҙҙең веб-серверығыҙҙа [https://modsecurity.org/ mod_security]/mod_security2 ҡабыҙылған. Уның күп кенә стандарт көйләүҙәре MediaWiki йәки бүтән ПО ҡулланыусыларға серверға ирекле контент ебәрегрә мөмкинлек буйынса проблемалар тыуҙырыуы мөмкин.\nКөтөлмәгән хаталарға тап булһағыҙ, ошонда [https://modsecurity.org/documentation/ документации mod_security]йәки үҙегеҙҙең хостинг-провайдерығыҙға мөрәжәғәт итегеҙ.",
        "config-diff3-bad": "GNU diff3 табылманы.",
        "config-git": "Git өлгөләрҙе контролләү системаһы табылды: <code>$1</code>.",
        "config-type-mysql": "MySQL (йәки тура килгән)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki -ла түбәндәге СУБД бар:\n\n$1\n\nӘгәр мәғлүмәт һаҡлау системаһын исемлектә күрмәһәгеҙ, рөхсәт алыу өсөн өҫтәге һылтанмалағы инструкция буйынса эш итегеҙ.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] — MediaWiki-ҙың иҫ яҡшы эшләгән төп мәғлүмәттәр базаһы.  MediaWiki шулай уҡ MySQL-тап килгән [{{int:version-db-mariadb-url}} MariaDB] һәм [{{int:version-db-percona-url}} Percona Server] менән эшләй. ([http://www.php.net/manual/ru/mysql.installation.php MySQL-ярҙамында PHP туплау инструкцияһы])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] —  СУБД-ның популяр открыткаһы, MySQL өсөн альтернатива.\nТөҙәтелмәгән хаталар булыуы мөмкин, эш схемаһында ҡулланыу тәҡдим ителмәй. ([http://www.php.net/manual/ru/pgsql.installation.php  PostgreSQL рөхсәт ителгән РНР йыйыу инструкцияһы]).",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] — MediaWiki-ҙың иҫ яҡшы эшләгән төп мәғлүмәттәр базаһы.  MediaWiki шулай уҡ MySQL-тап килгән [{{int:version-db-mariadb-url}} MariaDB] һәм [{{int:version-db-percona-url}} Percona Server] менән эшләй. ([https://secure.php.net/manual/ru/mysql.installation.php MySQL-ярҙамында PHP туплау инструкцияһы])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] —  СУБД-ның популяр открыткаһы, MySQL өсөн альтернатива.\nТөҙәтелмәгән хаталар булыуы мөмкин, эш схемаһында ҡулланыу тәҡдим ителмәй. ([https://secure.php.net/manual/en/pgsql.installation.php  PostgreSQL рөхсәт ителгән РНР йыйыу инструкцияһы]).",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] — яҡшы һәм еңел мәғлүмәт базаһы системаһы. ([http://www.php.net/manual/ru/pdo.installation.php  собрать PHP  SQLite]  PDO менән эшләй торған инструкция)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] — предприятие масштабындаға коммерция базыһы. ([http://www.php.net/manual/ru/oci8.installation.php OCI8 ярҙамындағы РНР нисек йыйырға])",
-       "config-dbsupport-mssql": "* [{{int:version-db-oracle-url}} Oracle] — предприятие масштабындаға Windows өсөн коммерция базыһы. ([http://www.php.net/manual/ru/oci8.installation.php OCI8 ярҙамындағы РНР нисек йыйырға])",
+       "config-dbsupport-mssql": "* [{{int:version-db-oracle-url}} Oracle] — предприятие масштабындаға Windows өсөн коммерция базыһы. ([https://secure.php.net/manual/en/sqlsrv.installation.php OCI8 ярҙамындағы РНР нисек йыйырға])",
        "config-header-mysql": "MySQL көйләү",
        "config-header-postgres": "PostgreSQL көйләү",
        "config-header-sqlite": "SQLite көйләү",
        "config-license-help": "Күпселек дөйөм ҡулланыуҙағы викиҙар үҙ материалдарын [https://freedomdefined.org/Definition/Ru ирекле лицензия] шарттарында файҙаланыуға рөхсәт бирә.\nБыл берҙәмлек тойғоһон булдыррыға ярҙам итә, ҡатнашыу ваҡытын оҙайтыуға дәртләндерә. Әммә шәхси йәки корпоратив викиҙар өсөн бындай ихтыяж юҡ. \n\nӘгәр һеҙ Википедия текстарын файҙаланырға йәки Википедияға үҙ викиғыҙҙан текстар күсереү мөмкинлеге булыуын теләһәгеҙ, \n<strong>{{int:config-license-cc-by-sa}}</strong> һайлағыҙ.\nВикипедия элек  GNU Free Documentation License лицензияһын файҙалана ине.\nGFDL файҙаланыла ала, әммә ул аңлау өсөн ҡатмарлы һәм материалдарҙы ҡабатлап ҡулланыуҙы ауырлаштыра.",
        "config-email-settings": "Электрон почта көйләүҙәре",
        "config-enable-email": "e-mail сығыусы почтаны рәхсәт итергә",
-       "config-enable-email-help": "Электрон почта эшләһен өсөн, [http://www.php.net/manual/ru/mail.configuration.php PHP көйләүҙәрен] башҡарырға кәрәк.\nӘгәр электрон почта мөмкинлектәре кәрәкмәһә, һүндерергә була.",
+       "config-enable-email-help": "Электрон почта эшләһен өсөн, [Config-dbsupport-oracle/manual/ru/mail.configuration.php PHP көйләүҙәрен] башҡарырға кәрәк.\nӘгәр электрон почта мөмкинлектәре кәрәкмәһә, һүндерергә була.",
        "config-email-user": "Ҡатнашыусынан ҡатнашыусыға почтаны рөхсәт итергә",
        "config-email-user-help": "Әгәр профилдә тейешле көйләү булһа, бөтә ҡатнашыусыларға электрон хат ебәрергә рөхсәт итергә.",
        "config-email-usertalk": "Ҡулланыусыларҙы уларҙың фекерләшеү битендәге хәбәрҙәр хаҡында белдереүҙәрҙе файҙаланыу",
index 19e1ea0..ce9aabb 100644 (file)
        "config-pcre-no-utf8": "'''Фатальная памылка''': модуль PCRE для PHP скампіляваны без падтрымкі PCRE_UTF8.\nMediaWiki патрабуе падтрымкі UTF-8 для слушнай працы.",
        "config-memory-raised": "Абмежаваньне на даступную для PHP памяць <code>memory_limit</code> было падвышанае з $1 да $2.",
        "config-memory-bad": "'''Папярэджаньне:''' памер PHP <code>memory_limit</code> складае $1.\nВерагодна, гэта вельмі мала.\nУсталяваньне можа быць няўдалым!",
-       "config-apc": "[http://www.php.net/apc APC] усталяваны",
-       "config-apcu": "[http://www.php.net/apcu APCu] ўсталяваны",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] усталяваны",
-       "config-no-cache-apcu": "<strong>Папярэджаньне:</strong> ня знойдзеныя [http://www.php.net/apcu APCu] ці [http://www.iis.net/download/WinCacheForPhp WinCache]. Кэшаваньне аб’ектаў адключанае.",
+       "config-apc": "[https://secure.php.net/apc APC] усталяваны",
+       "config-apcu": "[https://secure.php.net/apcu APCu] ўсталяваны",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] усталяваны",
+       "config-no-cache-apcu": "<strong>Папярэджаньне:</strong> ня знойдзеныя [https://secure.php.net/apcu APCu] ці [https://www.iis.net/downloads/microsoft/wincache-extension WinCache]. Кэшаваньне аб’ектаў адключанае.",
        "config-mod-security": "'''Папярэджаньне''': на Вашым ўэб-сэрверы ўключаны [https://modsecurity.org/ mod_security]. У выпадку няслушнай наладцы, ён можа стаць прычынай праблемаў для MediaWiki ці іншага праграмнага забесьпячэньня, якое дазваляе ўдзельнікам дасылаць на сэрвэр любы зьмест.\nГлядзіце [https://modsecurity.org/documentation/ дакумэнтацыю mod_security] ці зьвярніцеся ў падтрымку Вашага хосту, калі ў Вас узьнікаюць выпадковыя праблемы.",
        "config-diff3-bad": "GNU diff3 ня знойдзены.",
        "config-git": "Знойдзеная сыстэма канстролю вэрсіяў Git: <code>$1</code>",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki падтрымлівае наступныя сыстэмы базаў зьвестак:\n\n$1\n\nКалі Вы ня бачыце сыстэму базаў зьвестак, якую Вы спрабуеце выкарыстоўваць ў сьпісе ніжэй, перайдзіце па спасылцы інструкцыі, якая знаходзіцца ніжэй, каб уключыць падтрымку.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] зьяўляецца галоўнай мэтай MediaWiki і падтрымліваецца лепей за ўсё. MediaWiki таксама працуе з [{{int:version-db-mariadb-url}} MariaDB] і [{{int:version-db-percona-url}} Percona Server], якія сумяшчальныя з MySQL. ([http://www.php.net/manual/en/mysqli.installation.php Як скампіляваць PHP з падтрымкай MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] — папулярная сыстэма базы зьвестак з адкрытым кодам, якая зьяўляецца альтэрнатывай MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Як кампіляваць PHP з падтрымкай PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] — невялікая сыстэма базы зьвестак, якая мае вельмі добрую падтрымку. ([http://www.php.net/manual/en/pdo.installation.php Як кампіляваць PHP з падтрымкай SQLite], выкарыстоўвае PDO)",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] зьяўляецца галоўнай мэтай MediaWiki і падтрымліваецца лепей за ўсё. MediaWiki таксама працуе з [{{int:version-db-mariadb-url}} MariaDB] і [{{int:version-db-percona-url}} Percona Server], якія сумяшчальныя з MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Як скампіляваць PHP з падтрымкай MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] — папулярная сыстэма базы зьвестак з адкрытым кодам, якая зьяўляецца альтэрнатывай MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Як кампіляваць PHP з падтрымкай PostgreSQL])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] — невялікая сыстэма базы зьвестак, якая мае вельмі добрую падтрымку. ([https://secure.php.net/manual/en/pdo.installation.php Як кампіляваць PHP з падтрымкай SQLite], выкарыстоўвае PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] зьяўляецца камэрцыйнай прафэсійнай базай зьвестак. ([http://www.php.net/manual/en/oci8.installation.php Як скампіляваць PHP з падтрымкай OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] — камэрцыйная база зьвестак для Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Як скампіляваць PHP з падтрымкай SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] — камэрцыйная база зьвестак для Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Як скампіляваць PHP з падтрымкай SQLSRV])",
        "config-header-mysql": "Налады MySQL",
        "config-header-postgres": "Налады PostgreSQL",
        "config-header-sqlite": "Налады SQLite",
        "config-license-help": "Шматлікія адкрытыя вікі публікуюць увесь унёсак у праект на ўмовах [https://freedomdefined.org/Definition вольнай ліцэнзіі].\nГэта дазваляе ствараць эфэкт супольнай уласнасьці і садзейнічае доўгатэрміноваму ўнёску.\nДля прыватных і карпаратыўных вікі гэта не зьяўляецца неабходнасьцю.\n\nКалі Вы жадаеце выкарыстоўваць тэкст зь Вікіпэдыі, і жадаеце, каб Вікіпэдыя магла прымаць тэксты, скапіяваныя з Вашай вікі, Вам неабходна выбраць ліцэнзію <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nРаней Вікіпэдыя выкарыстоўвала ліцэнзію GNU Free Documentation.\nЯна ўсё яшчэ дзейнічае, але яна ўтрымлівае некаторыя моманты, якія ўскладняюць паўторнае выкарыстаньне і інтэрпрэтацыю матэрыялаў.",
        "config-email-settings": "Налады электроннай пошты",
        "config-enable-email": "Дазволіць выходзячыя электронныя лісты",
-       "config-enable-email-help": "Калі Вы жадаеце, каб працавала электронная пошта, неабходна сканфігураваць PHP [http://www.php.net/manual/en/mail.configuration.php адпаведным чынам].\nКалі Вы не жадаеце выкарыстоўваць магчымасьці электроннай пошты, Вы можаце яе адключыць.",
+       "config-enable-email-help": "Калі Вы жадаеце, каб працавала электронная пошта, неабходна сканфігураваць PHP [Config-dbsupport-oracle/manual/en/mail.configuration.php адпаведным чынам].\nКалі Вы не жадаеце выкарыстоўваць магчымасьці электроннай пошты, Вы можаце яе адключыць.",
        "config-email-user": "Дазволіць электронную пошту для сувязі паміж удзельнікамі",
        "config-email-user-help": "Дазволіць усім удзельнікам дасылаць адзін аднаму электронныя лісты, калі ўключаная адпаведная магчымасьць ў іх наладах.",
        "config-email-usertalk": "Уключыць абвяшчэньні пра паведамленьні на старонцы абмеркаваньня",
index 44c673b..4848bfb 100644 (file)
        "config-pcre-no-utf8": "'''Фатално''': Модулът PCRE на PHP изглежда е компилиран без поддръжка на PCRE_UTF8.\nЗа да функционира правилно, МедияУики изисква поддръжка на UTF-8.",
        "config-memory-raised": "<code>memory_limit</code> на PHP е $1, увеличаване до $2.",
        "config-memory-bad": "<strong>Внимание:</strong> <code>memory_limit</code> на PHP е $1.\nСтойността вероятно е твърде ниска.\nВъзможно е инсталацията да се провали!",
-       "config-apc": "[http://www.php.net/apc APC] е инсталиран",
-       "config-apcu": "[http://www.php.net/apc APC] е инсталиран",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] е инсталиран",
-       "config-no-cache-apcu": "<strong>Внимание:</strong> [http://www.php.net/apcu APCu] и [http://www.iis.net/download/WinCacheForPhp WinCache] не могат да бъдат открити.\nКеширането на обекти не е активирано.",
+       "config-apc": "[https://secure.php.net/apc APC] е инсталиран",
+       "config-apcu": "[https://secure.php.net/apc APC] е инсталиран",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] е инсталиран",
+       "config-no-cache-apcu": "<strong>Внимание:</strong> [https://secure.php.net/apcu APCu] и [https://www.iis.net/downloads/microsoft/wincache-extension WinCache] не могат да бъдат открити.\nКеширането на обекти не е активирано.",
        "config-mod-security": "<strong>Предупреждение:</strong> [https://modsecurity.org/ mod_security]/mod_security2 е включено на вашия уеб сървър. Много от обичайните му конфигурации пораждат проблеми с МедияУики и друг софтуер, който позволява публикуване на произволно съдържание.\nАко е възможно, моля изключете го. В противен случай се обърнете към [https://modsecurity.org/documentation/ документацията на mod_security] или се свържете с поддръжката на хостинга си, ако се сблъскате със случайни грешки.",
        "config-diff3-bad": "GNU diff3 не беше намерен.",
        "config-git": "Налична е системата за контрол на версиите Git: <code>$1</code>.",
        "config-type-mysql": "MySQL (или съвместима)",
        "config-type-mssql": "Microsoft SQL сървър",
        "config-support-info": "МедияУики поддържа следните системи за бази от данни:\n\n$1\n\nАко не виждате желаната за използване система в списъка по-долу, следвайте инструкциите за активиране на поддръжка по-горе.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] е най-важна за МедияУики и се поддържа най-добре. МедияУики работи също така с [{{int:version-db-mariadb-url}} MariaDB] и [{{int:version-db-percona-url}} Percona Server], които са съвместими с MySQL.\n([http://www.php.net/manual/bg/mysqli.installation.php Как се компилира PHP с поддръжка на MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] е популярна система за управление на бази от данни, алтернатива на MySQL. ([http://www.php.net/manual/bg/pgsql.installation.php Как се компилира PHP с поддръжка на PostgreSQL])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] е най-важна за МедияУики и се поддържа най-добре. МедияУики работи също така с [{{int:version-db-mariadb-url}} MariaDB] и [{{int:version-db-percona-url}} Percona Server], които са съвместими с MySQL.\n([https://secure.php.net/manual/bg/mysqli.installation.php Как се компилира PHP с поддръжка на MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] е популярна система за управление на бази от данни, алтернатива на MySQL. ([https://secure.php.net/manual/bg/pgsql.installation.php Как се компилира PHP с поддръжка на PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] е олекотена система за бази от данни, която е много добре поддържана. ([http://www.php.net/manual/bg/pdo.installation.php Как се компилира PHP с поддръжка на SQLite], използва PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] е комерсиална корпоративна база от данни. ([http://www.php.net/manual/en/oci8.installation.php Как се компилира PHP с поддръжка на OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] е комерсиална корпоративна база от данни за Windows. ([http://www.php.net/manual/bg/sqlsrv.installation.php Как да се компилира PHP с поддръжка на SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] е комерсиална корпоративна база от данни за Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Как да се компилира PHP с поддръжка на SQLSRV])",
        "config-header-mysql": "Настройки за MySQL",
        "config-header-postgres": "Настройки за PostgreSQL",
        "config-header-sqlite": "Настройки за SQLite",
        "config-license-help": "Много публични уикита поставят всички приноси под [https://freedomdefined.org/Definition/Bg свободен лиценз].\nТова помага за създаването на усещане за общност и насърчава дългосрочните приноси. \nТова не е необходимо като цяло за частно или корпоративно уики.\n\nАко искате да използвате текстове от Уикипедия, и искате Уикипедия да може да приема текстове, копирани от вашето уики, трябва да изберете лиценз <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nЛицензът за свободна документация на GNU е старият лиценз на съдържанието на Уикипедия.\nТой все още е валиден лиценз, но някои негови условия са трудни за разбиране и правят по-сложни повторното използване и интерпретацията.",
        "config-email-settings": "Настройки за е-поща",
        "config-enable-email": "Разрешаване на изходящи е-писма",
-       "config-enable-email-help": "За да работят възможностите за използване на е-поща, необходимо е [http://www.php.net/manual/en/mail.configuration.php настройките за поща на PHP] да бъдат конфигурирани правилно.\nАко няма да се използват услугите за е-поща в уикито, те могат да бъдат изключени тук.",
+       "config-enable-email-help": "За да работят възможностите за използване на е-поща, необходимо е [Config-dbsupport-oracle/manual/en/mail.configuration.php настройките за поща на PHP] да бъдат конфигурирани правилно.\nАко няма да се използват услугите за е-поща в уикито, те могат да бъдат изключени тук.",
        "config-email-user": "Позволяване на потребителите да си изпращат е-писма през уикито",
        "config-email-user-help": "Позволяване на потребителите да си изпращат е-писма ако са разрешили това в настройките си.",
        "config-email-usertalk": "Оповестяване при промяна на потребителската беседа",
index 132a06d..76399c4 100644 (file)
@@ -44,8 +44,8 @@
        "config-env-php": "পিএইচপি $1 ইন্সটল করা হয়েছে।",
        "config-env-hhvm": "HHVM $1 ইনস্টল করা হয়েছে।",
        "config-memory-raised": "পিএইচপির <code>memory_limit</code> হচ্ছে $1, বৃদ্ধি পেয়ে $2 হয়েছে।",
-       "config-apc": "[http://www.php.net/apc এপিসি] ইনস্টল হয়েছে",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] ইনস্টল করা হয়েছে",
+       "config-apc": "[https://secure.php.net/apc এপিসি] ইনস্টল হয়েছে",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] ইনস্টল করা হয়েছে",
        "config-diff3-bad": "GNU diff3 পাওয়া যায়নি।",
        "config-git": "Git সংস্করণের নিয়ন্ত্রণ সফটওয়্যার পাওয়া গেছে: <code>$1</code>।",
        "config-git-bad": "Git সংস্করণের নিয়ন্ত্রণ সফটওয়্যার পাওয়া যায়নি।",
@@ -65,7 +65,7 @@
        "config-oracle-def-ts": "পূর্বনির্ধারিত টেবিলস্পেস",
        "config-oracle-temp-ts": "সাময়কি টেবিলস্পেস:",
        "config-type-mssql": "মাইক্রোসফট এসকিউএল সার্ভার",
-       "config-dbsupport-postgres": "* MySQL-এর বিকল্প হিসেবে [{{int:version-db-postgres-url}} PostgreSQL] হচ্ছে একটি জনপ্রিয় ওপেন সোর্স ডাটাবেস ব্যবস্থা। ([http://www.php.net/manual/en/pgsql.installation.php PostgreSQL সমর্থনসহ কিভাবে PHP সঙ্কলন করবেন])",
+       "config-dbsupport-postgres": "* MySQL-এর বিকল্প হিসেবে [{{int:version-db-postgres-url}} PostgreSQL] হচ্ছে একটি জনপ্রিয় ওপেন সোর্স ডাটাবেস ব্যবস্থা। ([https://secure.php.net/manual/en/pgsql.installation.php PostgreSQL সমর্থনসহ কিভাবে PHP সঙ্কলন করবেন])",
        "config-header-mysql": "মাইএসকিউএল সেটিংস",
        "config-header-postgres": "পোস্টগ্রেএসকিউএল সেটিংস",
        "config-header-sqlite": "এসকিউলাইট সেটিংস",
index f41ef23..96b3dae 100644 (file)
        "config-pcre-no-utf8": "'''Fazi groñs ''': evit doare eo bet kempunet modulenn PCRE PHP hep ar skor PCRE_UTF8.\nEzhomm en deus MediaWiki eus UTF-8 evit mont plaen en-dro.",
        "config-memory-raised": "<code>memory_limit</code> ar PHP zo $1, kemmet e $2.",
        "config-memory-bad": "'''Diwallit :''' Da $1 emañ arventenn <code>memory_limit</code> PHP.\nRe izel eo moarvat.\nMarteze e c'hwito ar staliadenn !",
-       "config-apc": "Staliet eo [http://www.php.net/apc APC]",
-       "config-apcu": "Staliet eo [http://www.php.net/apcu APCu]",
-       "config-wincache": "Staliet eo [https://www.iis.net/download/WinCacheForPhp WinCache]",
-       "config-no-cache-apcu": "<strong>Taolit pled :</strong> N'eus ket bet gallet kavout [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] pe [http://www.iis.net/download/WinCacheForPhp WinCache].\nN'eo ket gweredekaet ar c'hrubuilhañ traezoù.",
+       "config-apc": "Staliet eo [https://secure.php.net/apc APC]",
+       "config-apcu": "Staliet eo [https://secure.php.net/apcu APCu]",
+       "config-wincache": "Staliet eo [https://www.iis.net/downloads/microsoft/wincache-extension WinCache]",
+       "config-no-cache-apcu": "<strong>Taolit pled :</strong> N'eus ket bet gallet kavout [https://secure.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] pe [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nN'eo ket gweredekaet ar c'hrubuilhañ traezoù.",
        "config-mod-security": "<strong>Taolit pled :</strong> Gweredekaet eo [https://modsecurity.org/ mod_security]/mod_security2 gant ho servijer web. Ma n'eo ket kfluniet mat e c'hall tegas trubuilhoù da MediaWiki ha meziantoù all a aotre implijerien da ouzhpennañ danvez evel ma karont.\nE kement ha m'eo posupl e tlefe bezañ diweredekaet. A-hend-all, sellit ouzh [https://modsecurity.org/documentation/ mod_security an teuliadur] pe kit e darempred gant skoazell ho herberc'hier m'en em gavit gant fazioù dargouezhek.",
        "config-diff3-bad": "N'eo ket bet kavet GNU diff3.",
        "config-git": "Kavet eo bet ar meziant kontrolliñ adstummoù Git : <code>$1</code>.",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "Skoret eo ar reizhiadoù diaz titouroù da-heul gant MediaWiki :\n\n$1\n\nMa ne welit ket amañ dindan ar reizhiad diaz titouroù a fell deoc'h ober ganti, heuilhit an titouroù a-us (s.o. al liammoù) evit gweredekaat ar skorañ.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] eo an dibab kentañ evit MediaWiki hag an hini skoret ar gwellañ. Mont a ra MediaWiki en-dro gant [{{int:version-db-mariadb-url}} MariaDB] ha [{{int:version-db-percona-url}} Percona Server] ivez, kenglotus o-daou gant MySQL. ([http://www.php.net/manual/en/mysqli.installation.php Penaos kempunañ PHP gant skor MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] zo anezhi ur reizhiad diaz roadennoù frank a wirioù brudet-mat a c'haller ober gantañ e plas MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Penaos kempunañ PHP gant skor PostgreSQL])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] eo an dibab kentañ evit MediaWiki hag an hini skoret ar gwellañ. Mont a ra MediaWiki en-dro gant [{{int:version-db-mariadb-url}} MariaDB] ha [{{int:version-db-percona-url}} Percona Server] ivez, kenglotus o-daou gant MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Penaos kempunañ PHP gant skor MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] zo anezhi ur reizhiad diaz roadennoù frank a wirioù brudet-mat a c'haller ober gantañ e plas MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Penaos kempunañ PHP gant skor PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] zo anezhi ur reizhiad diaz roadennoù 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-dbsupport-oracle": "* Un embregerezh kenwerzhel diaz roadennoù eo [{{int:version-db-oracle-url}} Oracle]. ([http://www.php.net/manual/en/oci8.installation.php Penaos kempunañ PHP gant skor OCI8])",
-       "config-dbsupport-mssql": "* Un embregerezh kenwerzhel diaz roadennoù evit Windows eo [{{int:version-db-mssql-url}} Microsoft SQL Server]. ([http://www.php.net/manual/en/sqlsrv.installation.php Penaos kempunañ PHP gant skor SQLSRV])",
+       "config-dbsupport-mssql": "* Un embregerezh kenwerzhel diaz roadennoù evit Windows eo [{{int:version-db-mssql-url}} Microsoft SQL Server]. ([https://secure.php.net/manual/en/sqlsrv.installation.php Penaos kempunañ PHP gant skor SQLSRV])",
        "config-header-mysql": "Arventennoù MySQL",
        "config-header-postgres": "Arventennoù PostgreSQL",
        "config-header-sqlite": "Arventennoù SQLite",
        "config-license-cc-choose": "Dibabit un aotre-implijout Creative Commons personelaet",
        "config-email-settings": "Arventennoù ar postel",
        "config-enable-email": "Gweredekaat ar posteloù a ya kuit",
-       "config-enable-email-help": "Mar fell deoc'h ober gant ar posteler eo ret deoc'h [http://www.php.net/manual/en/mail.configuration.php kefluniañ arventennoù postel PHP] ervat.\nMar ne fell ket deoc'h ober gant ar servij posteloù e c'hall bezañ diweredekaet amañ.",
+       "config-enable-email-help": "Mar fell deoc'h ober gant ar posteler eo ret deoc'h [Config-dbsupport-oracle/manual/en/mail.configuration.php kefluniañ arventennoù postel PHP] ervat.\nMar ne fell ket deoc'h ober gant ar servij posteloù e c'hall bezañ diweredekaet amañ.",
        "config-email-user": "Gweredekaat ar posteloù a implijer da implijer",
        "config-email-user-help": "Aotren a ra an holl implijerien da gas posteloù an eil d'egile mard eo bet gweredekaet an arc'hwel ganto en ho penndibaboù.",
        "config-email-usertalk": "Gweredekaat kemennadur pajennoù kaozeal an implijerien",
index 07a0e2e..a70c981 100644 (file)
@@ -50,9 +50,9 @@
        "config-no-db": "Ne mogu pronaći pogodan upravljački program za bazu podataka! Morate ga instalirati za PHP-bazu.\n{{PLURAL:$2|Podržana je sljedeća vrsta|Podržane su sljedeće vrste}} baze podataka: $1.\n\nAko se sami kompajlirali PHP, omogućite klijent baze podataka u postavkama koristeći, naprimjer, <code>./configure --with-mysqli</code>.\nAko ste instalirali PHP iz paketa za Debian ili Ubuntu, onda također morate instalirati, naprimjer, paket <code>php5-mysql</code>.",
        "config-memory-raised": "<code>memory_limit</code> za PHP iznosi $1, povišen na $2.",
        "config-memory-bad": "<strong>Upozorenje:</strong> <code>memory_limit</code> za PHP iznosi $1.\nOvo je vjerovatno premalo.\nInstalacija možda neće uspjeti!",
-       "config-apc": "[http://www.php.net/apc APC] je instaliran",
-       "config-apcu": "[http://www.php.net/apcu APCu] je instaliran",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] je instaliran",
+       "config-apc": "[https://secure.php.net/apc APC] je instaliran",
+       "config-apcu": "[https://secure.php.net/apcu APCu] je instaliran",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] je instaliran",
        "config-diff3-bad": "GNU diff3 nije pronađen.",
        "config-git": "Pronađen je Git program za kontrolu verzija: <code>$1</code>.",
        "config-git-bad": "Nije pronađen Git program za kontrolu verzija.",
index 983c5c2..e03a737 100644 (file)
@@ -60,9 +60,9 @@
        "config-unicode-using-intl": "S'utilitza l'[https://pecl.php.net/intl extensió intl PECL] per a la normalització de l'Unicode.",
        "config-memory-raised": "El <code>memory_limit</code> del PHP és $1 i s'ha aixecat a $2.",
        "config-memory-bad": "<strong>Avís:</strong> El <code>memory_limit</code> del PHP és $1.\nAixò és probablement massa baix.\nLa instal·lació pot fallar!",
-       "config-apc": "L’[http://www.php.net/apc APC] està instal·lat",
-       "config-apcu": "[http://www.php.net/apcu APCu] està instal·lat",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] està instal·lat",
+       "config-apc": "L’[https://secure.php.net/apc APC] està instal·lat",
+       "config-apcu": "[https://secure.php.net/apcu APCu] està instal·lat",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] està instal·lat",
        "config-diff3-bad": "No s'ha trobat el GNU diff3.",
        "config-git": "S'ha trobat el programari de control de versions Git: <code>$1</code>.",
        "config-git-bad": "No s'ha trobat el programari de control de versions Git.",
index a53e470..33bce2f 100644 (file)
@@ -31,8 +31,8 @@
        "config-page-existingwiki": "ویکی پێشوو",
        "config-restart": "بەڵێ، دەستی پێ بکەرەوە",
        "config-env-php": "PHP $1 دامەزراوە.",
-       "config-apc": "[http://www.php.net/apc APC] دامەزراوە",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] دامەزراوە",
+       "config-apc": "[https://secure.php.net/apc APC] دامەزراوە",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] دامەزراوە",
        "config-db-type": "جۆری داتابەیس:",
        "config-db-host": "خانەخوێی داتابەیس:",
        "config-db-name": "ناوی بنکەدراوە:",
index 8ab7abe..c2ec005 100644 (file)
@@ -10,7 +10,8 @@
                        "Matěj Suchánek",
                        "LordMsz",
                        "Seb35",
-                       "Ilimanaq29"
+                       "Ilimanaq29",
+                       "Dvorapa"
                ]
        },
        "config-desc": "Instalační program pro MediaWiki",
        "config-pcre-no-utf8": "<strong>Kritická chyba:</strong> PHP modul PCRE byl zřejmě přeložen bez podpory PCRE_UTF8.\nMediaWiki vyžaduje ke správné funkci podporu UTF-8.",
        "config-memory-raised": "<code>memory_limit</code> v PHP byl nastaven na $1, zvýšen na $2.",
        "config-memory-bad": "<strong>Upozornění:</strong> <code>memory_limit</code> je v PHP nastaven na $1.\nTo je pravděpodobně příliš málo.\nInstalace může selhat!",
-       "config-apc": "Je nainstalováno [http://www.php.net/apc APC]",
-       "config-apcu": "Je nainstalováno [http://www.php.net/apcu APCu]",
-       "config-wincache": "Je nainstalováno [https://www.iis.net/download/WinCacheForPhp WinCache]",
-       "config-no-cache-apcu": "<strong>Upozornění:</strong> Nebylo nalezeno [http://www.php.net/apcu APCu], \nani [http://www.iis.net/download/WinCacheForPhp WinCache].\nCachování objektů není povoleno.",
+       "config-apc": "Je nainstalováno [https://secure.php.net/apc APC]",
+       "config-apcu": "Je nainstalováno [https://secure.php.net/apcu APCu]",
+       "config-wincache": "Je nainstalováno [https://www.iis.net/downloads/microsoft/wincache-extension WinCache]",
+       "config-no-cache-apcu": "<strong>Upozornění:</strong> Nebylo nalezeno [https://secure.php.net/apcu APCu], \nani [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nCachování objektů není povoleno.",
        "config-mod-security": "<strong>Upozornění:</strong> váš webový server má zapnuto [https://modsecurity.org/ mod_security]/mod_security2. Mnoho běžných konfigurací bude způsobovat potíže MediaWiki a dalším programům, které umožňují ukládat libovolný obsah.\nPokud je to možné, mělo by se to vypnout. Jinak se v případě, že narazíte na náhodné chyby, podívejte do [https://modsecurity.org/documentation/ dokumentace mod_security] nebo kontaktujte technickou podporu vašeho poskytovatele.",
        "config-diff3-bad": "Nebyl nalezen GNU diff3.",
        "config-git": "Nalezen software pro správu verzí Git: <code>$1</code>.",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki podporuje následující databázové systémy:\n\n$1\n\nPokud v nabídce níže nevidíte databázový systém, který chcete použít, musíte pro zapnutí podpory následovat instrukce odkázané výše.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] je pro MediaWiki hlavní platformou a je podporováno nejlépe. MediaWiki pracuje také s [{{int:version-db-mariadb-url}} MariaDB] a [{{int:version-db-percona-url}} Percona Server], které jsou s MySQL kompatibilní. ([http://www.php.net/manual/en/mysql.installation.php Jak zkompilovat PHP s podporou MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] je populární otevřený databázový systém používaný jako alternativa k MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Jak přeložit PHP s podporou PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] je velmi dobře podporovaný odlehčený databázový systém. ([http://www.php.net/manual/en/pdo.installation.php Jak přeložit PHP s podporou SQLite], používá PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] je komerční podniková databáze. ([http://www.php.net/manual/en/oci8.installation.php Jak přeložit PHP s podporou OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] je komerční podniková databáze pro Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Jak přeložit PHP s podporou SQLSRV])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] je pro MediaWiki hlavní platformou a je podporováno nejlépe. MediaWiki pracuje také s [{{int:version-db-mariadb-url}} MariaDB] a [{{int:version-db-percona-url}} Percona Server], které jsou s MySQL kompatibilní. ([https://secure.php.net/manual/en/mysql.installation.php Jak zkompilovat PHP s podporou MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] je populární otevřený databázový systém používaný jako alternativa k MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Jak přeložit PHP s podporou PostgreSQL])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] je velmi dobře podporovaný odlehčený databázový systém. ([https://secure.php.net/manual/en/pdo.installation.php Jak přeložit PHP s podporou SQLite], používá PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] je komerční podniková databáze. ([https://secure.php.net/manual/en/oci8.installation.php Jak přeložit PHP s podporou OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] je komerční podniková databáze pro Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Jak přeložit PHP s podporou SQLSRV])",
        "config-header-mysql": "Nastavení MySQL",
        "config-header-postgres": "Nastavení PostgreSQL",
        "config-header-sqlite": "Nastavení SQLite",
        "config-license-help": "Mnoho veřejných wiki všechny příspěvky zveřejňuje pod některou [https://freedomdefined.org/Definition/Cs svobodnou licencí].\nTo pomáhá vytvořit duch komunitního vlastnictví a povzbuzuje dlouhodobé přispívání.\nTo obecně není potřeba u soukromé nebo firemní wiki.\n\nPokud chcete být schopni používat text z Wikipedie a chcete, aby Wikipedie byla schopna přijímat text okopírovaný z vaší wiki, měli byste zvolit <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nDříve Wikipedie používala GNU Free Documentation License.\nGFDL je platná licence, ale složité jí porozumět.\nTaké je komplikované používat obsah licencovaný pod GFDL.",
        "config-email-settings": "Nastavení e-mailu",
        "config-enable-email": "Zapnout odchozí e-mail",
-       "config-enable-email-help": "Pokud chcete, aby e-mail fungoval, je potřeba správně nakonfigurovat [http://www.php.net/manual/en/mail.configuration.php e-mailová nastavení PHP].\nPokud nechcete žádné e-mailové funkce, můžete je zde vypnout.",
+       "config-enable-email-help": "Pokud chcete, aby e-mail fungoval, je potřeba správně nakonfigurovat [https://secure.php.net/manual/en/mail.configuration.php e-mailová nastavení PHP].\nPokud nechcete žádné e-mailové funkce, můžete je zde vypnout.",
        "config-email-user": "Umožnit vzájemné e-maily mezi uživateli",
        "config-email-user-help": "Umožní všem uživatelům posílat si navzájem e-maily, pokud si to zapnout v uživatelském nastavení.",
        "config-email-usertalk": "Umožnit notifikace k uživatelským diskusím",
index 34cf29f..ff52ec6 100644 (file)
@@ -35,8 +35,8 @@
        "config-env-hhvm": "HHVM $1 je wjinastalowóné",
        "config-memory-raised": "Paraméter PHP <code>memory_limit</code> $1 òstôł zwikszony do $2.",
        "config-apc": "[Http://www.php.net/apc APC] je wjinstalowóny",
-       "config-apcu": "[http://www.php.net/apcu APCu] je wjinstalowóny",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] je wjinstalowóny",
+       "config-apcu": "[https://secure.php.net/apcu APCu] je wjinstalowóny",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] je wjinstalowóny",
        "config-diff3-bad": "Felënk GNU diff3.",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
index b20e1ed..add4c27 100644 (file)
        "config-pcre-no-utf8": "'''Fataler Fehler:''' Das PHP-Modul PCRE scheint ohne PCRE_UTF8-Unterstützung kompiliert worden zu sein.\nMediaWiki benötigt die UTF-8-Unterstützung, um fehlerfrei lauffähig zu sein.",
        "config-memory-raised": "Der PHP-Parameter <code>memory_limit</code> betrug $1 und wurde auf $2 erhöht.",
        "config-memory-bad": "'''Warnung:''' Der PHP-Parameter <code>memory_limit</code> beträgt $1.\nDieser Wert ist wahrscheinlich zu niedrig.\nDer Installationsvorgang könnte eventuell scheitern!",
-       "config-apc": "[http://www.php.net/apc APC] ist installiert",
-       "config-apcu": "[http://www.php.net/apcu APCu] ist installiert",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] ist installiert",
-       "config-no-cache-apcu": "<strong>Warnung:</strong> [http://www.php.net/apcu APCu] oder [http://www.iis.net/download/WinCacheForPhp WinCache] konnten nicht gefunden werden.\nDer Objektcache ist nicht aktiviert.",
+       "config-apc": "[https://secure.php.net/apc APC] ist installiert",
+       "config-apcu": "[https://secure.php.net/apcu APCu] ist installiert",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] ist installiert",
+       "config-no-cache-apcu": "<strong>Warnung:</strong> [https://secure.php.net/apcu APCu] oder [https://www.iis.net/downloads/microsoft/wincache-extension WinCache] konnten nicht gefunden werden.\nDer Objektcache ist nicht aktiviert.",
        "config-mod-security": "'''Warnung:''' Auf dem Webserver wurde [https://modsecurity.org/ ModSecurity] aktiviert. Sofern falsch konfiguriert, kann dies zu Problemen mit MediaWiki sowie anderer Software auf dem Server führen und es Benutzern ermöglichen, beliebige Inhalte im Wiki einzustellen.\nFür weitere Informationen empfehlen wir die [https://modsecurity.org/documentation/ Dokumentation zu ModSecurity] oder den Kontakt zum Hoster, sofern Fehler auftreten.",
        "config-diff3-bad": "GNU diff3 wurde nicht gefunden.",
        "config-git": "Die Versionsverwaltungssoftware „Git“ wurde gefunden: <code>$1</code>.",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki unterstützt die folgenden Datenbanksysteme:\n\n$1\n\nSofern unterhalb nicht das Datenbanksystem angezeigt wird, das verwendet werden soll, muss dieses noch verfügbar gemacht werden. Oben ist zu jedem unterstützten Datenbanksystem ein Link zur entsprechenden Anleitung vorhanden.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] ist das von MediaWiki primär unterstützte Datenbanksystem. MediaWiki funktioniert auch mit [{{int:version-db-mariadb-url}} MariaDB] und [{{int:version-db-percona-url}} Percona Server], die MySQL-kompatibel sind. ([https://www.php.net/manual/en/mysqli.installation.php Anleitung zur Kompilierung von PHP mit MySQL-Unterstützung])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] ist ein beliebtes Open-Source-Datenbanksystem und eine Alternative zu MySQL. ([https://www.php.net/manual/de/pgsql.installation.php Anleitung zur Kompilierung von PHP mit PostgreSQL-Unterstützung])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] ist das von MediaWiki primär unterstützte Datenbanksystem. MediaWiki funktioniert auch mit [{{int:version-db-mariadb-url}} MariaDB] und [{{int:version-db-percona-url}} Percona Server], die MySQL-kompatibel sind. ([https://secure.php.net/manual/en/mysqli.installation.php Anleitung zur Kompilierung von PHP mit MySQL-Unterstützung])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] ist ein beliebtes Open-Source-Datenbanksystem und eine Alternative zu MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Anleitung zur Kompilierung von PHP mit PostgreSQL-Unterstützung])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] ist ein verschlanktes Datenbanksystem, das auch gut unterstützt wird ([https://www.php.net/manual/de/pdo.installation.php Anleitung zur Kompilierung von PHP mit SQLite-Unterstützung], verwendet PHP Data Objects (PDO))",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] ist eine kommerzielle Unternehmensdatenbank ([https://www.php.net/manual/en/oci8.installation.php Anleitung zur Kompilierung von PHP mit OCI8-Unterstützung])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ist eine gewerbliche Unternehmensdatenbank für Windows. ([https://www.php.net/manual/de/sqlsrv.installation.php Anleitung zur Kompilierung von PHP mit SQLSRV-Unterstützung])",
        "config-license-help": "Viele öffentliche Wikis publizieren alle Beiträge unter einer [https://freedomdefined.org/Definition/De freien Lizenz.]\nDies trägt dazu bei, ein Gefühl von Gemeinschaft zu schaffen, und ermutigt zu längerfristiger Mitarbeit.\nHingegen ist im Allgemeinen eine freie Lizenz auf geschlossenen Wikis nicht notwendig.\n\nSofern man Texte aus der Wikipedia verwenden möchte und umgekehrt, sollte die Lizenz {{int:config-license-cc-by-sa}} gewählt werden.\n\nDie Wikipedia nutzte vormals die GNU-Lizenz für freie Dokumentation (GFDL).\nDie GFDL ist eine gültige Lizenz, die allerdings schwer zu verstehen ist.\nEs ist zudem schwierig, gemäß dieser Lizenz lizenzierte Inhalte wiederzuverwenden.",
        "config-email-settings": "E-Mail-Einstellungen",
        "config-enable-email": "Ausgehende E-Mails ermöglichen",
-       "config-enable-email-help": "Sofern die E-Mail-Funktionen genutzt werden sollen, müssen die entsprechenden [http://www.php.net/manual/en/mail.configuration.php PHP-E-Mail-Einstellungen] richtig konfiguriert werden.\nFür den Fall, dass die E-Mail-Funktionen nicht benötigt werden, können sie hier deaktiviert werden.",
+       "config-enable-email-help": "Sofern die E-Mail-Funktionen genutzt werden sollen, müssen die entsprechenden [https://secure.php.net/manual/en/mail.configuration.php PHP-E-Mail-Einstellungen] richtig konfiguriert werden.\nFür den Fall, dass die E-Mail-Funktionen nicht benötigt werden, können sie hier deaktiviert werden.",
        "config-email-user": "E-Mail-Versand von Benutzer zu Benutzer aktivieren",
        "config-email-user-help": "Allen Benutzern ermöglichen, sich gegenseitig E-Mails zu schicken, sofern sie es in ihren Einstellungen aktiviert haben.",
        "config-email-usertalk": "Benachrichtigungen zu Änderungen an Benutzerdiskussionsseiten ermöglichen",
        "config-nofile": "Die Datei „$1“ konnte nicht gefunden werden. Wurde sie gelöscht?",
        "config-extension-link": "Wusstest du, dass dein Wiki die Nutzung von [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions Erweiterungen] unterstützt?\n\nDu kannst die [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category Erweiterungen nach Kategorie] anzeigen oder die [https://www.mediawiki.org/wiki/Extension_Matrix Erweiterungs-Matrix] aufrufen, um eine vollständige Liste der Erweiterungen zu sehen.",
        "config-skins-screenshots": "$1 (Bildschirmfotos: $2)",
+       "config-skins-screenshot": "$1 ($2)",
        "config-extensions-requires": "$1 (erfordert $2)",
        "config-screenshot": "Bildschirmfoto",
        "mainpagetext": "<strong>MediaWiki wurde installiert.</strong>",
index 2350970..f8ce568 100644 (file)
        "config-pcre-no-utf8": "<strong>Κρίσιμο:</strong> Το PCRE module της PHP  φαίνεται να έχει μεταγλωττιστεί χωρίς υποστήριξη  PCRE_UTF8.\nΓια τη σωστή λειτουργία του MediaWiki απαιτείται υποστήριξη UTF-8.",
        "config-memory-raised": "Το  <code>memory_limit</code> της PHP είναι  $1 και αυξήθηκε σε  $2.",
        "config-memory-bad": "<strong>Προειδοποίηση:</strong> το <code>memory_limit</code> της PHP είναι $1.\nΑυτή η τιμή είναι πιθανώς πολύ χαμηλή.\n\nΗ εγκατάσταση ενδέχεται να αποτύχει!",
-       "config-apc": "Το [http://www.php.net/apc APC] είναι εγκατεστημένο",
-       "config-apcu": "Το [http://www.php.net/apcu APCu] είναι εγκατεστημένο",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp Το WinCache] είναι εγκατεστημένο",
-       "config-no-cache-apcu": "<strong>Προειδοποίηση:</strong> Αποτυχία εύρεσης του [http://www.php.net/apcu APCu] ή του [http://www.iis.net/download/WinCacheForPhp WinCache].\nΗ αρχειοθέτηση αντικειμένων δεν έχει ενεργοποιηθεί.",
+       "config-apc": "Το [https://secure.php.net/apc APC] είναι εγκατεστημένο",
+       "config-apcu": "Το [https://secure.php.net/apcu APCu] είναι εγκατεστημένο",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension Το WinCache] είναι εγκατεστημένο",
+       "config-no-cache-apcu": "<strong>Προειδοποίηση:</strong> Αποτυχία εύρεσης του [https://secure.php.net/apcu APCu] ή του [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nΗ αρχειοθέτηση αντικειμένων δεν έχει ενεργοποιηθεί.",
        "config-diff3-bad": "Το GNU diff3 δεν βρέθηκε.",
        "config-git": "Βρέθηκε το λογισμικό ελέγχου εκδόσεων Git: <code>$1</code>.",
        "config-git-bad": "Το λογισμικό ελέγχου εκδόσεων Git δεν βρέθηκε.",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "To MediaWiki υποστηρίζει τα ακόλουθα συστήματα βάσεων δεδομένων:\n\n$1\n\nΑν δεν εμφανίζεται παρακάτω το σύστημα βάσης δεδομένων που θέλετε να χρησιμοποιήσετε, τότε ακολουθήστε τις οδηγίες στον παραπάνω σύνδεσμο για να ενεργοποιήσετε την υποστήριξη.",
-       "config-dbsupport-mysql": "* Η [{{int:version-db-mysql-url}} MySQL] είναι ο πρωταρχικός στόχος για το MediaWiki και υποστηρίζεται καλύτερα. Το MediaWiki συνεργάζεται επίσης με τη [{{int:version-db-mariadb-url}} MariaDB] και το [{{int:version-db-percona-url}} διακομιστή Percona], που είναι όλα συμβατά με MySQL. ([http://www.php.net/manual/en/mysqli.installation.php Πώς να μεταγλωττίσετε την PHP με υποστήριξη MySQL])",
-       "config-dbsupport-postgres": "* Η [{{int:version-db-postgres-url}} PostgreSQL] είναι δημοφιλές σύστημα βάσης δεδομένων ανοικτού κώδικα ως εναλλακτική της MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Πώς να μεταγλωττίσετε την PHP με υποστήριξη PostgreSQL])",
+       "config-dbsupport-mysql": "* Η [{{int:version-db-mysql-url}} MySQL] είναι ο πρωταρχικός στόχος για το MediaWiki και υποστηρίζεται καλύτερα. Το MediaWiki συνεργάζεται επίσης με τη [{{int:version-db-mariadb-url}} MariaDB] και το [{{int:version-db-percona-url}} διακομιστή Percona], που είναι όλα συμβατά με MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Πώς να μεταγλωττίσετε την PHP με υποστήριξη MySQL])",
+       "config-dbsupport-postgres": "* Η [{{int:version-db-postgres-url}} PostgreSQL] είναι δημοφιλές σύστημα βάσης δεδομένων ανοικτού κώδικα ως εναλλακτική της MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Πώς να μεταγλωττίσετε την PHP με υποστήριξη PostgreSQL])",
        "config-dbsupport-sqlite": "* Η [{{int:version-db-sqlite-url}} SQLite] είναι ένα ελαφρύ σύστημα βάσης δεδομένων που υποστηρίζεται πολύ καλά. ([http://www.php.net/manual/en/pdo.installation.php Πώς να μεταγλωττίσετε την PHP με υποστήριξη SQLite], χρησιμοποιεί PDO)",
        "config-dbsupport-oracle": "* Η [{{int:version-db-oracle-url}} Oracle] είναι εμπορική βάση δεδομένων για επιχειρήσεις. ([http://www.php.net/manual/en/oci8.installation.php Πώς να μεταγλωττίσετε την PHP με υποστήριξη OCI8])",
-       "config-dbsupport-mssql": "* Ο [{{int:version-db-mssql-url}} Microsoft SQL Server] είναι εμπορική βάση δεδομένων για επιχειρήσεις που λειτουργεί σε Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Πώς να μεταγλωττίσετε την PHP με υποστήριξη SQLSRV])",
+       "config-dbsupport-mssql": "* Ο [{{int:version-db-mssql-url}} Microsoft SQL Server] είναι εμπορική βάση δεδομένων για επιχειρήσεις που λειτουργεί σε Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Πώς να μεταγλωττίσετε την PHP με υποστήριξη SQLSRV])",
        "config-header-mysql": "Ρυθμίσεις MySQL",
        "config-header-postgres": "Ρυθμίσεις PostgreSQL",
        "config-header-sqlite": "Ρυθμίσεις SQLite",
        "config-license-help": "Πολλά δημόσια wiki βάζουν όλες τις συνεισφορές υπό [https://freedomdefined.org/Definition ελεύθερη άδεια].\nΑυτό βοηθά να δημιουργηθεί μια αίσθηση κοινοτικής ιδιοκτησίας και ενθαρρύνει τη μακροχρόνια συνεισφορά.\nΔεν είναι γενικά απαραίτητο για ένα ιδιωτικό ή εταιρικό wiki.\n\nΑν θέλετε να μπορείτε να χρησιμοποιείτε κείμενο από τη Βικιπαίδεια και αν θέλετε να μπορεί η Βικιπαίδεια να δεχτεί κείμενο που αντιγράφεται από το wiki σας, θα πρέπει να επιλέξετε <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nΗ Βικιπαίδεια χρησιμοποιούσε παλιά την Άδεια Ελεύθερης Τεκμηρίωσης GNU (GFDL).\nΗ GFDL είναι μια έγκυρη άδεια, αλλά είναι δύσκολο να κατανοηθεί.\nΕίναι επίσης δύσκολο να επαναχρησιμοποιηθεί το περιεχόμενο που έχει χορηγηθεί βάσει της GFDL.",
        "config-email-settings": "Ρυθμίσεις ηλεκτρονικού ταχυδρομείου",
        "config-enable-email": "Ενεργοποίηση εξερχόμενου ηλεκτρονικού ταχυδρομείου",
-       "config-enable-email-help": "Αν θέλετε να λειτουργήσει το ηλεκτρονικό ταχυδρομείο, οι [http://www.php.net/manual/en/mail.configuration.php ρυθμίσεις αλληλογραφίας της PHP] πρέπει να ρυθμιστούν σωστά.\nΑν δεν θέλετε καθόλου λειτουργίες ηλεκτρονικού ταχυδρομείου, μπορείτε να τις απενεργοποιήσετε εδώ.",
+       "config-enable-email-help": "Αν θέλετε να λειτουργήσει το ηλεκτρονικό ταχυδρομείο, οι [Config-dbsupport-oracle/manual/en/mail.configuration.php ρυθμίσεις αλληλογραφίας της PHP] πρέπει να ρυθμιστούν σωστά.\nΑν δεν θέλετε καθόλου λειτουργίες ηλεκτρονικού ταχυδρομείου, μπορείτε να τις απενεργοποιήσετε εδώ.",
        "config-email-user": "Ενεργοποίηση ηλεκτρονικού ταχυδρομείου από χρήστη σε χρήστη",
        "config-email-user-help": "Να επιτρέπεται σε όλους τους χρήστες να στέλνουν ο ένας στον άλλον μηνύματα ηλεκτρονικού ταχυδρομείου εάν το έχουν ενεργοποιήσει στις προτιμήσεις τους.",
        "config-email-usertalk": "Ενεργοποίηση ειδοποίησης σελίδας συζήτησης χρήστη",
index d1a3b83..412b405 100644 (file)
        "config-pcre-no-utf8": "<strong>Fatal:</strong> PHP's PCRE module seems to be compiled without PCRE_UTF8 support.\nMediaWiki requires UTF-8 support to function correctly.",
        "config-memory-raised": "PHP's <code>memory_limit</code> is $1, raised to $2.",
        "config-memory-bad": "<strong>Warning:</strong> PHP's <code>memory_limit</code> is $1.\nThis is probably too low.\nThe installation may fail!",
-       "config-apc": "[http://www.php.net/apc APC] is installed",
-       "config-apcu": "[http://www.php.net/apcu APCu] is installed",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] is installed",
-       "config-no-cache-apcu": "<strong>Warning:</strong> Could not find [http://www.php.net/apcu APCu] or [http://www.iis.net/download/WinCacheForPhp WinCache].\nObject caching is not enabled.",
+       "config-apc": "[https://secure.php.net/apc APC] is installed",
+       "config-apcu": "[https://secure.php.net/apcu APCu] is installed",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] is installed",
+       "config-no-cache-apcu": "<strong>Warning:</strong> Could not find [https://secure.php.net/apcu APCu] or [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nObject caching is not enabled.",
        "config-mod-security": "<strong>Warning:</strong> Your web server has [https://modsecurity.org/ mod_security]/mod_security2 enabled. Many common configurations of this will cause problems for MediaWiki and other software that allows users to post arbitrary content.\nIf possible, this should be disabled. Otherwise, refer to [https://modsecurity.org/documentation/ mod_security documentation] or contact your host's support if you encounter random errors.",
+
        "config-diff3-bad": "GNU diff3 not found.",
        "config-git": "Found the Git version control software: <code>$1</code>.",
        "config-git-bad": "Git version control software not found.",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki supports the following database systems:\n\n$1\n\nIf you do not see the database system you are trying to use listed below, then follow the instructions linked above to enable support.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] is the primary target for MediaWiki and is best supported. MediaWiki also works with [{{int:version-db-mariadb-url}} MariaDB] and [{{int:version-db-percona-url}} Percona Server], which are MySQL compatible. ([http://www.php.net/manual/en/mysqli.installation.php How to compile PHP with MySQL support])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] is a popular open source database system as an alternative to MySQL. ([http://www.php.net/manual/en/pgsql.installation.php How to compile PHP with PostgreSQL support])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] is a lightweight database system that is very well supported. ([http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], uses PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] is a commercial enterprise database. ([http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] is a commercial enterprise database for Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] is the primary target for MediaWiki and is best supported. MediaWiki also works with [{{int:version-db-mariadb-url}} MariaDB] and [{{int:version-db-percona-url}} Percona Server], which are MySQL compatible. ([https://secure.php.net/manual/en/mysqli.installation.php How to compile PHP with MySQL support])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] is a popular open source database system as an alternative to MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php How to compile PHP with PostgreSQL support])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] is a lightweight database system that is very well supported. ([https://secure.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], uses PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] is a commercial enterprise database. ([https://secure.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] is a commercial enterprise database for Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
        "config-header-mysql": "MySQL settings",
        "config-header-postgres": "PostgreSQL settings",
        "config-header-sqlite": "SQLite settings",
        "config-license-help": "Many public wikis put all contributions under a [https://freedomdefined.org/Definition free license].\nThis helps to create a sense of community ownership and encourages long-term contribution.\nIt is not generally necessary for a private or corporate wiki.\n\nIf you want to be able to use text from Wikipedia, and you want Wikipedia to be able to accept text copied from your wiki, you should choose <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipedia previously used the GNU Free Documentation License.\nThe GFDL is a valid license, but it is difficult to understand.\nIt is also difficult to reuse content licensed under the GFDL.",
        "config-email-settings": "Email settings",
        "config-enable-email": "Enable outbound email",
-       "config-enable-email-help": "If you want email to work, [http://www.php.net/manual/en/mail.configuration.php PHP's mail settings] need to be configured correctly.\nIf you do not want any email features, you can disable them here.",
+       "config-enable-email-help": "If you want email to work, [https://secure.php.net/manual/en/mail.configuration.php PHP's mail settings] need to be configured correctly.\nIf you do not want any email features, you can disable them here.",
        "config-email-user": "Enable user-to-user email",
        "config-email-user-help": "Allow all users to send each other email if they have enabled it in their preferences.",
        "config-email-usertalk": "Enable user talk page notification",
index c1c5edf..bf791f3 100644 (file)
@@ -37,8 +37,8 @@
        "config-env-bad": "La medio estis kontrolita.\nNe eblas instali MediaWiki.",
        "config-env-php": "PHP $1 estas instalita.",
        "config-env-hhvm": "HHVM $1 instalatas.",
-       "config-apc": "[http://www.php.net/apc APC] estas instalita",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] estas instalita",
+       "config-apc": "[https://secure.php.net/apc APC] estas instalita",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] estas instalita",
        "config-diff3-bad": "GNU diff3 ne estis trovita.",
        "config-db-type": "Tipo de datumbazo:",
        "config-db-wiki-settings": "Identigu ĉi tiun vikion",
index 8f9e592..99be820 100644 (file)
@@ -34,7 +34,9 @@
                        "Dgstranz",
                        "Irus",
                        "Tinss",
-                       "KATRINE1992"
+                       "KATRINE1992",
+                       "MarcoAurelio",
+                       "Adjen"
                ]
        },
        "config-desc": "El instalador de MediaWiki",
        "config-pcre-no-utf8": "'''Error fatal ''': Parece que el módulo PCRE de PHP fue compilado sin el soporte PCRE_UTF8.\nMediaWiki requiere compatibilidad con UTF-8 para funcionar correctamente.",
        "config-memory-raised": "El parámetro <code>memory_limit</code> de PHP es $1. Se aumenta a $2.",
        "config-memory-bad": "<strong>Advertencia:</strong> el parámetro <code>memory_limit</code> de PHP es $1.\nProbablemente sea demasiado bajo.\n¡La instalación puede fallar!",
-       "config-apc": "[http://www.php.net/apc APC] está instalado",
-       "config-apcu": "[http://www.php.net/apcu APCu] está instalado",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] está instalado",
-       "config-no-cache-apcu": "<strong>Advertencia:</strong> No se pudo encontrar [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] o [http://www.iis.net/download/WinCacheForPhp WinCache].\nEl caché de objetos no está activado.",
+       "config-apc": "[https://secure.php.net/apc APC] está instalado",
+       "config-apcu": "[https://secure.php.net/apcu APCu] está instalado",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] está instalado",
+       "config-no-cache-apcu": "<strong>Atención:</strong> no se pudo encontrar [https://secure.php.net/apcu APCu] o [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nEl almacenamiento en antememoria de objetos no está activado.",
        "config-mod-security": "<strong>Advertencia:</strong> tu servidor web tiene activado [https://modsecurity.org/ mod_security]/mod_security2. Muchas de sus configuraciones comunes pueden causar problemas a MediaWiki u otro software que permita a los usuarios publicar contenido arbitrario. De ser posible, deberías desactivarlo. Si no, consulta la [https://modsecurity.org/documentation/ documentación de mod_security] o contacta con el administrador de tu servidor si encuentras errores aleatorios.",
        "config-diff3-bad": "GNU diff3 no se encuentra.",
        "config-git": "Se encontró el software de control de versiones Git: <code>$1</code>.",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki es compatible con los siguientes sistemas de bases de datos:\n\n$1\n\nSi no encuentras en el listado el sistema de base de datos que estás intentando utilizar, sigue las instrucciones enlazadas arriba para activar la compatibilidad.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] es la base de datos mayoritaria para MediaWiki y la que goza de mayor compatibilidad. MediaWiki también funciona con [{{int:version-db-mariadb-url}} MariaDB] y [{{int:version-db-percona-url}} Percona Server], que son compatibles con MySQL. ([http://www.php.net/manual/es/mysql.installation.php Cómo compilar PHP con compatibilidad MySQL])",
-       "config-dbsupport-postgres": "[{{int:version-db-postgres-url}} PostgreSQL] es un sistema de base de datos popular de código abierto, alternativa a MySQL. ([http://www.php.net/manual/es/pgsql.installation.php Cómo compilar PHP con compatibilidad PostgreSQL]).",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] es un sistema de base de datos ligero con gran compatibilidad con MediaWiki. ([http://www.php.net/manual/es/pdo.installation.php Cómo compilar PHP con compatibilidad SQLite], usando PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] 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-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] es un sistema comercial de base de datos empresariales para Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Cómo compilar PHP con compatibilidad con SQLSRV])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] es la base de datos mayoritaria para MediaWiki y la que goza de mayor compatibilidad. MediaWiki también funciona con [{{int:version-db-mariadb-url}} MariaDB] y [{{int:version-db-percona-url}} Percona Server], que son compatibles con MySQL. ([https://secure.php.net/manual/es/mysql.installation.php Cómo compilar PHP con compatibilidad MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] es un sistema de base de datos popular de código abierto, alternativa a MySQL. ([https://secure.php.net/manual/es/pgsql.installation.php Cómo compilar PHP con compatibilidad PostgreSQL]).",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] es un sistema de base de datos ligero con gran compatibilidad con MediaWiki. ([https://secure.php.net/manual/en/pdo.installation.php Cómo compilar PHP con compatibilidad SQLite], usando PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] es una base de datos comercial a nivel empresarial. ([https://secure.php.net/manual/en/oci8.installation.php Cómo compilar PHP con compatibilidad con OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] es un sistema comercial de base de datos empresariales para Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Cómo compilar PHP con compatibilidad con SQLSRV])",
        "config-header-mysql": "Configuración de MySQL",
        "config-header-postgres": "Configuración de PostgreSQL",
        "config-header-sqlite": "Configuración de SQLite",
        "config-license-help": "Muchos wikis públicos ponen todas las contribuciones bajo una [https://freedomdefined.org/Definition licencia libre].\nEsto ayuda a crear un sentido de propiedad comunitaria y alienta la contribución a largo plazo.\nEsto no es generalmente necesario para un wiki privado o corporativo.\n\nSi deseas poder utilizar texto de Wikipedia, y deseas que Wikipedia pueda aceptar el texto copiado de tu wiki, debes elegir <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipedia utilizaba anteriormente la licencia de documentación libre de GNU (GFDL).\nLa GFDL es una licencia válida, pero es difícil de entender.\nTambién es difícil reutilizar el contenido licenciado bajo la GFDL.",
        "config-email-settings": "Configuración de correo electrónico",
        "config-enable-email": "Activar el envío de correos electrónicos",
-       "config-enable-email-help": "Si quieres que el correo electrónico funcione, la [http://www.php.net/manual/en/mail.configuration.php configuración PHP de correo electrónico] debe ser la correcta.\nSi no quieres la funcionalidad de correo electrónico, puedes desactivarla aquí.",
+       "config-enable-email-help": "Si quieres que el correo electrónico funcione, la [https://secure.php.net/manual/en/mail.configuration.php configuración PHP de correo electrónico] debe ser configurada correctamente.\nSi no quieres ninguna funcionalidad del correo electrónico, puedes desactivarla aquí.",
        "config-email-user": "Activar correo electrónico entre usuarios",
        "config-email-user-help": "Permitir que todos los usuarios intercambien correos electrónicos si lo han activado en sus preferencias.",
        "config-email-usertalk": "Activar notificaciones de páginas de discusión de usuarios",
        "config-cache-options": "Configuración de la antememoria de objetos:",
        "config-cache-help": "El almacenamiento en caché de objetos se utiliza para mejorar la velocidad de MediaWiki mediante el almacenamiento en caché los datos usados más frecuentemente.\nA los sitios medianos y grandes se les recomienda que permitirlo. También es beneficioso para los sitios pequeños.",
        "config-cache-none": "Sin almacenamiento en caché (no se pierde ninguna funcionalidad, pero la velocidad puede resentirse en sitios grandes)",
-       "config-cache-accel": "Almacenamiento en caché de objetos PHP (APC, APCu, XCache o WinCache)",
+       "config-cache-accel": "Almacenamiento en antememoria de objetos PHP (APC, APCu o WinCache)",
        "config-cache-memcached": "Utilizar Memcached (necesita ser instalado y configurado aparte)",
        "config-memcached-servers": "Servidores Memcached:",
        "config-memcached-help": "Lista de direcciones IP que serán usadas por Memcached.\nDeben especificarse una por cada línea y especificar el puerto a utilizar. Por ejemplo:\n127.0.0.1:11211\n192.168.1.25:1234",
        "config-extension-link": "¿Sabías que tu wiki admite [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions extensiones]?\n\nPuedes navegar por las [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category categorías] o visitar el [https://www.mediawiki.org/wiki/Extension_Matrix centro de extensiones] para ver una lista completa.",
        "config-skins-screenshots": "$1 (capturas de pantalla: $2)",
        "config-skins-screenshot": "$1 ($2)",
+       "config-extensions-requires": "$1 (requiere $2)",
        "config-screenshot": "captura de pantalla",
        "mainpagetext": "<strong>MediaWiki se ha instalado.</strong>",
        "mainpagedocfooter": "Consulta la [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents guía] para obtener información sobre el uso del software wiki.\n\n== Primeros pasos ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista de ajustes de configuración]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Preguntas frecuentes sobre MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista de correo de anuncios de publicación de MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Traducir MediaWiki a tu idioma]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Aprende a combatir el spam en tu wiki]"
index 18c917e..07198f7 100644 (file)
        "config-pcre-no-utf8": "<strong>Fatal:</strong> PHREko PCRE modulua PCRE_UTF8 ko laguntza gabe bildu da.\nMediaWiki-k UTF-8 euskarria behar du behar bezala funtziona dezan.",
        "config-memory-raised": "PHP-ko <code>memory_limit</code> $1 da, $2-ra igota.",
        "config-memory-bad": "<strong>Warning:</strong> PHPko <code>memory_limit</code> $1 da.\nZiurrenik hau oso baxua da.\nInstalazioa huts egin dezake!",
-       "config-apc": "[http://www.php.net/apc APC] instalatuta dago",
-       "config-apcu": "[http://www.php.net/apcu APCu] instalatuta dago",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] instalatuta dago",
-       "config-no-cache-apcu": "<strong>Warning:</strong> Ezin izan da [http://www.php.net/apcu APCu] edo [http://www.iis.net/download/WinCacheForPhp WinCache] aurkitu.\nObjektu katxea ez dago aktibatuta.",
+       "config-apc": "[https://secure.php.net/apc APC] instalatuta dago",
+       "config-apcu": "[https://secure.php.net/apcu APCu] instalatuta dago",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] instalatuta dago",
+       "config-no-cache-apcu": "<strong>Warning:</strong> Ezin izan da [https://secure.php.net/apcu APCu] edo [https://www.iis.net/downloads/microsoft/wincache-extension WinCache] aurkitu.\nObjektu katxea ez dago aktibatuta.",
        "config-mod-security": "<strong>Warning:</strong> Zure web zerbitzariak [https://modsecurity.org/mod_security] / mod_security2 aktibatu du. Honen konfigurazio komun asko sortu ahal dituzte arazoak MediaWikin  eta beste software batzuetan, hautazko edukia argitaratzeko aukera ematen dutenei erabiltzaileei.\nAhal izanez gero, desgaitu egin beharko litzateke. Bestela, kontsultatu [https://modsecurity.org/documentation/ mod_security documentation] edo jarri harremanetan zure ostalariarekin ausazko akatsak aurkitzen badituzu.",
        "config-diff3-bad": "GNU diff3 ez da aurkitu.",
        "config-git": "Git bertsio-kontrol software aurkitu da: <code>$1</code>",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki-k onartzen du hurrengo datu-base sistemak:\n\n$1\n\nListan ez baduzu ikusten erabili nahi duzun sistema, jarraitu goiko argibideak aktibatzeko.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] MediaWikiren lehenengoko helburua da eta primeran babesturik dago. MediaWikik ere [{{int:version-db-mariadb-url}} MariaDB]-rekin egiten du lan baita [{{int:version-db-percona-url}} Percona Server]-kin, MySQL-rekin balio dutenak. ([http://www.php.net/manual/en/mysqli.installation.php How to compile PHP with MySQL support])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] iturburu irekiko datu basea sistema famatua da MySQL-rako alternatiba bezala. ([http://www.php.net/manual/en/pgsql.installation.php How to compile PHP with PostgreSQL support])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] MediaWikiren lehenengoko helburua da eta primeran babesturik dago. MediaWikik ere [{{int:version-db-mariadb-url}} MariaDB]-rekin egiten du lan baita [{{int:version-db-percona-url}} Percona Server]-kin, MySQL-rekin balio dutenak. ([https://secure.php.net/manual/en/mysqli.installation.php How to compile PHP with MySQL support])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] iturburu irekiko datu basea sistema famatua da MySQL-rako alternatiba bezala. ([https://secure.php.net/manual/en/pgsql.installation.php How to compile PHP with PostgreSQL support])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] oso ondo onartzen duen datu-basearen sistema arina da.\n ([http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], uses PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] enpresa komertzial baten datu-basea da. ([http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] Windows-entzako enpresa komertzial baten datu-basea da.  ([http://www.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] Windows-entzako enpresa komertzial baten datu-basea da.  ([https://secure.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
        "config-header-mysql": "MySQL hobespenak",
        "config-header-postgres": "PostgreSQL hobespenak",
        "config-header-sqlite": "SQLite hobespenak",
        "config-license-help": "Wikilari publiko askok ekarpen guztiak jartzen dituzte [https://freedomdefined.org/Definition lizentzia aske] azpian.\nHonek komunitatearen jabetza zentzuaren kontzeptua sortzen laguntzen du eta epe luzerako ekarpena bultzatzen du.\nEz da, oro har, wiki pribatu edo korporatiborik behar.\n\nWikipediatik testua erabiltzeko aukera izan nahi baduzu eta Wikipediak zure wikietatik kopiatutako testua onartzeko gai izatea nahi baduzu,  <strong>{{int:config-license-cc-by-sa}}</strong> aukeratu beharko zenuke.\n\nWikipedia lehenago erabili izan du GNU Dokumentazio Librearen Lizentzia.\nGFDL baliozko lizentzia da, baina ulertzeko zaila da.\nGFDLren baimenarekin lotutako edukiak berrerabiltzea ere zaila da.",
        "config-email-settings": "E-posta hobespenak",
        "config-enable-email": "Aktibatu irteerako emaila.",
-       "config-enable-email-help": "Lan egiteko email-a nahi baduzu, [http://www.php.net/manual/en/mail.configuration.php PHP's mail settings] ondo konfiguratu egin behar da. Email ezaugarririk ez baduzu nahi, hemen kendu ditzakezu.",
+       "config-enable-email-help": "Lan egiteko email-a nahi baduzu, [Config-dbsupport-oracle/manual/en/mail.configuration.php PHP's mail settings] ondo konfiguratu egin behar da. Email ezaugarririk ez baduzu nahi, hemen kendu ditzakezu.",
        "config-email-user": "Aktibatu erabiltzaileen arteko emaila.",
        "config-email-user-help": "Baimena eman erabiltzaileei beraien artean emailak bidaltzeko, lehentasunetan aukera aktibatuta badaukate.",
        "config-email-usertalk": "Aktibatu erabiltzaileen eztabaida orrien jakinarazpena",
index d75b063..a94cae8 100644 (file)
        "config-pcre-no-utf8": "<strong>مخرب:</strong> به‌ نظر می‌رسد پودمان پی‌سی‌آراییِ پی‌اچ‌پی بدون پشتیبانی پی‌سی‌آرایی_یو‌تی‌اف۸ تهیه شده‌است.\nمدیاویکی برای درست عمل کردن نیازمند پشتیبانی یوتی‌اف-۸ است.",
        "config-memory-raised": "PHP's <code>memory_limit</code>, نسخهٔ $1 است، به نسخهٔ $2 ارتقاء داده شده‌است.",
        "config-memory-bad": "'''هشدار:''' PHP's <code>memory_limit</code> نسخهٔ $1 است.\nاین ممکن است خیلی پایین باشد.\nممکن است نصب با مشکل رو‌به‌رو شود.",
-       "config-apc": "[http://www.php.net/apc APC] نصب شده‌است.",
-       "config-apcu": "[http://www.php.net/apcu APCu] نصب شده‌است",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] نصب شده‌است.",
-       "config-no-cache-apcu": "<strong>هشدار:</strong> پیوند [http://www.php.net/apcu APCu] یا [http://www.iis.net/download/WinCacheForPhp WinCache] یافت نشد. ذخیره شی فعال نیست.",
+       "config-apc": "[https://secure.php.net/apc APC] نصب شده‌است.",
+       "config-apcu": "[https://secure.php.net/apcu APCu] نصب شده‌است",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] نصب شده‌است.",
+       "config-no-cache-apcu": "<strong>هشدار:</strong> پیوند [https://secure.php.net/apcu APCu] یا [https://www.iis.net/downloads/microsoft/wincache-extension WinCache] یافت نشد. ذخیره شی فعال نیست.",
        "config-mod-security": "'''هشدار:''' وب سرور شما [https://modsecurity.org/ mod_security] فعال است.اگر اشتباه پیکربندی شده‌‌ باشد،می تواند باعث ایجاد مشکلاتی برای مدیاویکی یا دیگر نرم‌افزاری شود که به کاربران اجازه می‌دهد پیام دلخواه ارسال کنند.\nبه [https://modsecurity.org/documentation/ mod_security documentation] مراجعه کنید یا اگر با خطاهای اتفاقی مواجه شدید با پشتیبانی میزبان خود در تماس باشید.",
        "config-diff3-bad": "جی‌ان‌یو دیف۳ پیدا نشد.",
        "config-git": "کنترل نسخهٔ نرم‌افزار گیت پیدا شد: <code>$1</code>.",
        "config-type-mysql": "مای‌اس‌کیو‌ال (یا سازگار)",
        "config-type-mssql": "سرور مایکروسافت اس‌کیو‌ال",
        "config-support-info": "مدیاویکی سامانه‌های پایگاه اطلاعاتی زیر را حمایت می‌کند:\n$1\nاگر متوجه سامانه پایگاه اطلاعاتی که سعی دارید از فهرست زیر استفاده کنید، نمی‌شوید، بنابراین دستورالعمل‌های مرتبط در بالا را برای فعال کردن پشتیبانی دنبال کنید.",
-       "config-dbsupport-mysql": "*[{{int:version-db-mysql-url}} MySQL] مهم‌ترین هدف برای مدیاویکی است و بهترین پشتیبانی. مدیاویکی همچنین کار می‌کند با [{{int:version-db-mariadb-url}} MariaDB] و [{{int:version-db-percona-url}} Percona Server] که با MySQL سازگار هستند.([http://www.php.net/manual/en/mysqli.installation.php چگونه php را با MySQL کامپایل کنیم])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} پستگرس‌کیوال] یک سامانه پایگاه اطلاعات متن‌باز پر‌طرفدار است که جایگزینی برای مای‌اس‌کیوال است. ([http://www.php.net/manual/en/pgsql.installation.php راهنمای تنظیم کردن پی‌اچ‌پی به همراه پستگرس‌کیوال])",
+       "config-dbsupport-mysql": "*[{{int:version-db-mysql-url}} MySQL] مهم‌ترین هدف برای مدیاویکی است و بهترین پشتیبانی. مدیاویکی همچنین کار می‌کند با [{{int:version-db-mariadb-url}} MariaDB] و [{{int:version-db-percona-url}} Percona Server] که با MySQL سازگار هستند.([https://secure.php.net/manual/en/mysqli.installation.php چگونه php را با MySQL کامپایل کنیم])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} پستگرس‌کیوال] یک سامانه پایگاه اطلاعات متن‌باز پر‌طرفدار است که جایگزینی برای مای‌اس‌کیوال است. ([https://secure.php.net/manual/en/pgsql.installation.php راهنمای تنظیم کردن پی‌اچ‌پی به همراه پستگرس‌کیوال])",
        "config-dbsupport-sqlite": "*[{{int:version-db-sqlite-url}} اس‌کیولایت] یک سامانه پایگاه اطلاعاتی کم حجمی است که بسیار خوب پشتیبانی شده‌است.\n([http://www.php.net/manual/en/pdo.installation.php چگونگی کامپایل پی‌اچ‌پی با اس‌کیولایت]، از PDO استفاده می‌کند)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] یک پایگاه اطلاعاتی کار تبلیغاتی است.\n([http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] یک پایگاه اطلاعاتی موسسهٔ تبلیغاتی برای وینذوز است. ([http://www.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] یک پایگاه اطلاعاتی موسسهٔ تبلیغاتی برای وینذوز است. ([https://secure.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
        "config-header-mysql": "تنظیمات مای‌اس‌کیو‌ال",
        "config-header-postgres": "تنظیمات پست‌گر‌اس‌کیو‌ال",
        "config-header-sqlite": "تنظیمات اس‌کیو‌لایت",
        "config-license-help": "بسیاری از وبگاه‌ها ویرایش‌های ها را با  [https://freedomdefined.org/Definition اجازه‌نامهٔ آزاد] منتشر می‌کنند.\nاین کار به داشتن حس مالکیت جمعی کمک می‌کند و ویرایش‌های طولانی مدت را اشاعه می‌دهد.\nاین برای ویکی‌های خصوصی یا سازمانی الزامی نیست.\n\nاگر شما می‌خواهید از متون ویکی‌پدیا استفاده کنید، یا اینکه به ویکی‌پدیا اجازه دهید از متون شما استفاده کند باید متون خود را با <strong>{{int:config-license-cc-by-sa}}</strong> منتشر کنید.\n\nویکی‌پدیا در گذشته از اجازه‌نامهٔ داده‌های آزاد گنو استفاده می‌کرد.\nاین اجازه‌نامه مورد قبول است، ولی فهم آن آسان نیست.\nهمچنین استفادهٔ دوباره از متون تحت اجازه‌نامهٔ داده‌های آزاد گنو به سختی انجام می‌گیرد.",
        "config-email-settings": "تنظیمات ایمیل",
        "config-enable-email": "فعال‌سازی ایمیل خروجی",
-       "config-enable-email-help": "اگر می‌خواهید ارسال ایمیل کار کند، [http://www.php.net/manual/en/mail.configuration.php PHP's mail settings] نیازمند پیکربندی صحیح است.\nاگر هیچ قابلیت ایمیلی نمی‌خواهید، می‌توانید آنها را اینجا غیر‌فعال کنید.",
+       "config-enable-email-help": "اگر می‌خواهید ارسال ایمیل کار کند، [Config-dbsupport-oracle/manual/en/mail.configuration.php PHP's mail settings] نیازمند پیکربندی صحیح است.\nاگر هیچ قابلیت ایمیلی نمی‌خواهید، می‌توانید آنها را اینجا غیر‌فعال کنید.",
        "config-email-user": "فعال کردن ایمیل کاربر به کاربر",
        "config-email-user-help": "به همهٔ کاربرانی که ارسال ایمیل را در ترجیحات خود فعال کرده‌اند، اجازه داده خواهد شد که به یکدیگر ایمیل ارسال کنند.",
        "config-email-usertalk": "فعال کردن اطلاع‌رسانی صفحهٔ بحث کاربر",
index 9bb5a85..5f47db4 100644 (file)
@@ -74,9 +74,9 @@
        "config-pcre-old": "<strong>Tärkeää:</strong> PCRE $1 tai uudempi versio tarvitaan.\nPHP-binäärisi on linkitetty versiolla PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Lisätietoja].",
        "config-memory-raised": "PHP:n <code>memory_limit</code> on $1, nostetaan arvoon $2.",
        "config-memory-bad": "'''Varoitus:''' PHP:n <code>memory_limit</code> on $1.\nTämä on luultavasti liian alhainen.\nAsennus saattaa epäonnistua!",
-       "config-apc": "[http://www.php.net/apc APC] on asennettu.",
-       "config-apcu": "[http://www.php.net/apcu APCu] on asennettu",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] on asennettu",
+       "config-apc": "[https://secure.php.net/apc APC] on asennettu.",
+       "config-apcu": "[https://secure.php.net/apcu APCu] on asennettu",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] on asennettu",
        "config-diff3-bad": "GNU diff3:a ei löytynyt.",
        "config-git": "Löydetty Git versionhallintaohjelmisto: <code>$1</code>",
        "config-git-bad": "Git versionhallintaohjelmistoa ei löydy.",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki tukee seuraavia tietokantajärjestelmiä:\n\n$1\n\nJos et näe tietokantajärjestelmää, jota yrität käyttää, listattuna alhaalla, seuraa yläpuolella olevia ohjeita tuen aktivoimiseksi.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] on MediaWikin ensisijainen kohde ja se on myös parhaiten tuettu. MediaWiki voi myös käyttää [{{int:version-db-mariadb-url}} MariaDB]- sekä [{{int:version-db-percona-url}} Percona Server]-järjestelmiä, jotka ovat MySQL-yhteensopivia. ([http://www.php.net/manual/en/mysqli.installation.php Miten käännetään PHP MySQL-tuella])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] on suosittu avoimen lähdekoodin tietokantajärjestelmä vaihtoehtona MySQL:lle. ([http://www.php.net/manual/en/pgsql.installation.php Kuinka käännetään PHP PostgreSQL-tuella])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] on MediaWikin ensisijainen kohde ja se on myös parhaiten tuettu. MediaWiki voi myös käyttää [{{int:version-db-mariadb-url}} MariaDB]- sekä [{{int:version-db-percona-url}} Percona Server]-järjestelmiä, jotka ovat MySQL-yhteensopivia. ([https://secure.php.net/manual/en/mysqli.installation.php Miten käännetään PHP MySQL-tuella])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] on suosittu avoimen lähdekoodin tietokantajärjestelmä vaihtoehtona MySQL:lle. ([https://secure.php.net/manual/en/pgsql.installation.php Kuinka käännetään PHP PostgreSQL-tuella])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] on kevyt tietokantajärjestelmä, jota tuetaan hyvin. ([http://www.php.net/manual/en/pdo.installation.php Miten käännetään PHP SQLite-tuella], käyttää PDO:ta)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] on kaupallinen yritystietokanta. ([http://www.php.net/manual/en/oci8.installation.php Kuinka käännetään PHP OCI8-tuella])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] on kaupallinen yritystietokanta Windowsille. ([http://www.php.net/manual/en/sqlsrv.installation.php Miten käännetään PHP SQLSRV-tuella])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] on kaupallinen yritystietokanta Windowsille. ([https://secure.php.net/manual/en/sqlsrv.installation.php Miten käännetään PHP SQLSRV-tuella])",
        "config-header-mysql": "MySQL-asetukset",
        "config-header-postgres": "PostgreSQL-asetukset",
        "config-header-sqlite": "SQLite-asetukset",
        "config-license-help": "Monet julkiset wikit käyttävät muokkauksiin [https://freedomdefined.org/Definition vapaata lisenssiä].\nTämä auttaa luomaan yhteisöllisen omistajuuden tunteen ja kannustaa pitkäkestoiseen muokkaamiseen.\nSe ei ole yleensä tarpeen yksityiselle tai yrityksen wikille.\n\nJos haluat pystyä käyttämään tekstiä Wikipediasta, ja haluat Wikipedian pystyvän hyväksymään wikistäsi kopioitua tekstiä, sinun tulisi valita <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipedia käytti aiemmin GNU Free Documentation Licenseä.\nGFDL on kelvollinen lisenssi, mutta vaikea ymmärtää.\nOn myös vaikeaa käyttää uudelleen GFDL-lisensöityä sisältöä.",
        "config-email-settings": "Sähköpostiasetukset",
        "config-enable-email": "Ota käyttöön sähköpostien lähetys",
-       "config-enable-email-help": "Jotta sähköposti toimii, [http://www.php.net/manual/en/mail.configuration.php PHP:n sähköpostiasetukset] täytyy asettaa oikein.\nJos et halua käyttää sähköpostiominaisuuksia, ne voi kytkeä pois päältä tästä.",
+       "config-enable-email-help": "Jotta sähköposti toimii, [Config-dbsupport-oracle/manual/en/mail.configuration.php PHP:n sähköpostiasetukset] täytyy asettaa oikein.\nJos et halua käyttää sähköpostiominaisuuksia, ne voi kytkeä pois päältä tästä.",
        "config-email-user": "Ota käyttöön käyttäjältä käyttäjälle sähköpostit",
        "config-email-user-help": "Salli käyttäjien lähettää sähköpostia toisilleen jos he ovat ottaneet käyttöön toiminnon asetuksissaan.",
        "config-email-usertalk": "Ota käyttöön käyttäjien keskustelusivusta ilmoittaminen",
index 3d801cc..39a1868 100644 (file)
        "config-pcre-no-utf8": "<strong>Erreur fatale :</strong> le module PCRE de PHP semble être compilé sans la prise en charge de PCRE_UTF8.\nMediaWiki a besoin de la gestion d’UTF-8 pour fonctionner correctement.",
        "config-memory-raised": "Le paramètre <code>memory_limit</code> de PHP était à $1, porté à $2.",
        "config-memory-bad": "<strong>Attention :</strong> Le paramètre <code>memory_limit</code> de PHP est à $1.\nCette valeur est probablement trop faible.\nIl est possible que l’installation échoue !",
-       "config-apc": "[http://www.php.net/apc APC] est installé",
-       "config-apcu": "[http://www.php.net/apcu APCu] est installé",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] est installé",
-       "config-no-cache-apcu": "<strong>Attention :</strong> impossible de trouver [http://www.php.net/apcu APCu] ou [http://www.iis.net/download/WinCacheForPhp WinCache].\nLa mise en cache d’objets n’est pas activée.",
+       "config-apc": "[https://secure.php.net/apc APC] est installé",
+       "config-apcu": "[https://secure.php.net/apcu APCu] est installé",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] est installé",
+       "config-no-cache-apcu": "<strong>Attention :</strong> impossible de trouver [https://secure.php.net/apcu APCu] ou [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nLa mise en cache d’objets n’est pas activée.",
        "config-mod-security": "<strong>Attention :</strong> votre serveur web a [https://modsecurity.org/ mod_security] activé. S’il est mal configuré, cela peut poser des problèmes à MediaWiki ou à d’autres applications qui permettent aux utilisateurs de publier un contenu quelconque. Si possible, ceci devrait être désactivé. Sinon, reportez-vous à [https://modsecurity.org/documentation/ la documentation de mod_security] ou contactez l’assistance de votre hébergeur si vous rencontrez des erreurs aléatoires.",
        "config-diff3-bad": "GNU diff3 introuvable.",
        "config-git": "Logiciel de contrôle de version Git trouvé : <code>$1</code>.",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki prend en charge ces systèmes de bases de données :\n\n$1\n\nSi vous ne voyez pas le système de base de données que vous essayez d’utiliser ci-dessous, alors suivez les instructions ci-dessus (voir liens) pour activer la prise en charge.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] est le premier choix pour MediaWiki et est le mieux pris en charge. MediaWiki fonctionne aussi avec [{{int:version-db-mariadb-url}} MariaDB] et [{{int:version-db-percona-url}} Percona Server], qui sont compatibles avec MySQL. ([http://www.php.net/manual/en/mysqli.installation.php Comment compiler PHP avec la prise en charge de MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] est un système de base de données populaire en ''source ouverte'' qui peut être une alternative à MySQL ([http://www.php.net/manual/en/pgsql.installation.php Comment compiler PHP avec la prise en charge de PostgreSQL]).",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] est un système de base de données léger bien pris en charge ([http://www.php.net/manual/fr/pdo.installation.php Comment compiler PHP avec la prise en charge de SQLite], en utilisant PDO).",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] est un système commercial de gestion de base de données d’entreprise. ([http://www.php.net/manual/en/oci8.installation.php Comment compiler PHP avec la prise en charge d’OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] est une base de données commerciale d’entreprise pour Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Comment compiler PHP avec la prise en charge de SQLSRV])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] est le premier choix pour MediaWiki et est le mieux pris en charge. MediaWiki fonctionne aussi avec [{{int:version-db-mariadb-url}} MariaDB] et [{{int:version-db-percona-url}} Percona Server], qui sont compatibles avec MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Comment compiler PHP avec la prise en charge de MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] est un système de base de données populaire en ''source ouverte'' qui peut être une alternative à MySQL ([https://secure.php.net/manual/en/pgsql.installation.php Comment compiler PHP avec la prise en charge de PostgreSQL]).",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] est un système de base de données léger bien pris en charge ([https://secure.php.net/manual/en/pdo.installation.php Comment compiler PHP avec la prise en charge de SQLite], en utilisant PDO).",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] est un système commercial de gestion de base de données d’entreprise. ([https://secure.php.net/manual/en/oci8.installation.php Comment compiler PHP avec la prise en charge d’OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] est une base de données commerciale d’entreprise pour Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Comment compiler PHP avec la prise en charge de SQLSRV])",
        "config-header-mysql": "Paramètres de MySQL",
        "config-header-postgres": "Paramètres de PostgreSQL",
        "config-header-sqlite": "Paramètres de SQLite",
        "config-license-help": "Beaucoup de wikis publics mettent l’ensemble des contributions sous une [https://freedomdefined.org/Definition/Fr licence libre].\nCela contribue à créer un sentiment d’appartenance à une communauté et encourage les contributions sur le long terme.\nCe n’est généralement pas nécessaire pour un wiki privé ou d’entreprise.\n\nSi vous souhaitez utiliser des textes de Wikipédia, et souhaitez que Wikipédia puisse réutiliser des textes copiés depuis votre wiki, vous devriez choisir <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipédia utilisait auparavant la Licence de Documentation Libre GNU (GFDL).\nC’est une licence valide, mais difficile à comprendre. \nIl est aussi difficile de réutiliser du contenu sous la licence GFDL.",
        "config-email-settings": "Paramètres de courriel",
        "config-enable-email": "Activer les courriels sortants",
-       "config-enable-email-help": "Si vous souhaitez utiliser le courriel, vous devez [http://www.php.net/manual/en/mail.configuration.php configurer des paramètres PHP] (texte en anglais).\nSi vous ne voulez pas du service de courriel, vous pouvez le désactiver ici.",
+       "config-enable-email-help": "Si vous souhaitez utiliser le courriel, vous devez avoir les [https://secure.php.net/manual/en/mail.configuration.php paramètres courriel de PHP] configurés correctement (texte en anglais).\nSi vous ne voulez pas du service de courriel, vous pouvez le désactiver ici.",
        "config-email-user": "Activer les courriers électroniques d'utilisateur à utilisateur",
        "config-email-user-help": "Permet à tous les utilisateurs d'envoyer des courriels à d'autres utilisateurs si cela est activé dans leurs préférences.",
        "config-email-usertalk": "Activer la notification des pages de discussion des utilisateurs",
index 7f943f2..6f6210e 100644 (file)
@@ -30,8 +30,8 @@
        "config-page-existingwiki": "Vouiqui ègzistent",
        "config-env-php": "PHP $1 est enstalâ.",
        "config-memory-raised": "Lo paramètre <code>memory_limit</code> de PHP ére a $1, portâ a $2.",
-       "config-apc": "[http://www.php.net/apc APC] est enstalâ",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] est enstalâ",
+       "config-apc": "[https://secure.php.net/apc APC] est enstalâ",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] est enstalâ",
        "config-diff3-bad": "GNU diff3 entrovâblo.",
        "config-db-type": "Tipo de bâsa de balyês :",
        "config-db-host": "Hôto de la bâsa de balyês :",
index 50b124e..c625b67 100644 (file)
        "config-pcre-no-utf8": "<strong>Erro fatal:</strong> Semella que o módulo PCRE do PHP foi compilado sen o soporte PCRE_UTF8.\nMediaWiki necesita soporte UTF-8 para funcionar correctamente.",
        "config-memory-raised": "O parámetro <code>memory_limit</code> do PHP é $1. Aumentado a $2.",
        "config-memory-bad": "<strong>Atención:<strong> O parámetro <code>memory_limit</code> do PHP é $1.\nProbablemente é un valor baixo de máis.\nA instalación pode fallar!",
-       "config-apc": "[http://www.php.net/apc APC] está instalado",
-       "config-apcu": "[http://www.php.net/apcu APCu] está instalado",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] está instalado",
-       "config-no-cache-apcu": "<strong>Advertencia:</strong> Non se puido atopar [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] ou [http://www.iis.net/download/WinCacheForPhp WinCache].\nA caché de obxectos non está activada.",
+       "config-apc": "[https://secure.php.net/apc APC] está instalado",
+       "config-apcu": "[https://secure.php.net/apcu APCu] está instalado",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] está instalado",
+       "config-no-cache-apcu": "<strong>Advertencia:</strong> Non se puido atopar [https://secure.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] ou [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nA caché de obxectos non está activada.",
        "config-mod-security": "<strong>Atención:</strong> O seu servidor web ten o [https://modsecurity.org/ mod_security] activado. Se estivese mal configurado, pode causar problemas a MediaWiki ou calquera outro software que permita aos usuarios publicar contidos arbitrarios.\nOlle a [https://modsecurity.org/documentation/ documentación do mod_security] ou póñase en contacto co soporte do seu servidor se atopa erros aleatorios.",
        "config-diff3-bad": "GNU diff3 non se atopou.",
        "config-git": "Atopouse o software de control da versión de Git: <code>$1</code>.",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki soporta os seguintes sistemas de bases de datos:\n\n$1\n\nSe non ve listado a continuación o sistema de base de datos que intenta usar, siga as instrucións ligadas enriba para activar o soporte.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] é o obxectivo principal para MediaWiki e está mellor soportado. MediaWiki tamén funciona con [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], que son compatibles con MySQL. ([http://www.php.net/manual/en/mysqli.installation.php  Como compilar PHP con compatibilidade MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] é un sistema de base de datos popular e de código aberto como alternativa a MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Como compilar PHP con compatibilidade PostgreSQL])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] é o obxectivo principal para MediaWiki e está mellor soportado. MediaWiki tamén funciona con [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], que son compatibles con MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php  Como compilar PHP con compatibilidade MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] é un sistema de base de datos popular e de código aberto como alternativa a MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Como compilar PHP con compatibilidade PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] é un sistema de base de datos lixeiro moi ben soportado. ([http://www.php.net/manual/en/pdo.installation.php Como compilar o PHP con soporte SQLite], emprega PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] é un sistema comercial de xestión de base de datos de nivel empresarial. ([http://www.php.net/manual/en/oci8.installation.php Como compilar o PHP con compatibilidade OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] é un sistema comercial de xestión de base de datos de nivel empresarial para Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Como compilar o PHP con compatibilidade SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] é un sistema comercial de xestión de base de datos de nivel empresarial para Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Como compilar o PHP con compatibilidade SQLSRV])",
        "config-header-mysql": "Configuración do MySQL",
        "config-header-postgres": "Configuración do PostgreSQL",
        "config-header-sqlite": "Configuración do SQLite",
        "config-license-help": "Moitos wikis públicos liberan todas as súas contribucións baixo unha [https://freedomdefined.org/Definition/Gl licenza libre].\nIsto axuda a crear un sentido de propiedade comunitaria e anima a seguir contribuíndo durante moito tempo.\nXeralmente, non é necesario nos wikis privados ou de empresas.\n\nSe quere poder empregar textos da Wikipedia, así como que a Wikipedia poida aceptar textos copiados do seu wiki, escolla a licenza <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nA licenza de documentación libre de GNU era a licenza anterior da Wikipedia.\nMalia aínda ser unha licenza válida, é difícil de entender.\nTamén é difícil reusar contidos baixo esta licenza.",
        "config-email-settings": "Configuración do correo electrónico",
        "config-enable-email": "Activar os correos electrónicos de saída",
-       "config-enable-email-help": "Se quere que o correo electrónico funcione, cómpre configurar os [http://www.php.net/manual/en/mail.configuration.php parámetros PHP] correctamente.\nSe non quere ningunha característica no correo, pode desactivalas aquí.",
+       "config-enable-email-help": "Se quere que o correo electrónico funcione, cómpre configurar os [Config-dbsupport-oracle/manual/en/mail.configuration.php parámetros PHP] correctamente.\nSe non quere ningunha característica no correo, pode desactivalas aquí.",
        "config-email-user": "Activar o intercambio de correos electrónicos entre usuarios",
        "config-email-user-help": "Permitir que todos os usuarios intercambien correos electrónicos, se o teñen activado nas súas preferencias.",
        "config-email-usertalk": "Activar a notificación da páxina de conversa de usuario",
index 44f5eb2..48dfbe3 100644 (file)
@@ -49,8 +49,8 @@
        "config-pcre-no-utf8": "'''Fatale Fähler: S PHP-Modul PCRE isch schyns ohni PCRE_UTF8-Unterstitzig kompiliert wore.'''\nMediaWiki brucht d UTF-8-Unterstitzi zum fählerfrej lauffähig syy.",
        "config-memory-raised": "Dr PHP-Parameter <code>memory_limit</code> lyt bi $1 un isch uf $2 uffegsetzt wore.",
        "config-memory-bad": "'''Warnig:''' Dr PHP-Parameter <code>memory_limit</code> lyt bi $1.\nDää Wärt isch wahrschyns z nider.\nDr Inschtallationsvorgang chennt wäge däm fählschlaa!",
-       "config-apc": "[http://www.php.net/apc APC] isch inschtalliert",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] isch inschtalliert",
+       "config-apc": "[https://secure.php.net/apc APC] isch inschtalliert",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] isch inschtalliert",
        "config-diff3-bad": "GNU diff3 isch nit gfunde wore.",
        "config-imagemagick": "ImageMagick isch gfunde wore: <code>$1</code>.\nMiniaturaasichte vu Bilder sin megli, sobald s Uffelade vu Dateie aktiviert isch.",
        "config-help": "Hilf",
index 72a4d7d..36871b8 100644 (file)
        "config-pcre-no-utf8": "<strong>שגיאה סופנית</strong>: נראה שמודול PCRE של PHP מהודר ללא תמיכה ב־PCRE_UTF8.\nמדיה־ויקי דורשת תמיכה ב־UTF-8 לפעילות נכונה.",
        "config-memory-raised": "ערך האפשרות <code>memory_limit</code> של PHP הוא $1, הועלה ל־$2.",
        "config-memory-bad": "'''אזהרה:''' ערך האפשרות <code>memory_limit</code> של PHP הוא $1.\nזה כנראה נמוך מדי.\nההתקנה עשויה להיכשל!",
-       "config-apc": "[http://www.php.net/apc APC] מותקן",
-       "config-apcu": "[http://www.php.net/apcu APCu] מותקן",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] מותקן",
-       "config-no-cache-apcu": "<strong>אזהרה:</strong> לא נמצא [http://www.php.net/apcu APCu]‏ או [http://www.iis.net/download/WinCacheForPhp WinCache].\nמטמון עצמים לא מופעל.",
+       "config-apc": "[https://secure.php.net/apc APC] מותקן",
+       "config-apcu": "[https://secure.php.net/apcu APCu] מותקן",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] מותקן",
+       "config-no-cache-apcu": "<strong>אזהרה:</strong> לא נמצא [https://secure.php.net/apcu APCu]‏ או [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nמטמון עצמים לא מופעל.",
        "config-mod-security": "'''אזהרה''': בשרת הווב שלך מופעל [https://modsecurity.org/ mod_security]. אם הוא לא מוגדר טוב, זה יכול לגרום לבעיות במדיה־ויקי ובתכנה אחרת שמאפשרת למשתמשים לשלוח תוכן שרירותי.\nיש לקרוא את [https://modsecurity.org/documentation/ התיעוד של mod_security] או ליצור קשר עם אנשי התמיכה של שירותי האירוח שלכם אם מופיעות לך שגיאות אקראיות.",
        "config-diff3-bad": "GNU diff3 לא נמצא.",
        "config-git": "נמצאה Git, תכנת בקרת התצורה: <code dir=\"ltr\">$1</code>.",
        "config-type-mysql": "MySQL (או תואם)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "מדיה־ויקי תומכת במערכות מסדי הנתונים הבאות:\n\n$1\n\nאם אינך רואה את מסד הנתונים שלך ברשימה, יש לעקוב אחר ההוראות המקושרות לעיל כדי להפעיל את התמיכה.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] הוא היעד העיקרי עבור מדיה־ויקי ולו התמיכה הטובה ביותר. מדיה־ויקי עובדת גם עם [{{int:version-db-mariadb-url}} MariaDB] ועם [{{int:version-db-percona-url}} Percona Server], שתואמים ל־MySQL. (ר׳ [http://www.php.net/manual/en/mysql.installation.php how to compile PHP with MySQL support])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] הוא מסד נתונים נפוץ בקוד פתוח והוא נפוץ בתור חלופה ל־MySQL. (ר׳ [http://www.php.net/manual/en/pgsql.installation.php how to compile PHP with PostgreSQL support]).",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] הוא היעד העיקרי עבור מדיה־ויקי ולו התמיכה הטובה ביותר. מדיה־ויקי עובדת גם עם [{{int:version-db-mariadb-url}} MariaDB] ועם [{{int:version-db-percona-url}} Percona Server], שתואמים ל־MySQL. (ר׳ [https://secure.php.net/manual/en/mysql.installation.php how to compile PHP with MySQL support])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] הוא מסד נתונים נפוץ בקוד פתוח והוא נפוץ בתור חלופה ל־MySQL. (ר׳ [https://secure.php.net/manual/en/pgsql.installation.php how to compile PHP with PostgreSQL support]).",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] הוא מסד נתונים קליל עם תמיכה טובה מאוד. (ר׳ [http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], משתמש ב־PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] הוא מסד נתונים עסקי מסחרי. (ר׳ [http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] הוא מסד נתונים עסקי מסחרי לחלונות. ([http://www.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] הוא מסד נתונים עסקי מסחרי לחלונות. ([https://secure.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
        "config-header-mysql": "הגדרות MySQL",
        "config-header-postgres": "הגדרות PostgreSQL",
        "config-header-sqlite": "הגדרות SQLite",
        "config-license-help": "אתרי ויקי ציבוריים רבים מפרסמים את כל התרומות [https://freedomdefined.org/Definition ברישיון חופשי].\nזה עוזר ליצור תחושה של בעלות קהילתית ומעודד תרומה לאורך זמן.\nזה בדרך כלל לא נחוץ לאתר ויקי פרטי או אתר של חברה מסחרית.\n\nאם האפשרות להשתמש בטקסט מוויקיפדיה והאפשרות שוויקיפדיה תוכל תקבל עותקים של טקסטים מהוויקי שלך חשובות לך, כדאי לבחור ב<strong>{{int:config-license-cc-by-sa}}</strong>.\n\nויקיפדיה השתמשה בעבר ברישיון החופשי למסמכים של גנו (GNU FDL או GFDL).\nהוא עדיין רישיון תקין, אבל קשה להבנה.\nכמו־כן, קשה לעשות שימוש חוזר ביצירות שפורסמו לפי GFDL.",
        "config-email-settings": "הגדרות דוא״ל",
        "config-enable-email": "להפעיל דוא״ל יוצא",
-       "config-enable-email-help": "אם אתם רוצים שדוא״ל יעבוד, [http://www.php.net/manual/en/mail.configuration.php אפשרויות הדוא״ל של PHP] צריכות להיות מוגדרות נכון.\nאם אינכם רוצים להפעיל שום אפשרויות דוא״ל, כבו אותן כאן ועכשיו.",
+       "config-enable-email-help": "אם אתם רוצים שדוא״ל יעבוד, [Config-dbsupport-oracle/manual/en/mail.configuration.php אפשרויות הדוא״ל של PHP] צריכות להיות מוגדרות נכון.\nאם אינכם רוצים להפעיל שום אפשרויות דוא״ל, כבו אותן כאן ועכשיו.",
        "config-email-user": "להפעיל שליחת דוא״ל ממשתמש למשתמש",
        "config-email-user-help": "לאפשר לכל המשתמשים לשלוח אחד לשני דוא״ל אם הם הפעילו את זה בהעדפות שלהם.",
        "config-email-usertalk": "להפעיל הודעות על דף שיחת משתמש",
index 5e9e1e2..992ba29 100644 (file)
@@ -47,9 +47,9 @@
        "config-env-php": "PHP $1 स्थापित किया गया है।",
        "config-env-hhvm": "एचएचवीएम $1 स्थापित किया गया है।",
        "config-memory-raised": "पीएचपी की <code>memory_limit</code> सीमा $1 है, जो $2 तक बढ़ गई है।",
-       "config-apc": "[http://www.php.net/apc एपीसी] स्थापित है।",
-       "config-apcu": "[http://www.php.net/apcu एपीसीयू] स्थापित है।",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp विनकैश] स्थापित है।",
+       "config-apc": "[https://secure.php.net/apc एपीसी] स्थापित है।",
+       "config-apcu": "[https://secure.php.net/apcu एपीसीयू] स्थापित है।",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension विनकैश] स्थापित है।",
        "config-using-32bit": "<विशेष>चेतावनी:</विशेष> आपका सिस्टम 32-बिट पूर्णांक के साथ चल रहा है यह [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit विवेचित नहीं है]।",
        "config-db-type": "डेटाबेस प्रकार:",
        "config-db-host": "डेटाबेस होस्ट:",
index 343f50b..ef58e56 100644 (file)
@@ -57,8 +57,8 @@
        "config-pcre-no-utf8": "'''Fataler Fehler:''' Das PHP-Modul PCRE scheint ohne PCRE_UTF8-Unterstützung kompiliert worre sin.\nMediaWiki benöticht die UTF-8-Unnerstützung, um fehlerfrei looffähich zu sin.",
        "config-memory-raised": "Der PHP-Parameter <code>memory_limit</code> betruch $1 und woard uff $2 erhöcht.",
        "config-memory-bad": "'''Warnung:''' Der PHP-Parameter <code>memory_limit</code> beträcht $1.\nDer Weart ist wahrscheinlich zu niedrich.\nDer Installationsvoargang könnt doher scheitre!",
-       "config-apc": "[http://www.php.net/apc APC] ist installiert",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] ist installiert",
+       "config-apc": "[https://secure.php.net/apc APC] ist installiert",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] ist installiert",
        "config-mod-security": "'''Warnung:''' Uff dem Webserver woard [https://modsecurity.org/ ModSecurity] aktiviert. Sofern falsch konfiguriert, kann das zu Probleme mit MediaWiki sowie annrer Software uff dem Server führe und es Benutzer ermöchliche beliebiche Inhalte im Wiki Renzustelle.\nFür weitre Informatione empfehle mir die [https://modsecurity.org/documentation/ Dokumentation zu ModSecurity] orrer den Kontakt zum Hoster, sofern Fehler ufftrete.",
        "config-diff3-bad": "GNU diff3 woard net gefund.",
        "config-git": "Die Versionsverwaltungssoftware „Git“ woard gefund: <code>$1</code>.",
        "config-type-mysql": "MySQL (orrer kompatible Datebanksysteme)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki unnerstützt die follichenne Datebanksysteme:\n\n$1\n\nSoweit net das Datebanksystem oongezeicht weard, das verwennt werre soll, gebt das uwe en Link zu der Oonleitung mit Informatione, wie das aktiviert sin kann.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] ist das von MediaWiki primär unterstützte Datebanksystem. MediaWiki funktioniert ooch mit [{{int:version-db-mariadb-url}} MariaDB] und [{{int:version-db-percona-url}} Percona Server], die MySQL-kompatibel sind. ([http://www.php.net/manual/en/mysqli.installation.php Oonleitung zur Kompilierung von PHP mit MySQL-Unnerstützung] [englisch Sproch])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] ist en beliebtes Open-Source-Datebanksystem und ein Alternativ zu MySQL. Es gibt awer enche klenre Implementierungsfehler, so dass von der Nutzung in ener Produktivumgebung abgerat weard. ([http://www.php.net/manual/de/pgsql.installation.php Oonnleitung zur Kompilierung von PHP mit PostgreSQL-Unterstützung])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] ist das von MediaWiki primär unterstützte Datebanksystem. MediaWiki funktioniert ooch mit [{{int:version-db-mariadb-url}} MariaDB] und [{{int:version-db-percona-url}} Percona Server], die MySQL-kompatibel sind. ([https://secure.php.net/manual/en/mysqli.installation.php Oonleitung zur Kompilierung von PHP mit MySQL-Unnerstützung] [englisch Sproch])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] ist en beliebtes Open-Source-Datebanksystem und ein Alternativ zu MySQL. Es gibt awer enche klenre Implementierungsfehler, so dass von der Nutzung in ener Produktivumgebung abgerat weard. ([https://secure.php.net/manual/en/pgsql.installation.php Oonnleitung zur Kompilierung von PHP mit PostgreSQL-Unterstützung])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] ist en verschlanktes Datebanksystem, das ooch gut unnerstützt weard ([http://www.php.net/manual/de/pdo.installation.php Oonleitung zur Kompilierung von PHP mit SQLite-Unterstützung], verwennt PHP Data Objects (PDO))",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] ist en kommerzielle Unnernehmensdatebank ([http://www.php.net/manual/en/oci8.installation.php Oonleitung zur Kompilierung von PHP mit OCI8-Unnerstützung (en)])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ist en gewerbliche Unnernehmensdatebank für Windows. ([http://www.php.net/manual/de/sqlsrv.installation.php Oonleitung zur Kompilierung von PHP mithilfe SQLSRV-Unnerstützung])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ist en gewerbliche Unnernehmensdatebank für Windows. ([Config-dbsupport-oracle/manual/de/sqlsrv.installation.php Oonleitung zur Kompilierung von PHP mithilfe SQLSRV-Unnerstützung])",
        "config-header-mysql": "MySQL-Instellunge",
        "config-header-postgres": "PostgreSQL-Instellunge",
        "config-header-sqlite": "SQLite-Instellunge",
        "config-license-help": "Viele öffentliche Wikis publiziere all Beiträche unner en [https://freedomdefined.org/Definition/De freie Lizenz].\nDas träht dozu bei en Gefühl von Gemeinschaft zu schaffe und ermuticht zu längerfristicher Mitoorweit.\nDahinchege ist im Allgemeinen en freie Lizenz uff geschlossne Wikis net notwennich.\n\nSoweit man Texte aus der Wikipedia verwenne möcht und umgekehrt, sollt die Creative Commons-Lizenz \"Noomenennung, Weitergäb unner gleiche Bedingunge\" gewählt sin.\n\nDie Wikipedia nutzte voarmols die GNU-Lizenz für freie Dokumentation (GFDL).\nDie GFDL ist en gültiche Lizenz, wo awer schwear zu verstehn ist.\nEs ist zudem schwierich gemäss die Lizenz lizenziert Inhalte wiederzuverwenne.",
        "config-email-settings": "E-Mail-Instellunge",
        "config-enable-email": "Ausgehende E-Mails ermöchliche",
-       "config-enable-email-help": "Soweit die E-Mail-Funktione benutzt sin solle, müsse die entsprechende [http://www.php.net/manual/en/mail.configuration.php PHP-E-Mail-Einstellungen] richtich konfiguriert sin.\nFür den Fall, dass die E-Mail-Funktione net benöticht sin, könne die dohier deaktiviert sin.",
+       "config-enable-email-help": "Soweit die E-Mail-Funktione benutzt sin solle, müsse die entsprechende [Config-dbsupport-oracle/manual/en/mail.configuration.php PHP-E-Mail-Einstellungen] richtich konfiguriert sin.\nFür den Fall, dass die E-Mail-Funktione net benöticht sin, könne die dohier deaktiviert sin.",
        "config-email-user": "E-Mail-Versand von Benutzer zu Benutzer aktiviere",
        "config-email-user-help": "Alle Benutzer ermöchliche, sich gecheseitich E-Mails zu schicke, soweit die das in ehre Instellunge aktiviert hoon.",
        "config-email-usertalk": "Benachrichtigunge zu Ändrunge an Benutzerdiskussionsseite ermöchliche",
index 1544d21..3d898ea 100644 (file)
@@ -53,8 +53,8 @@
        "config-pcre-no-utf8": "'''Ćežki zmylk''': Zda so, zo PCRE-modul za PHP ma so bjez PCRE_UTF8-podpěry kompilować.\nMediaWiki trjeba UTF-8-podpěru, zo by korektnje fungował.",
        "config-memory-raised": "PHP-parameter <code>memory_limit</code> je $1, je so na hódnotu $2 zwyšił.",
        "config-memory-bad": "'''Warnowanje:''' PHP-parameter <code>memory_limit</code> ma hódnotu $1,\nTo je najskerje přeniske.\nInstalacija móhła so njeporadźić!",
-       "config-apc": "[http://www.php.net/apc APC] je instalowany",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] je instalowany",
+       "config-apc": "[https://secure.php.net/apc APC] je instalowany",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] je instalowany",
        "config-diff3-bad": "GNU diff3 njenamakany.",
        "config-no-uri": "'''Zmylk:''' Aktualny URI njeda so postajić.\nInstalacija bu přetorhnjena.",
        "config-no-cli-uri": "'''Warnowanje''': Žana skriptowa šćežka (<code>--scriptpath</code>) podata, standard so wužiwa: <code>$1</code>.",
@@ -87,8 +87,8 @@
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] je primarny cil za MediaWiki a podpěruje so najlěpje. MediaWiki funguje tež z [{{int:version-db-mariadb-url}} MariaDB] a [{{int:version-db-percona-url}} Percona Server], kotrejž stej kompatibelnej z MySQL. ([http://www.php.net/manual/en/mysqli.installation.php Nawod ke kompilowanju  PHP z  MySQL-podpěru])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] je popularny system datoweje banki zjawneho žórła jako alternatiwa k MySQL. Móhło hišće někotre zmylki eksistować, a njeporuča so jón w produktiwnej wokolinje wužiwać. ([http://www.php.net/manual/en/pgsql.installation.php Nawod za kompilowanje PHP z podpěru PostgreSQL])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] je primarny cil za MediaWiki a podpěruje so najlěpje. MediaWiki funguje tež z [{{int:version-db-mariadb-url}} MariaDB] a [{{int:version-db-percona-url}} Percona Server], kotrejž stej kompatibelnej z MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Nawod ke kompilowanju  PHP z  MySQL-podpěru])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] je popularny system datoweje banki zjawneho žórła jako alternatiwa k MySQL. Móhło hišće někotre zmylki eksistować, a njeporuča so jón w produktiwnej wokolinje wužiwać. ([https://secure.php.net/manual/en/pgsql.installation.php Nawod za kompilowanje PHP z podpěru PostgreSQL])",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] 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-header-mysql": "Nastajenja MySQL",
        "config-header-postgres": "Nastajenja PostgreSQL",
        "config-license-cc-choose": "Swójsku licencu Creative Commons wubrać",
        "config-email-settings": "E-mejlowe nastajenja",
        "config-enable-email": "Wuchadźace e-mejlki zmóžnić",
-       "config-enable-email-help": "Jeli chceš e-mejl wužiwać, dyrbja so [http://www.php.net/manual/en/mail.configuration.php e-mejlowe nastajenja PHP] prawje konfigurować.\nJeli nochceš e-mejlowe funkcije wužiwać, móžeš je tu znjemóžnić.",
+       "config-enable-email-help": "Jeli chceš e-mejl wužiwać, dyrbja so [Config-dbsupport-oracle/manual/en/mail.configuration.php e-mejlowe nastajenja PHP] prawje konfigurować.\nJeli nochceš e-mejlowe funkcije wužiwać, móžeš je tu znjemóžnić.",
        "config-email-user": "E-mejl mjez wužiwarjemi zmóžnić",
        "config-email-user-help": "Wšěm wužiwarjam dowolić, jednomu druhemu e-mejlki pósłać, jeli su tutu funkciju w swojich nastajenjach zmóžnili.",
        "config-email-usertalk": "Zdźělenja za wužiwarske diskusijne strony zmóžnić",
index 9f5e286..93c95ab 100644 (file)
        "config-pcre-no-utf8": "<strong>Kritikus hiba:</strong> Úgy tűnik, hogy a PHP PRCE modulja PRCE_UTF8 támogatás nélkül lett fordítva.\nA MediaWikinek UTF-8-támogatásra van szüksége a helyes működéshez.",
        "config-memory-raised": "A PHP <code>memory_limit</code> beállításának értéke: $1. Meg lett növelve a következő értékre: $2.",
        "config-memory-bad": "<strong>Figyelmeztetés:</strong> A PHP <code>memory_limit</code> beállításának értéke $1.\nEz az érték valószínűleg túl kevés, a telepítés sikertelen lehet.",
-       "config-apc": "Az [http://www.php.net/apc APC] telepítve van",
-       "config-apcu": "Az [http://www.php.net/apcu APCu] telepítve van",
-       "config-wincache": "A [https://www.iis.net/download/WinCacheForPhp WinCache] telepítve van",
-       "config-no-cache-apcu": "<strong>Figyelmeztetés:</strong> nem találhatók a következők: [http://www.php.net/apcu APCu] vagy [http://www.iis.net/download/WinCacheForPhp WinCache].\nAz objektum gyorsítótárazása nincs engedélyezve.",
+       "config-apc": "Az [https://secure.php.net/apc APC] telepítve van",
+       "config-apcu": "Az [https://secure.php.net/apcu APCu] telepítve van",
+       "config-wincache": "A [https://www.iis.net/downloads/microsoft/wincache-extension WinCache] telepítve van",
+       "config-no-cache-apcu": "<strong>Figyelmeztetés:</strong> nem találhatók a következők: [https://secure.php.net/apcu APCu] vagy [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nAz objektum gyorsítótárazása nincs engedélyezve.",
        "config-diff3-bad": "GNU diff3 nem található.",
        "config-git": "Megtaláltam a Git verziókezelő szoftvert: <code>$1</code>.",
        "config-git-bad": "A Git verziókezelő rendszer nem található.",
        "config-type-mysql": "MySQL (vagy kompatibilis)",
        "config-type-mssql": "Microsoft SQL Szerver",
        "config-support-info": "A MediaWiki a következő adatbázisrendszereket támogatja:\n\n$1\n\nHa az alábbi listán nem találod azt a rendszert, melyet használni szeretnél, a fenti linken található instrukciókat követve engedélyezheted a támogatását.",
-       "config-dbsupport-mysql": "* A [{{int:version-db-mysql-url}} MySQL] a MediaWiki elsődleges célpontja, így a legjobban támogatott. A MediaWiki elfut [{{int:version-db-mariadb-url}} MariaDB-n] és [{{int:version-db-percona-url}} Percona Serveren] is, mivel ezek MySQL-kompatibilisek. ([http://www.php.net/manual/en/mysql.installation.php Hogyan fordítható a PHP MySQL-támogatással])",
-       "config-dbsupport-postgres": "* A [{{int:version-db-postgres-url}} PostgreSQL] népszerű, nyílt forráskódú adatbázisrendszer, a MySQL alternatívája. ([http://www.php.net/manual/en/pgsql.installation.php Hogyan fordítható a PHP PostgreSQL-támogatással])",
+       "config-dbsupport-mysql": "* A [{{int:version-db-mysql-url}} MySQL] a MediaWiki elsődleges célpontja, így a legjobban támogatott. A MediaWiki elfut [{{int:version-db-mariadb-url}} MariaDB-n] és [{{int:version-db-percona-url}} Percona Serveren] is, mivel ezek MySQL-kompatibilisek. ([https://secure.php.net/manual/en/mysql.installation.php Hogyan fordítható a PHP MySQL-támogatással])",
+       "config-dbsupport-postgres": "* A [{{int:version-db-postgres-url}} PostgreSQL] népszerű, nyílt forráskódú adatbázisrendszer, a MySQL alternatívája. ([https://secure.php.net/manual/en/pgsql.installation.php Hogyan fordítható a PHP PostgreSQL-támogatással])",
        "config-dbsupport-sqlite": "* Az [{{int:version-db-sqlite-url}} SQLite] egy könnyű, nagyon jól támogatott adatbázisrendszer. ([http://www.php.net/manual/en/pdo.installation.php Hogyan fordítható a PHP SQLite-támogatással], PDO-t használ)",
        "config-dbsupport-oracle": "* Az [{{int:version-db-oracle-url}} Oracle] kereskedelmi, vállalati adatbázisrendszer. ([http://www.php.net/manual/en/oci8.installation.php Hogyan fordítható a PHP OCI8-támogatással])",
-       "config-dbsupport-mssql": "* A [{{int:version-db-mssql-url}} Microsoft SQL Server] kereskedelmi, vállalati adatbázisrendszer. ([http://www.php.net/manual/en/sqlsrv.installation.php Hogyan fordítható a PHP SQLSRV-támogatással])",
+       "config-dbsupport-mssql": "* A [{{int:version-db-mssql-url}} Microsoft SQL Server] kereskedelmi, vállalati adatbázisrendszer. ([https://secure.php.net/manual/en/sqlsrv.installation.php Hogyan fordítható a PHP SQLSRV-támogatással])",
        "config-header-mysql": "MySQL-beállítások",
        "config-header-postgres": "PostgreSQL-beállítások",
        "config-header-sqlite": "SQLite-beállítások",
        "config-license-help": "A legtöbb wiki valamilyen [https://freedomdefined.org/Definition szabad licenc] alatt teszi közzé a szerkesztéseit.\nEz erősíti a közösségi tulajdon érzését, és elősegíti a hosszú távú közreműködők megjelenését.\nÁltalában nem szükséges magán- vagy vállalati wiki esetén.\n\nHa a Wikipédiáról szeretnél szövegeket másolni, és azt szeretnéd, hogy a Wikipédián felhasználhassák a wikidben található szöveget, akkor a <strong>{{int:config-license-cc-by-sa}}</strong> lehetőséget válaszd.\n\nA Wikipédia korábban a GNU Szabad Dokumentációs Licencet használta.\nEz a licenc még ma is használható, azonban nem könnyű megérteni,\ntovábbá a GFDL alatt közzétett tartalom újrafelhasználása nehézkes.",
        "config-email-settings": "E-mail beállítások",
        "config-enable-email": "Kimenő e-mailek engedélyezése",
-       "config-enable-email-help": "E-mailek küldéséhez [http://www.php.net/manual/en/mail.configuration.php a PHP mail beállításait] megfelelően meg kell adni.\nHa nem akarsz semmilyen e-mailes funkciót használni, itt tilthatod le őket.",
+       "config-enable-email-help": "E-mailek küldéséhez [Config-dbsupport-oracle/manual/en/mail.configuration.php a PHP mail beállításait] megfelelően meg kell adni.\nHa nem akarsz semmilyen e-mailes funkciót használni, itt tilthatod le őket.",
        "config-email-user": "A felhasználók küldhetnek egymásnak e-maileket",
        "config-email-user-help": "Bármelyik felhasználó küldhet másiknak e-mail üzenetet, amennyiben engedélyezték a lehetőséget a beállításaiknál.",
        "config-email-usertalk": "Vitalapi értesítések engedélyezése",
index a7ede0a..7ef9c2d 100644 (file)
        "config-pcre-no-utf8": "'''Fatal''': Le modulo PCRE de PHP pare haber essite compilate sin supporto de PCRE_UTF8.\nMediaWiki require supporto de UTF-8 pro functionar correctemente.",
        "config-memory-raised": "Le <code>memory_limit</code> de PHP es $1, elevate a $2.",
        "config-memory-bad": "'''Aviso:''' Le <code>memory_limit</code> de PHP es $1.\nIsto es probabilemente troppo basse.\nLe installation pote faller!",
-       "config-apc": "[http://www.php.net/apc APC] es installate",
-       "config-apcu": "[http://www.php.net/apcu APCu] es installate",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] es installate",
-       "config-no-cache-apcu": "<strong>Attention:</strong> Impossibile trovar [http://www.php.net/apcu APCu] o [http://www.iis.net/download/WinCacheForPhp WinCache].\nLe cache de objectos non es activate.",
+       "config-apc": "[https://secure.php.net/apc APC] es installate",
+       "config-apcu": "[https://secure.php.net/apcu APCu] es installate",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] es installate",
+       "config-no-cache-apcu": "<strong>Attention:</strong> Impossibile trovar [https://secure.php.net/apcu APCu] o [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nLe cache de objectos non es activate.",
        "config-mod-security": "<strong>Attention</strong>: [https://modsecurity.org/ mod_security]/mod_security2 es active in tu servitor web. Multe configurationes commun de isto causa problemas pro MediaWiki o altere software que permitte al usatores de publicar contento arbitrari. Si possibile, isto deberea esser disactivate.\nAlteremente, consulta le [https://modsecurity.org/documentation/ documentation de mod_security] o contacta le servicio de adjuta de tu servitor si tu incontra estranie errores.",
        "config-diff3-bad": "GNU diff3 non trovate.",
        "config-git": "Systema de controlo de version Git trovate: <code>$1</code>",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki supporta le sequente systemas de base de datos:\n\n$1\n\nSi tu non vide hic infra le systema de base de datos que tu tenta usar, alora seque le instructiones ligate hic supra pro activar le supporto.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] es le systema primari pro MediaWiki e le melio supportate. MediaWiki functiona anque con [{{int:version-db-mariadb-url}} MariaDB] e con [{{int:version-db-percona-url}} Percona Server], le quales es compatibile con MySQL. ([http://www.php.net/manual/en/mysqli.installation.php Como compilar PHP con supporto de MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] es un systema de base de datos popular e open source, alternativa a MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Como compilar PHP con supporto de PostgreSQL])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] es le systema primari pro MediaWiki e le melio supportate. MediaWiki functiona anque con [{{int:version-db-mariadb-url}} MariaDB] e con [{{int:version-db-percona-url}} Percona Server], le quales es compatibile con MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Como compilar PHP con supporto de MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] es un systema de base de datos popular e open source, alternativa a MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Como compilar PHP con supporto de PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] es un systema de base de datos legier que es multo ben supportate. ([http://www.php.net/manual/en/pdo.installation.php Como compilar PHP con supporto de SQLite], usa PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] es un banca de datos commercial pro interprisas. ([http://www.php.net/manual/en/oci8.installation.php Como compilar PHP con supporto de OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] es un base de datos de interprisa commercial pro Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Como compilar PHP con supporto de SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] es un base de datos de interprisa commercial pro Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Como compilar PHP con supporto de SQLSRV])",
        "config-header-mysql": "Configuration de MySQL",
        "config-header-postgres": "Configuration de PostgreSQL",
        "config-header-sqlite": "Configuration de SQLite",
        "config-license-help": "Multe wikis public pone tote le contributiones sub un [https://freedomdefined.org/Definition/Ia?uselang=ia licentia libere].\nIsto adjuta a crear un senso de proprietate communitari e incoragia le contribution in longe termino.\nIsto non es generalmente necessari pro un wiki private o de interprisa.\n\nSi tu vole poter usar texto de Wikipedia, e si tu vole que Wikipedia pote acceptar texto copiate de tu wiki, tu debe seliger <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipedia usava anteriormente le Licentia GNU pro Documentation Libere (GFDL).\nIste es un licentia valide, ma es difficile a comprender.\nIl es anque difficile reusar le contento licentiate sub GFDL.",
        "config-email-settings": "Configuration de e-mail",
        "config-enable-email": "Activar le e-mail sortiente",
-       "config-enable-email-help": "Si tu vole que e-mail functiona, [http://www.php.net/manual/en/mail.configuration.php le optiones de e-mail de PHP] debe esser configurate correctemente.\nSi tu non vole functiones de e-mail, tu pote disactivar los hic.",
+       "config-enable-email-help": "Si tu vole que e-mail functiona, [Config-dbsupport-oracle/manual/en/mail.configuration.php le optiones de e-mail de PHP] debe esser configurate correctemente.\nSi tu non vole functiones de e-mail, tu pote disactivar los hic.",
        "config-email-user": "Activar le e-mail de usator a usator",
        "config-email-user-help": "Permitter a tote le usatores de inviar e-mail inter se, si illes lo ha activate in lor preferentias.",
        "config-email-usertalk": "Activar notification de cambios in paginas de discussion de usatores",
index 6e1834f..7605f85 100644 (file)
@@ -71,9 +71,9 @@
        "config-pcre-no-utf8": "'''Fatal''': Modul PCRE PHP tampaknya dikompilasi tanpa dukungan PCRE_UTF8.\nMediaWiki memerlukan dukungan UTF-8 untuk berfungsi dengan benar.",
        "config-memory-raised": "<code>memory_limit</code> PHP adalah $1, dinaikkan ke $2.",
        "config-memory-bad": "'''Peringatan:''' <code>memory_limit</code> PHP adalah $1.\nIni terlalu rendah.\nInstalasi terancam gagal!",
-       "config-apc": "[http://www.php.net/apc APC] telah diinstal",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] telah diinstal",
-       "config-no-cache-apcu": "<strong>Peringatan:</strong> Tidak dapat menemukan [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] atau [http://www.iis.net/download/WinCacheForPhp WinCache]. Singgahan obyek tidak diaktifkan.",
+       "config-apc": "[https://secure.php.net/apc APC] telah diinstal",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] telah diinstal",
+       "config-no-cache-apcu": "<strong>Peringatan:</strong> Tidak dapat menemukan [https://secure.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] atau [https://www.iis.net/downloads/microsoft/wincache-extension WinCache]. Singgahan obyek tidak diaktifkan.",
        "config-mod-security": "<strong>Peringatan:</strong> Server web Anda memiliki [https://modsecurity.org/ mod_security] yang diaktifkan. Jika salah dalam mengkonfigurasi, ini dapat menyebabkan masalah untuk MediaWiki atau perangkat lunak lain yang memungkinkan pengguna untuk mengirim sembarang konten.\nLihat [https://modsecurity.org/documentation/ dokumentasi mod_security] atau hubungi layanan host Anda jika Anda mengalami kesalahan acak.",
        "config-diff3-bad": "GNU diff3 tidak ditemukan.",
        "config-git": "Menemukan perangkat lunak kontrol versi Git: <code>$1</code>.",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki mendukung sistem basis data berikut:\n\n$1\n\nJika Anda tidak melihat sistem basis data yang Anda gunakan tercantum di bawah ini, ikuti petunjuk terkait di atas untuk mengaktifkan dukungan.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] adalah target utama MediaWiki dan memiliki dukungan terbaik. MediaWiki juga berjalan dengan [{{int:version-db-mariadb-url}} MariaDB] dan [{{int:version-db-percona-url}} Server Percona], yang kompatibel dengan MySQL. ([http://www.php.net/manual/en/mysql.installation.php Cara mengompilasi PHP dengan dukungan MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] adalah sistem basis data sumber terbuka populer sebagai alternatif MySQL.([http://www.php.net/manual/en/pgsql.installation.php Bagaimana mengompilasikan PHP dengan dukungan PostgreSQL])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] adalah target utama MediaWiki dan memiliki dukungan terbaik. MediaWiki juga berjalan dengan [{{int:version-db-mariadb-url}} MariaDB] dan [{{int:version-db-percona-url}} Server Percona], yang kompatibel dengan MySQL. ([https://secure.php.net/manual/en/mysql.installation.php Cara mengompilasi PHP dengan dukungan MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] adalah sistem basis data sumber terbuka populer sebagai alternatif MySQL.([https://secure.php.net/manual/en/pgsql.installation.php Bagaimana mengompilasikan PHP dengan dukungan PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] 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-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] adalah basis data komersial untuk perusahaan. ([http://www.php.net/manual/en/oci8.installation.php cara mengompilasi PHP dengan dukungan OCI8])",
-       "config-dbsupport-mssql": "[{{int:version-db-mssql-url}} Microsoft SQL Server] adalah database perusahaan komersial untuk Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Bagaimana cara mengkompilasi PHP dengan dukungan SQLSRV])",
+       "config-dbsupport-mssql": "[{{int:version-db-mssql-url}} Microsoft SQL Server] adalah database perusahaan komersial untuk Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Bagaimana cara mengkompilasi PHP dengan dukungan SQLSRV])",
        "config-header-mysql": "Pengaturan MySQL",
        "config-header-postgres": "Pengaturan PostgreSQL",
        "config-header-sqlite": "Pengaturan SQLite",
        "config-license-help": "Banyak wiki publik melisensikan semua kontribusi di bawah [https://freedomdefined.org/Definition lisensi bebas].\nHal ini membantu menciptakan rasa kepemilikan komunitas dan mendorong kontribusi jangka panjang.\nHal ini umumnya tidak diperlukan untuk wiki pribadi atau perusahaan.\n\nJika Anda ingin dapat menggunakan teks dari Wikipedia dan Anda ingin agar Wikipedia dapat menerima teks yang disalin dari wiki Anda, Anda harus memilih <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipedia sebelumnya menggunakan GNU Free Documentation License.\nLisensi ini masih sah, namun sulit dipahami.\nSelain itu, sulit untuk menggunakan ulang konten yang dilisensikan di bawah GFDL.",
        "config-email-settings": "Pengaturan surel",
        "config-enable-email": "Aktifkan surel keluar",
-       "config-enable-email-help": "Jika Anda ingin mengaktifkan surel, [http://www.php.net/manual/en/mail.configuration.php setelah surel PHP] perlu dikonfigurasi dengan benar.\nJika Anda tidak perlu fitur surel, Anda dapat menonaktifkannya di sini.",
+       "config-enable-email-help": "Jika Anda ingin mengaktifkan surel, [Config-dbsupport-oracle/manual/en/mail.configuration.php setelah surel PHP] perlu dikonfigurasi dengan benar.\nJika Anda tidak perlu fitur surel, Anda dapat menonaktifkannya di sini.",
        "config-email-user": "Aktifkan surel antarpengguna",
        "config-email-user-help": "Memungkinkan semua pengguna untuk saling berkirim surel jika mereka mengaktifkan pilihan tersebut dalam preferensi mereka.",
        "config-email-usertalk": "Aktifkan pemberitahuan perubahan halaman pembicaraan pengguna",
index 78be96b..2f5826f 100644 (file)
@@ -34,8 +34,8 @@
        "config-copyright": "=== Höfundarréttur og skilmálar ===\n\n$1\n\nÞetta er frjáls hugbúnaður; þú mátt dreifa honum og/eða breyta samkvæmt skilmálum í almenna GNU GPL notkunarleyfinu eins og það er gefið út af Frjálsu hugbúnaðarstofnuninni; annaðhvort útgáfu 2 af GPL-leyfinu, eða (ef þér sýnist svo) einhverri nýrri útgáfu leyfisins.\n\nHugbúnaði þessum er dreift í þeirri von að hann geti verið gagnlegur, en <strong>ÁN ALLRAR ÁBYRGÐAR</strong>; einnig án þeirrar ábyrgðar sem gefin er í skyn með <strong>SELJANLEIKA</strong> eða <strong>EIGINLEIKUM TIL TILTEKINNA NOTA</strong>. Sjá almenna GNU GPL notkunarleyfið fyrir nánari upplýsingar.\n\nÞað ætti að hafa fylgt afrit af almenna <doclink href=Copying>GNU GPL notkunarleyfinu</doclink> með forritinu; ef ekki skrifið þá Fjálsu hugbúnarstofnuninni: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA, eða [https://www.gnu.org/copyleft/gpl.html lestu það á netinu].",
        "config-env-php": "PHP $1 er uppsett.",
        "config-env-hhvm": "HHVM $1 er uppsett.",
-       "config-apc": "[http://www.php.net/apc APC] er uppsett",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] er uppsett",
+       "config-apc": "[https://secure.php.net/apc APC] er uppsett",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] er uppsett",
        "config-diff3-bad": "GNU diff3 fannst ekki.",
        "config-using-server": "Nota \"<nowiki>$1</nowiki>\" sem heiti á þjóni.",
        "config-using-uri": "Nota \"<nowiki>$1$2</nowiki>\" sem slóð á þjón.",
index b9f0482..35adc1c 100644 (file)
        "config-pcre-no-utf8": "'''Errore''': Il modulo PCRE di PHP sembra essere stato compilato senza il supporto PCRE_UTF8, ma MediaWiki lo richiede per funzionare correttamente.",
        "config-memory-raised": "Il valore <code>memory_limit</code> di PHP è $1, aumentato a $2.",
        "config-memory-bad": "''Attenzione:''' Il valore di <code>memory_limit</code> di PHP è $1.\nProbabilmente è troppo basso.\nL'installazione potrebbe non riuscire!",
-       "config-apc": "[http://www.php.net/apc APC] è installato",
-       "config-apcu": "[http://www.php.net/apc APC] è installato",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] è installato",
-       "config-no-cache-apcu": "'''Attenzione:''' [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] o [http://www.iis.net/download/WinCacheForPhp WinCache] non sono stati trovati.\nLa caching degli oggetti non è attivata.",
+       "config-apc": "[https://secure.php.net/apc APC] è installato",
+       "config-apcu": "[https://secure.php.net/apcu APCu] è installato",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] è installato",
+       "config-no-cache-apcu": "'''Attenzione:''' [https://secure.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] o [https://www.iis.net/downloads/microsoft/wincache-extension WinCache] non sono stati trovati.\nLa caching degli oggetti non è attivata.",
        "config-mod-security": "<strong>Attenzione:</strong> Il tuo server web ha il [https://modsecurity.org/ mod_security] abilitato. Se non correttamente configurato, può creare problemi a MediaWiki o ad altro software che permette agli utenti di pubblicare contenuto.\nFai riferimento alla [https://modsecurity.org/documentation/ documentazione sul mod_security] o contatta il supporto tecnico del tuo provider di hosting se si verificano errori.",
        "config-diff3-bad": "GNU diff3 non trovato.",
        "config-git": "Trovato software di controllo della versione Git: <code>$1</code>.",
        "config-type-mysql": "MySQL (o compatibile)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki supporta i seguenti sistemi di database:\n\n$1\n\nSe fra quelli elencati qui sotto non vedi il sistema di database che vorresti utilizzare, seguire le istruzioni linkate sopra per abilitare il supporto.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] è la configurazione preferibile per MediaWiki ed è quella meglio supportata. MediaWiki funziona anche con [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], che sono compatibili con MySQL.([http://www.php.net/manual/en/mysqli.installation.php Come compilare PHP con supporto MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] è un popolare sistema di database open source come alternativa a MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Come compilare PHP con supporto PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]  è un sistema di database leggero, che è supportato molto bene. ([http://www.php.net/manual/en/pdo.installation.php Come compilare PHP con supporto SQLite], utilizza PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] è un database di un'impresa commerciale. ([http://www.php.net/manual/en/oci8.installation.php Come compilare PHP con supporto OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] è un database di un'impresa commerciale per Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Come compilare PHP con supporto SQLSRV])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] è la configurazione preferibile per MediaWiki ed è quella meglio supportata. MediaWiki funziona anche con [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], che sono compatibili con MySQL.([https://secure.php.net/manual/en/mysqli.installation.php Come compilare PHP con supporto MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] è un popolare sistema di database open source come alternativa a MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Come compilare PHP con supporto PostgreSQL])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]  è un sistema di database leggero, che è supportato molto bene. ([https://secure.php.net/manual/en/pdo.installation.php Come compilare PHP con supporto SQLite], utilizza PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] è un database di un'impresa commerciale. ([https://secure.php.net/manual/en/oci8.installation.php Come compilare PHP con supporto OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] è un database di un'impresa commerciale per Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Come compilare PHP con supporto SQLSRV])",
        "config-header-mysql": "Impostazioni MySQL",
        "config-header-postgres": "Impostazioni PostgreSQL",
        "config-header-sqlite": "Impostazioni SQLite",
        "config-license-help": "Molti wiki pubblici rilasciano i loro contributi con una [https://freedomdefined.org/Definition licenza libera]. Questo aiuta a creare un senso di proprietà condivisa nella comunità e incoraggia a contribuire a lungo termine. Non è generalmente necessario per un wiki privato o aziendale.\n\nSe vuoi usare testi da Wikipedia, o desideri che Wikipedia possa essere in grado di accettare testi copiati dal tuo wiki, dovresti scegliere <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nIn precedenza Wikipedia ha utilizzato la GNU Free Documentation License. La GFDL è una licenza valida, ma è di difficile comprensione e complica il riutilizzo dei contenuti.",
        "config-email-settings": "Impostazioni email",
        "config-enable-email": "Abilita la posta elettronica in uscita",
-       "config-enable-email-help": "Se vuoi che funzionino le email, le [http://www.php.net/manual/en/mail.configuration.php PHP's impostazioni della posta] devono essere configurate correttamente.\nSe non si desidera alcuna funzionalità di posta elettronica, puoi disabilitarla qui.",
+       "config-enable-email-help": "Se vuoi che funzionino le email, le [https://secure.php.net/manual/en/mail.configuration.php impostazioni della posta] devono essere configurate correttamente.\nSe non si desidera alcuna funzionalità di posta elettronica, puoi disabilitarla qui.",
        "config-email-user": "Abilita invio email fra utenti",
        "config-email-user-help": "Consente a tutti gli utenti di inviarsi a vicenda email, se lo hanno abilitato nelle loro preferenze.",
        "config-email-usertalk": "Abilita le notifiche per le pagine di discussione utente",
index a784813..838eaae 100644 (file)
        "config-pcre-no-utf8": "<strong>致命的エラー:</strong> PHP の PCRE が PCRE_UTF8 対応なしでコンパイルされているようです。\nMediaWiki を正しく動作させるには、UTF-8 対応が必要です。",
        "config-memory-raised": "PHPの<code>memory_limit</code>は$1で、$2に引き上げられました。",
        "config-memory-bad": "<strong>警告:</strong> PHPの<code>memory_limit</code>に$1に設定されています。\nこの値はおそらく小さすぎます。\nインストールが失敗するおそれがあります!",
-       "config-apc": "[http://www.php.net/apc APC] がインストール済み",
-       "config-apcu": "[http://www.php.net/apcu APCu] がインストール済み",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] がインストール済み",
-       "config-no-cache-apcu": "<strong>警告:</strong> [http://www.php.net/apcu APCu]、 [http://www.iis.net/download/WinCacheForPhp WinCache] のいずれも見つかりませんでした。\nオブジェクトのキャッシュは有効化されません。",
+       "config-apc": "[https://secure.php.net/apc APC] がインストール済み",
+       "config-apcu": "[https://secure.php.net/apcu APCu] がインストール済み",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] がインストール済み",
+       "config-no-cache-apcu": "<strong>警告:</strong> [https://secure.php.net/apcu APCu]、 [https://www.iis.net/downloads/microsoft/wincache-extension WinCache] のいずれも見つかりませんでした。\nオブジェクトのキャッシュは有効化されません。",
        "config-mod-security": "<strong>警告:</strong> あなたのウェブサーバーでは [https://modsecurity.org/ mod_security] が有効になっています。正しく構成されていない場合は、MediaWiki や利用者にコンテンツの投稿を許可するその他のソフトウェアに問題が発生する場合があります。\n[https://modsecurity.org/documentation/ mod_security の説明文書]を確認するか、ランダムなエラーが発生した場合はあなたのホストのサポートにお問い合わせください。",
        "config-diff3-bad": "GNU diff3 が見つかりません。",
        "config-git": "バージョン管理ソフトウェア Git が見つかりました: <code>$1</code>",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "マイクロソフト SQL Server",
        "config-support-info": "MediaWiki は以下のデータベース システムに対応しています:\n\n$1\n\n使用しようとしているデータベース システムが下記の一覧にない場合は、上記リンク先の手順に従ってインストールしてください。",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL]はMediaWikiの主要な対象であり、最もよくサポートされています。MediaWikiはMySQLと互換性のある[{{int:version-db-mariadb-url}} MariaDB]、[{{int:version-db-percona-url}} Percona Server]でも動きます。 ([http://www.php.net/manual/ja/mysqli.installation.php PHPをMySQLサポート付きでコンパイルする方法])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] は、MySQLの代替として人気がある公開のデータベースシステムです。([http://www.php.net/manual/en/pgsql.installation.php PHPをPostgreSQLサポート付きでコンパイルする方法])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL]はMediaWikiの主要な対象であり、最もよくサポートされています。MediaWikiはMySQLと互換性のある[{{int:version-db-mariadb-url}} MariaDB]、[{{int:version-db-percona-url}} Percona Server]でも動きます。 ([https://secure.php.net/manual/ja/mysqli.installation.php PHPをMySQLサポート付きでコンパイルする方法])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] は、MySQLの代替として人気がある公開のデータベースシステムです。([https://secure.php.net/manual/en/pgsql.installation.php PHPをPostgreSQLサポート付きでコンパイルする方法])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]は、良くサポートされている、軽量データベースシステムです。([http://www.php.net/manual/ja/pdo.installation.php SQLiteに対応したPHPをコンパイルする方法]、PDOを使用)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle]は商業企業のデータベースです。([http://www.php.net/manual/en/oci8.installation.php OCI8サポートなPHPをコンパイルする方法])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]は商業企業のWindows用データベースです。([http://www.php.net/manual/en/sqlsrv.installation.php SQLSRVサポートなPHPをコンパイルする方法])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]は商業企業のWindows用データベースです。([https://secure.php.net/manual/en/sqlsrv.installation.php SQLSRVサポートなPHPをコンパイルする方法])",
        "config-header-mysql": "MySQL の設定",
        "config-header-postgres": "PostgreSQL の設定",
        "config-header-sqlite": "SQLite の設定",
        "config-license-help": "多くの公開ウィキでは、すべての寄稿物が[https://freedomdefined.org/Definition フリーライセンス]のもとに置かれています。\nこうすることにより、コミュニティによる共有の感覚が生まれ、長期的な寄稿が促されます。\n私的ウィキや企業のウィキでは、通常、フリーライセンスにする必要はありません。\n\nウィキペディアにあるテキストをあなたのウィキで利用し、逆にあなたのウィキにあるテキストをウィキペディアに複製することを許可したい場合には、<strong>{{int:config-license-cc-by-sa}}</strong>を選択するべきです。\n\nウィキペディアは以前、GNUフリー文書利用許諾契約書(GFDL)を使用していました。\nGFDLは有効なライセンスですが、内容を理解するのは困難です。\nまた、GFDLのもとに置かれているコンテンツの再利用も困難です。",
        "config-email-settings": "メールの設定",
        "config-enable-email": "メール送信を有効にする",
-       "config-enable-email-help": "メールを使用したい場合は、[http://www.php.net/manual/en/mail.configuration.php PHP のメール設定]が正しく設定されている必要があります。\nメールの機能を使用しない場合は、ここで無効にすることができます。",
+       "config-enable-email-help": "メールを使用したい場合は、[Config-dbsupport-oracle/manual/en/mail.configuration.php PHP のメール設定]が正しく設定されている必要があります。\nメールの機能を使用しない場合は、ここで無効にすることができます。",
        "config-email-user": "利用者間のメールを有効にする",
        "config-email-user-help": "設定で有効になっている場合、すべてのユーザーがお互いにメールのやりとりを行うことを許可する。",
        "config-email-usertalk": "ユーザーのトークページでの通知を有効にする",
index fb47fcd..2d12f47 100644 (file)
@@ -27,8 +27,8 @@
        "config-sidebar": "* [https://www.mediawiki.org მედიავიკის ვებ-გვერდი]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents/ka მომხმარებლების დახმარება]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents/ka ადმინისტრატორების დახმარება]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/ka FAQ]\n----\n* <doclink href=Readme>წამიკითხე</doclink>\n* <doclink href=ReleaseNotes>ინფორმაცია გამოშვებაზე</doclink>\n* <doclink href=Copying>ლიცენზია</doclink>\n* <doclink href=UpgradeDoc>განახლება</doclink>",
        "config-env-php": "PHP $1 დაინსტალირებულია",
        "config-env-hhvm": "HHVM $1 დაინსტალირებულია.",
-       "config-apc": "[http://www.php.net/apc APC] დაყენდა",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] დაყენდა",
+       "config-apc": "[https://secure.php.net/apc APC] დაყენდა",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] დაყენდა",
        "config-diff3-bad": "GNU diff3 ვერ მოიძებნა.",
        "config-db-type": "მონაცემთა ბაზის ტიპი:",
        "config-db-host-oracle": "მონაცემთა ბაზის TNS:",
index 3e646bf..d97c55f 100644 (file)
        "config-pcre-no-utf8": "<strong>치명:</strong> PHP의 PCRE 모듈은 RCRE_UTF8 지원 없이 컴파일된 것 같습니다.\n미디어위키가 올바르게 작동하려면 UTF-8을 지원해야 합니다.",
        "config-memory-raised": "PHP의 <code>memory_limit</code>는 $1이며 $2(으)로 늘렸습니다.",
        "config-memory-bad": "<strong>경고:</strong> PHP의 <code>memory_limit</code>는 $1입니다.\n아마도 너무 낮은 것 같습니다.\n설치가 실패할 수 있습니다!",
-       "config-apc": "[http://www.php.net/apc APC]가 설치되었습니다",
-       "config-apcu": "[http://www.php.net/apcu APCu]가 설치되었습니다",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache]가 설치되었습니다",
-       "config-no-cache-apcu": "<strong>경고:</strong> [http://www.php.net/apcu APCu] 또는 [http://www.iis.net/download/WinCacheForPhp WinCache]를 찾을 수 없습니다.",
+       "config-apc": "[https://secure.php.net/apc APC]가 설치되었습니다",
+       "config-apcu": "[https://secure.php.net/apcu APCu]가 설치되었습니다",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache]가 설치되었습니다",
+       "config-no-cache-apcu": "<strong>경고:</strong> [https://secure.php.net/apcu APCu] 또는 [https://www.iis.net/downloads/microsoft/wincache-extension WinCache]를 찾을 수 없습니다.",
        "config-mod-security": "<strong>경고:</strong> 웹 서버에 [https://modsecurity.org/ mod_security]가 허용되었습니다. 잘못 설정된 경우 미디어위키나 사용자가 임의의 내용을 게시할 수 있는 다른 소프트웨어에 대한 문제를 일으킬 수 있습니다.\n[https://modsecurity.org/documentation/ mod_security] 문서를 참고하거나 임의의 오류가 발생할 경우 호스트의 지원 요청에 문의하십시오.",
        "config-diff3-bad": "GNU diff3를 찾을 수 없습니다.",
        "config-git": "Git 버전 관리 소프트웨어를 찾았습니다: <code>$1</code>.",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL 서버",
        "config-support-info": "미디어위키는 다음의 데이터베이스 시스템을 지원합니다:\n\n$1\n\n데이터베이스 시스템이 표시되지 않을 때 아래에 나열된 다음 지원을 활성화하려면 위의 링크된 지시에 따라 설치해볼 수 있습니다.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL]은 미디어위키의 기본 대상이며 가장 잘 지원됩니다. 미디어위키는 또한 MySQL와 호환되는 [{{int:version-db-mariadb-url}} MariaDB]와 [{{int:version-db-percona-url}} Percona 서버]에서도 작동합니다. ([http://www.php.net/manual/en/mysql.installation.php MySQL 지원으로 PHP를 컴파일하는 방법])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL]은 MySQL의 대안으로서 인기 있는 오픈 소스 데이터베이스 시스템입니다. ([http://www.php.net/manual/en/pgsql.installation.php PostgreSQL 지원으로 PHP를 컴파일하는 방법])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL]은 미디어위키의 기본 대상이며 가장 잘 지원됩니다. 미디어위키는 또한 MySQL와 호환되는 [{{int:version-db-mariadb-url}} MariaDB]와 [{{int:version-db-percona-url}} Percona 서버]에서도 작동합니다. ([https://secure.php.net/manual/en/mysql.installation.php MySQL 지원으로 PHP를 컴파일하는 방법])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL]은 MySQL의 대안으로서 인기 있는 오픈 소스 데이터베이스 시스템입니다. ([https://secure.php.net/manual/en/pgsql.installation.php PostgreSQL 지원으로 PHP를 컴파일하는 방법])",
        "config-dbsupport-sqlite": "*  [{{int:version-db-sqlite-url}} SQLite]는 매우 잘 지원되고 가벼운 데이터베이스 시스템입니다. ([http://www.php.net/manual/en/pdo.installation.php SQLite 지원으로 PHP를 컴파일하는 방법], PDO 사용)",
        "config-dbsupport-oracle": "*  [{{int:version-db-oracle-url}} Oracle]은 상용 기업 데이터베이스입니다. ([http://www.php.net/manual/en/oci8.installation.php OCI8 지원으로 PHP를 컴파일하는 방법])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL 서버]는 Windows용 상용 기업 데이터베이스입니다. ([http://www.php.net/manual/en/sqlsrv.installation.php SQLSRV 지원으로 PHP를 컴파일하는 방법])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL 서버]는 Windows용 상용 기업 데이터베이스입니다. ([https://secure.php.net/manual/en/sqlsrv.installation.php SQLSRV 지원으로 PHP를 컴파일하는 방법])",
        "config-header-mysql": "MySQL 설정",
        "config-header-postgres": "PostgreSQL 설정",
        "config-header-sqlite": "SQLite 설정",
        "config-license-help": "많은 공개 위키는 모든 기여를 [https://freedomdefined.org/Definition 자유 라이선스]에 따르도록 합니다.\n이렇게 하면 커뮤니티에 대한 소유권을 이해할 수 있도록 하고 장기적인 기여를 장려합니다.\n일반적으로 개인 또는 회사 위키에게는 필요하지 않습니다.\n\n위키백과의 텍스트를 사용할 수 있도록 하고 위키백과가 위키에서 복사한 텍스트를 사용할 수 있도록 원한다면 <strong>{{int:config-license-cc-by-sa}}</strong>으로 선택해야 합니다.\n\n위키백과는 이전에 GNU 자유 문서 사용 허가서(GFDL)를 사용했습니다.\nGFDL은 유효한 라이선스이지만 내용을 이해하기 어렵습니다.\nGFDL에 따라 사용이 허가된 내용을 재사용하는 것도 어렵습니다.",
        "config-email-settings": "이메일 설정",
        "config-enable-email": "발신 이메일 활성화",
-       "config-enable-email-help": "이메일을 작동하려면 [http://www.php.net/manual/en/mail.configuration.php PHP의 메일 설정]을 올바르게 설정해야 합니다.\n이메일 기능을 사용하지 않으려면 이를 비활성화할 수 있습니다.",
+       "config-enable-email-help": "이메일을 작동하려면 [Config-dbsupport-oracle/manual/en/mail.configuration.php PHP의 메일 설정]을 올바르게 설정해야 합니다.\n이메일 기능을 사용하지 않으려면 이를 비활성화할 수 있습니다.",
        "config-email-user": "사용자와 사용자 간 이메일 활성화",
        "config-email-user-help": "환경 설정에서 활성화한 경우 모든 사용자가 이메일을 서로 보내도록 활성화합니다.",
        "config-email-usertalk": "사용자 토론 문서 알림 활성화",
index 2ccf4e0..4b89b41 100644 (file)
@@ -60,9 +60,9 @@
        "config-pcre-no-utf8": "'''Dä:''' Et PHP-Modul <i lang=\"en\">PCRE</i> schingk ohne de <i lang=\"en\">PCRE_UTF8</i>-Aandeile övversaz ze sin.\nMediaWiki bruch dä UTF-8-Krohm ävver, öm ohne Fähler loufe ze künne.",
        "config-memory-raised": "Der jrühzte zohjelasse Shpeisherbedarf vum PHP, et <code lang=\"en\">memory_limit</code>, shtund op $1 un es op $2 erop jesaz woode.",
        "config-memory-bad": "'''Opjepaß:''' Dem PHP singe Parameeter <code lang=\"en\">memory_limit</code> es $1.\nDat es wall ze winnisch.\nEt Enreeschte kunnt doh draan kappott jon!",
-       "config-apc": "Dä <code lang=\"en\">[http://www.php.net/apc APC]</code> es ennjeresht.",
-       "config-wincache": "Dä <code lang=\"en\">[https://www.iis.net/download/WinCacheForPhp WinCache]</code> es ennjeresht.",
-       "config-no-cache-apcu": "'''Opjepaß:''' Mer kunnte dä <code lang=\"en\" xml:lang=\"en\" dir=\"rtl\">[http://www.php.net/apcu APCu]</code>, dä <code lang=\"en\" xml:lang=\"en\" dir=\"rtl\">[http://xcache.lighttpd.net/ XCache]</code> udder dä <code lang=\"en\" xml:lang=\"en\" dir=\"rtl\">[http://www.iis.net/download/WinCacheForPhp WinCache]</code> nit fenge.\nEt <i lang=\"en\" xml:lang=\"en\" dir=\"rtl\">object caching</i> es nit müjjelesch un es ußjeschalldt.",
+       "config-apc": "Dä <code lang=\"en\">[https://secure.php.net/apc APC]</code> es ennjeresht.",
+       "config-wincache": "Dä <code lang=\"en\">[https://www.iis.net/downloads/microsoft/wincache-extension WinCache]</code> es ennjeresht.",
+       "config-no-cache-apcu": "'''Opjepaß:''' Mer kunnte dä <code lang=\"en\" xml:lang=\"en\" dir=\"rtl\">[https://secure.php.net/apcu APCu]</code>, dä <code lang=\"en\" xml:lang=\"en\" dir=\"rtl\">[http://xcache.lighttpd.net/ XCache]</code> udder dä <code lang=\"en\" xml:lang=\"en\" dir=\"rtl\">[https://www.iis.net/downloads/microsoft/wincache-extension WinCache]</code> nit fenge.\nEt <i lang=\"en\" xml:lang=\"en\" dir=\"rtl\">object caching</i> es nit müjjelesch un es ußjeschalldt.",
        "config-mod-security": "<strong>Opjepaß</strong>: Dinge Wäbßööver hät <code  lang=\"en\" xml:lang=\"en\" dir=\"ltr\">[https://modsecurity.org/ mod_security]</code> enjeschalldt. Jenohch schtandattmähßejje Enschtällonge heh em Wikki künne Problehme met MehdijaWikki un och met ander Projramme aanschtivvelle, di zohlohße, dat vun ußerhallef öhndsene Krohm op dä Webßööver jebraat wähde künnt.\nWann müjjelesch sullt mer dat affschallde. Söns beloor Der di Sigg <code  lang=\"en\" xml:lang=\"en\" dir=\"ltr\">[https://modsecurity.org/documentation/ mod_security documentation]</code> udder donn met dä Fachlück för Dinge Webßööver kalle, wann zohfälleje un koomijje Fähler bemärke deihß.",
        "config-diff3-bad": "Mer han <i lang=\"en\">GNU</i> <code lang=\"en\">diff3</code> nit jefonge.",
        "config-git": "Mer han de Väsjohn <code>$1</code> vun däm Väsjohnsverwalldongsprojamm <i lang=\"en\">Git</i> jefonge.",
        "config-type-oracle": "<i lang=\"en\">Oracle</i>",
        "config-type-mssql": "Dä <i lang=\"en\" xml:lang=\"en\">SQL</i>-ẞööver vun <i lang=\"en\" xml:lang=\"en\">Microsoft</i>",
        "config-support-info": "MediaWiki kann met heh dä Daatebangk_Süßteeme zosamme jonn:\n\n$1\n\nWann dat Daatebangk_Süßteem, wat De nämme wells, onge nit dobei es, dann donn desch aan di Aanleidonge hallde, di bovve verlengk sen, öm et op Dingem ẞööver singem Süßteem müjjelesh ze maache, se aan et Loufe ze krijje.",
-       "config-dbsupport-mysql": "* <i lang=\"en\" xml:lang=\"en\">[{{int:version-db-mysql-url}} MySQL]</i> es dat vum MediaWiki et eets un et bäß ongerschtöz Daatebangksüßtehm. Et leuf ävver och met <i lang=\"en\" xml:lang=\"en\">[{{int:version-db-mariadb-url}} MariaDB]</i> un <i lang=\"en\" xml:lang=\"en\">[{{int:version-db-percona-url}} Percona Server]</i>. Di sin kumpatihbel mem <i lang=\"en\" xml:lang=\"en\">MySQL</i>. ([http://www.php.net/manual/de/mysql.installation.php Aanleidung för et Övversäze un Enreeschte von <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"PHP Hypertext Preprocessor\">PHP</i> met <i lang=\"en\">MySQL</i> dobei, op Deutsch])",
-       "config-dbsupport-postgres": "* <i lang=\"en\">[{{int:version-db-postgres-url}} PostgreSQL]</i> es e bikannt Daatebangksüßtehm met offe Quälltäxde, un ed es och en Wahl nävve <i lang=\"en\">MySQL</i>. Et sinn_er ävver paa klein Fählersche bekannt, um mer künne et em Momang för et reschtijje Werke nit ämfähle. ([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])",
+       "config-dbsupport-mysql": "* <i lang=\"en\" xml:lang=\"en\">[{{int:version-db-mysql-url}} MySQL]</i> es dat vum MediaWiki et eets un et bäß ongerschtöz Daatebangksüßtehm. Et leuf ävver och met <i lang=\"en\" xml:lang=\"en\">[{{int:version-db-mariadb-url}} MariaDB]</i> un <i lang=\"en\" xml:lang=\"en\">[{{int:version-db-percona-url}} Percona Server]</i>. Di sin kumpatihbel mem <i lang=\"en\" xml:lang=\"en\">MySQL</i>. ([https://secure.php.net/manual/de/mysql.installation.php Aanleidung för et Övversäze un Enreeschte von <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"PHP Hypertext Preprocessor\">PHP</i> met <i lang=\"en\">MySQL</i> dobei, op Deutsch])",
+       "config-dbsupport-postgres": "* <i lang=\"en\">[{{int:version-db-postgres-url}} PostgreSQL]</i> es e bikannt Daatebangksüßtehm met offe Quälltäxde, un ed es och en Wahl nävve <i lang=\"en\">MySQL</i>. Et sinn_er ävver paa klein Fählersche bekannt, um mer künne et em Momang för et reschtijje Werke nit ämfähle. ([https://secure.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])",
        "config-dbsupport-sqlite": "* <i lang=\"en\">[{{int:version-db-sqlite-url}} SQLite]</i> es e eijfach Daatebangksüßtehm, wat joot en Schoß jehallde 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-dbsupport-oracle": "* <i lang=\"en\">[{{int:version-db-oracle-url}} Oracle]</i> es e jeschäfflesch Daatebangksüßtehm 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\" xml:lang=\"en\">OCI8</i> dobei, op Deutsch])",
-       "config-dbsupport-mssql": "* Dä <i lang=\"en\" xml:lang=\"en\">[{{int:version-db-mssql-url}} Microsoft SQL Server]</i> es e jeschäfflesch Dahtebangksüßtehm för Rääschner met <i lang=\"en\" xml:lang=\"en\">Windows</i>. ([http://www.php.net/manual/de/sqlsrv.installation.php Aanleidong för et Övversäze un Enreeschte von <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"PHP Hypertext Preprocessor\">PHP</i> met <i lang=\"en\" xml:lang=\"en\">SQLSRV </i> dobei, op Deutsch])",
+       "config-dbsupport-mssql": "* Dä <i lang=\"en\" xml:lang=\"en\">[{{int:version-db-mssql-url}} Microsoft SQL Server]</i> es e jeschäfflesch Dahtebangksüßtehm för Rääschner met <i lang=\"en\" xml:lang=\"en\">Windows</i>. ([https://secure.php.net/manual/en/sqlsrv.installation.php Aanleidong för et Övversäze un Enreeschte von <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"PHP Hypertext Preprocessor\">PHP</i> met <i lang=\"en\" xml:lang=\"en\">SQLSRV </i> dobei, op Deutsch])",
        "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",
        "config-license-help": "Ättlijje öffentleje Wikis donn iehr Beidrääsch onger en [https://freedomdefined.org/Definition freije Lizänz] schtelle.\nDat hellef, e Jeföhl vun Jemeinsamkeid opzeboue, un op lange Seesch emmer wider Beidrääsch ze krijje.\nDat es nit onbedengk nüüdesh för e Jeschäffs- udder Privaat_Wiki.\n\nWä Stöcke uß de Wikipedia bruche well, un dröm han well, dat mer för Wikipedia uss_em eije Wiki jät övvernämme kann, sullt „'''<i lang=\"en\">Creative Commons</i>, dem Schriever singe Name moß jenannt wääde, un Wiggerjävve zoh dersellve Bedengunge es zohjelohße'''“ ußwähle.\n\nDe su jenannte '''<i lang=\"en\">GNU Free Documentation License</i>''' (de freije Lizänz för Dokemäntazjuhne vun dä GNU) sen de ahle Lizänzbedenonge vun de Wikipedia. Se es emmer noch in Odenong un jöltesch, ävver se es schwer ze verschtonn un et Wiggerjävve un widder Bruche es ens schwieerejer domet.",
        "config-email-settings": "Enschtellunge för de <i lang=\"en\">e-mail</i>",
        "config-enable-email": "De <i lang=\"en\">e-mail</i> noh druße zohlohße",
-       "config-enable-email-help": "Sulle \n<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mails</i> zohjelohße sin, moß mer, domet et noher flupp, dä Datteij <code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">[http://www.php.net/manual/en/mail.configuration.php</code> Enschtällonge em PHP för de <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i>] zopaß jemaat han.\nWann kein <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mails</i> nüüdesch sin, kam_mer se heh afschallde.",
+       "config-enable-email-help": "Sulle \n<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mails</i> zohjelohße sin, moß mer, domet et noher flupp, dä Datteij <code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">[Config-dbsupport-oracle/manual/en/mail.configuration.php</code> Enschtällonge em PHP för de <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i>] zopaß jemaat han.\nWann kein <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mails</i> nüüdesch sin, kam_mer se heh afschallde.",
        "config-email-user": "<i lang=\"en\">e-mails</i> zwesche de Metmaacher zohlohße",
        "config-email-user-help": "Määt et müjjelesch, dat sesch de Metmaacher jääjesiggesch \n<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mails</i> scheke künne, wann se dat en iehre eije Enschtällonge och enjeschalldt han.",
        "config-email-usertalk": "<i lang=\"en\">e-mails</i> mem Bescheid zohlohße, dat einem sing Klaafsigg verändert woodt",
index 6d40a10..ea8c6a6 100644 (file)
@@ -26,8 +26,8 @@
        "config-page-upgradedoc": "Bilindkirin",
        "config-page-existingwiki": "Wîkiya heye",
        "config-restart": "Erê, jinûve bide destpêkirin",
-       "config-apc": "[http://www.php.net/apc APC] hate avakirin",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] hate avakirin",
+       "config-apc": "[https://secure.php.net/apc APC] hate avakirin",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] hate avakirin",
        "config-diff3-bad": "GNU diff3 nehate dîtin.",
        "config-db-type": "Cureya danegehê:",
        "config-db-wiki-settings": "Vî wîkîyê bide danasîn",
index cc42c42..92adf7b 100644 (file)
@@ -49,9 +49,9 @@
        "config-no-db": "Et konnt kee passenden Datebank-Driver fonnt ginn! Dir musst een Datebank-Driver fir PHP installéieren.\n{{PLURAL:$2|Dësn Datebank-Typ gëtt|Dës Datebank-Type ginn}} ënnerstëtzt: $1.\n\nWann Dir PHP selwer compiléiert hutt, da rekonfiguréiert en mat dem ageschalten Datebank-Client, zum Beispill an deem Dir <code>./configure --with-mysqli</code> benotzt.\nWann Dir PHP vun engem Debian oder Ubuntu Package aus installéiert hutt, da musst Dir och den php5-mysql Modul installéieren.",
        "config-outdated-sqlite": "'''Warnung:''' SQLite $1 ass installéiert. Allerdengs brauch MediaWiki SQLite $2 oder méi nei. SQLite ass dofir net disponibel.",
        "config-memory-bad": "'''Opgepasst:''' De Parameter <code>memory_limit</code> vu PHP ass $1.\nDat ass wahrscheinlech ze niddreg.\nD'Installatioun kéint net funktionéieren.",
-       "config-apc": "[http://www.php.net/apc APC] ass installéiert",
-       "config-apcu": "[http://www.php.net/apcu APCu] ass installéiert.",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] ass installéiert",
+       "config-apc": "[https://secure.php.net/apc APC] ass installéiert",
+       "config-apcu": "[https://secure.php.net/apcu APCu] ass installéiert.",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] ass installéiert",
        "config-diff3-bad": "GNU diff3 gouf net fonnt.",
        "config-git": "D'Software Git fir d'Kontroll vu Versioune gouf fonnt: <code>$1</code>.",
        "config-git-bad": "D'Software fir d'Kontroll vun de Versiounen 'Git' gouf net fonnt.",
@@ -84,9 +84,9 @@
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] ass e beléiften Open-Source-Datebanksystem an eng Alternativ zu MySQL. ([http://www.php.net/manual/de/pgsql.installation.php Uleedung fir d'Kompilatoun vu PHP mat PostgreSQL-Ënnerstëtzung])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] ass e beléiften Open-Source-Datebanksystem an eng Alternativ zu MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Uleedung fir d'Kompilatoun vu PHP mat PostgreSQL-Ënnerstëtzung])",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] ass eng kommerziell Datebank-Software. ([http://www.php.net/manual/en/oci8.installation.php How to compile PHP mat OCI8 Ënnerstëtzung])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ass eng kommerziell Datebank-Software fir Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Wéi PHP mat SQLSRV Ënnerstëtzung kompiléieren])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ass eng kommerziell Datebank-Software fir Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Wéi PHP mat SQLSRV Ënnerstëtzung kompiléieren])",
        "config-header-mysql": "MySQL-Astellungen",
        "config-header-postgres": "PostgreSQL-Astellungen",
        "config-header-sqlite": "SQLite-Astellungen",
index 7a7ed57..130dbda 100644 (file)
        "config-pcre-no-utf8": "'''Fatale''': o modulo PCRE de PHP pâ ch'o segge stæto compilou sença o supporto PCRE_UTF8. A MediaWiki a-o richiede pe fonçionâ corettamente.",
        "config-memory-raised": "O valô <code>memory_limit</code> de PHP o l'è $1, aomentou a $2.",
        "config-memory-bad": "''Atençion:''' O valô de <code>memory_limit</code> do PHP o l'è $1.\nFoscia o l'è troppo basso.\nL'installaçion a porriæ fallî!",
-       "config-apc": "[http://www.php.net/apc APC] o l'è installou",
-       "config-apcu": "[http://www.php.net/apc APC] o l'è installou",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] o l'è installou",
-       "config-no-cache-apcu": "'''Atençion:''' [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] ò [http://www.iis.net/download/WinCacheForPhp WinCache] no son stæti trovæ.\nA caching di ogetti a no l'è attivâ.",
+       "config-apc": "[https://secure.php.net/apc APC] o l'è installou",
+       "config-apcu": "[https://secure.php.net/apc APC] o l'è installou",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] o l'è installou",
+       "config-no-cache-apcu": "'''Atençion:''' [https://secure.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] ò [https://www.iis.net/downloads/microsoft/wincache-extension WinCache] no son stæti trovæ.\nA caching di ogetti a no l'è attivâ.",
        "config-mod-security": "<strong>Atençion:</strong> O to serviou web o g'ha o [https://modsecurity.org/ mod_security] abilitou. Gh'è tante configuaçioin che crean di problemi a-a MediaWiki ò a atro software ch'o permette a-i utenti de pubbricâ quâ-se-segge contegnuo. Se poscibbile o doviæ ese disabilitou.\nFanni rifeimento a-a [https://modsecurity.org/documentation/ documentaçion insce-o mod_security] ò contatta o supporto tecnico do to provider de hosting se se veifica di erroî.",
        "config-diff3-bad": "GNU diff3 non trovou.",
        "config-git": "Trovou software de controllo da verscion Git: <code>$1</code>.",
        "config-type-mysql": "MySQL (ò compatibbile)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki o supporta i seguenti scistemi de database:\n\n$1\n\nSe fra quelli elencæ chì de sotta no ti veddi o scistema de database che ti voriesci doeuviâ, segui e instruçioin inganciæ de d'ato pe abilitâ o supporto.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] a l'è a primma scelta pe MediaWiki e a l'è quella megio suportâ. MediaWiki a fonçion-a ascì con [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], che son compatibbili con MySQL.([http://www.php.net/manual/en/mysqli.installation.php Comme compilâ PHP con suporto MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] o l'è un popolare scistema de database open source comme alternativa a MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Comme compilâ PHP con suporto PostgreSQL])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] a l'è a primma scelta pe MediaWiki e a l'è quella megio suportâ. MediaWiki a fonçion-a ascì con [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], che son compatibbili con MySQL.([https://secure.php.net/manual/en/mysqli.installation.php Comme compilâ PHP con suporto MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] o l'è un popolare scistema de database open source comme alternativa a MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Comme compilâ PHP con suporto PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] o l'è un scistema de database leggio, ch'o l'è suportou molto ben. ([http://www.php.net/manual/en/pdo.installation.php Comme compilâ PHP con suporto SQLite], o l'utilizza PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] o l'è un database de un'impreiza comerciâ. ([http://www.php.net/manual/en/oci8.installation.php Comme compilâ PHP con suporto OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] o l'è un database de un'impreiza commerciâ per Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Comme compilâ PHP con supporto SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] o l'è un database de un'impreiza commerciâ per Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Comme compilâ PHP con supporto SQLSRV])",
        "config-header-mysql": "Impostaçioin MySQL",
        "config-header-postgres": "Impostaçioin PostgreSQL",
        "config-header-sqlite": "Impostaçioin SQLite",
        "config-license-help": "Tante wiki pubbriche rilascian i so contributi co-ina [https://freedomdefined.org/Definition liçençia libbera]. Sto fæto o l'agiutta a creâ un senso de propietæ condivisa inta comunitæ e o l'incoragisce a contriboî a longo termine. O no l'è generalmente necessaio pe 'na wiki privâ ò aziendale.\n\nSe ti voeu doeuviâ di scriti da Wikipedia, ò ti dexiddei che a Wikipedia a posse vese in graddo de acetâ di scriti copiæ da-a to wiki, ti doviesci scellie <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nIn precedença a Wikipedia a l'ha doeuviou a GNU Free Documentation License. A GFDL a l'è 'na liçençia vallida, ma a l'è difiççile da capî e a complica o riutilizzo di contegnui.",
        "config-email-settings": "Impostaçioin e-mail",
        "config-enable-email": "Abillita a sciortia da posta elettronica",
-       "config-enable-email-help": "Se ti voeu che fonçion-e l'e-mail, e [http://www.php.net/manual/en/mail.configuration.php PHP's impostaçioin della posta] dev'esan configuæ corettamente.\nSe non ti dexiddei arcun-a fonçionalitæ de posta eletronnica, ti a poeu disabilitâ chie.",
+       "config-enable-email-help": "Se ti voeu che fonçion-e l'e-mail, e [Config-dbsupport-oracle/manual/en/mail.configuration.php PHP's impostaçioin della posta] dev'esan configuæ corettamente.\nSe non ti dexiddei arcun-a fonçionalitæ de posta eletronnica, ti a poeu disabilitâ chie.",
        "config-email-user": "Abillita e-mail fra utenti",
        "config-email-user-help": "Consente a tutti i utenti de inviâse l'un l'atro l'e-mail, se l'han abilitou inte so preferençe.",
        "config-email-usertalk": "Abillita e notiffiche pe-e paggine de discuscion utente",
index 4506139..5268510 100644 (file)
@@ -5,7 +5,8 @@
                        "Mantak111",
                        "Zygimantus",
                        "Hugo.arg",
-                       "Homo"
+                       "Homo",
+                       "Manvydasz"
                ]
        },
        "config-desc": "MediaWiki diegimas",
        "config-env-hhvm": "HHVM $1 yra įdiegtas.",
        "config-outdated-sqlite": "<strong>Įspėjimas:</strong> jūs turite SQLite $1, kuri yra mažesnė nei minimali reikalinga versija $2. SQLite nebus prieinama.",
        "config-memory-raised": "PHP <code>memory_limit</code> yra $1, padidintas iki $2.",
-       "config-apc": "[http://www.php.net/apc APC] yra įdiegtas",
-       "config-apcu": "[http://www.php.net/apcu APCu] yra įdiegtas",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] yra įdiegtas",
-       "config-no-cache-apcu": "<strong>Įspėjimas:</strong> Nepavyko rasti [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] or [http://www.iis.net/download/WinCacheForPhp WinCache].\nObjekto spartinimas neįjungtas.",
+       "config-apc": "[https://secure.php.net/apc APC] yra įdiegtas",
+       "config-apcu": "[https://secure.php.net/apcu APCu] yra įdiegtas",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] yra įdiegtas",
+       "config-no-cache-apcu": "<strong>Įspėjimas:</strong> Nepavyko rasti [https://secure.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] ar [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nObjekto spartinimas neįjungtas.",
        "config-diff3-bad": "GNU diff3 nerastas.",
        "config-git": "Rasta Git versijų kontrolės sistema: <code>$1</code>.",
        "config-imagemagick": "Rastas „ImageMagick“: <code>$1</code>.\nPaveikslėlių miniatiūrizavimas bus įjungtas, jeigu įgalinsite vaizdų įkėlimą.",
index 671d073..ccf733e 100644 (file)
@@ -27,7 +27,7 @@
        "config-restart": "Jā, restartēt",
        "config-env-php": "PHP $1 ir uzstādīts.",
        "config-env-hhvm": "HHVM $1 ir uzstādīts.",
-       "config-apcu": "[http://www.php.net/apcu APCu] ir uzstādīts",
+       "config-apcu": "[https://secure.php.net/apcu APCu] ir uzstādīts",
        "config-diff3-bad": "GNU diff3 nav atrasts.",
        "config-db-host-oracle": "Datubāzes TNS:",
        "config-db-name": "Datubāzes nosaukums:",
index 4598aa9..829a543 100644 (file)
        "config-pcre-no-utf8": "<strong>Кобно</strong>: PCRE-модулот на PHP е срочен без поддршка за PCRE_UTF8.\nМедијаВики бара поддршка за UTF-8 за да може да работи правилно.",
        "config-memory-raised": "<code>memory_limit</code> за PHP изнесува $1, зголемен на $2.",
        "config-memory-bad": "<strong>Предупредување:</strong> <code>memory_limit</code> за PHP изнесува $1.\nОва е веројатно премалку.\nВоспоставката може да не успее!",
-       "config-apc": "[http://www.php.net/apc APC] е воспоставен",
-       "config-apcu": "[http://www.php.net/apcu APCu] е воспоставен",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] е воспоставен",
-       "config-no-cache-apcu": "<strong>Предупредување:</strong> Не можев да го најдам [http://www.php.net/apcu APCu] или [http://www.iis.net/download/WinCacheForPhp WinCache].",
+       "config-apc": "[https://secure.php.net/apc APC] е воспоставен",
+       "config-apcu": "[https://secure.php.net/apcu APCu] е воспоставен",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] е воспоставен",
+       "config-no-cache-apcu": "<strong>Предупредување:</strong> Не можев да го најдам [https://secure.php.net/apcu APCu] или [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].",
        "config-mod-security": "'''Предупредување''': на вашиот опслужувач има овозможено [https://modsecurity.org/ mod_security]. Ако не е поставено како што треба, ова може да предизвика проблеми кај МедијаВики и други програми што им овозможуваат на корисниците да објавуваат произволни содржини.\nПогледнете ја [https://modsecurity.org/documentation/ mod_security документацијата] или обратете се кај домаќинот ако наидете на случајни грешки.",
        "config-diff3-bad": "GNU diff3 не е пронајден.",
        "config-git": "Го пронајдов Git програмот за контрола на верзии: <code>$1</code>.",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "МедијаВики ги поддржува следниве системи на бази на податоци:\n\n$1\n\nАко системот што сакате да го користите не е наведен подолу, тогаш проследете ја горенаведената врска со инструкции за да овозможите поддршка за тој систем.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] е главната цел на МедијаВики и најдобро е поддржан. МедијаВики работи и со [{{int:version-db-mariadb-url}} MariaDB] и [{{int:version-db-percona-url}} Percona], кои се складни со MySQL. ([http://www.php.net/manual/en/mysqli.installation.php Како да срочите PHP со поддршка за MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] е популарен систем на бази на податоци со отворен код кој претставува алтернатива на MySQL ([http://www.php.net/manual/en/pgsql.installation.php како да составите PHP со поддршка за PostgreSQL]). ([http://www.php.net/manual/en/pgsql.installation.php Како да срочите PHP со поддршка за PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] е лесен систем за бази на податоци кој е многу добро поддржан. ([http://www.php.net/manual/en/pdo.installation.php Како да составите PHP со поддршка за SQLite], користи PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] е база на податоци на комерцијално претпријатие. ([http://www.php.net/manual/en/oci8.installation.php Како да составите PHP со поддршка за OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]  е база на податоци на комерцијално претпријатиe за Windows ([http://www.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV поддршка])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] е главната цел на МедијаВики и најдобро е поддржан. МедијаВики работи и со [{{int:version-db-mariadb-url}} MariaDB] и [{{int:version-db-percona-url}} Percona], кои се складни со MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Како да срочите PHP со поддршка за MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] е популарен систем на бази на податоци со отворен код кој претставува алтернатива на MySQL ([https://secure.php.net/manual/en/pgsql.installation.php како да составите PHP со поддршка за PostgreSQL]). ([https://secure.php.net/manual/en/pgsql.installation.php Како да срочите PHP со поддршка за PostgreSQL])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] е лесен систем за бази на податоци кој е многу добро поддржан. ([https://secure.php.net/manual/en/pdo.installation.php Како да составите PHP со поддршка за SQLite], користи PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] е база на податоци на комерцијално претпријатие. ([https://secure.php.net/manual/en/oci8.installation.php Како да составите PHP со поддршка за OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]  е база на податоци на комерцијално претпријатиe за Windows ([https://secure.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV поддршка])",
        "config-header-mysql": "Нагодувања на MySQL",
        "config-header-postgres": "Нагодувања на PostgreSQL",
        "config-header-sqlite": "Нагодувања на SQLite",
        "config-license-help": "Многу јавни викија ги ставаат сите придонеси под [https://freedomdefined.org/Definition слободна лиценца].\nСо ова се создава атмосфера на општа сопственост и поттикнува долгорочно учество.\nОва не е неопходно за викија на поединечни физички или правни лица.\n\nАко сакате да користите текст од Википедија, и сакате Википедија да прифаќа текст прекопиран од вашето вики, тогаш треба да ја одберете лиценцата <strong>{{int:config-license-cc-by-sa}}</strong>..\n\nГНУ-овата лиценца за слободна документација (ГЛСД) е старата лиценца на Википедија.\nОваа лиценца сè уште важи, но е тешка за разбирање.\nИсто така треба да се има на ум дека пренамената на содржините под ГЛСД не е лесна.",
        "config-email-settings": "Нагодувања за е-пошта",
        "config-enable-email": "Овозможи излезна е-пошта",
-       "config-enable-email-help": "Ако сакате да работи е-поштата, [http://www.php.net/manual/en/mail.configuration.php поштенските нагодувања на PHP] треба да се правилно наместени.\nАко воопшто не сакате никакви функции за е-пошта, тогаш можете да ги оневозможите тука.",
+       "config-enable-email-help": "Ако сакате да работи е-поштата, [Config-dbsupport-oracle/manual/en/mail.configuration.php поштенските нагодувања на PHP] треба да се правилно наместени.\nАко воопшто не сакате никакви функции за е-пошта, тогаш можете да ги оневозможите тука.",
        "config-email-user": "Овозможи е-пошта од корисник до корисник",
        "config-email-user-help": "Дозволи сите корисници да можат да си праќаат е-пошта ако ја имаат овозможено во нагодувањата.",
        "config-email-usertalk": "Овозможи известувања за промени во кориснички страници за разговор",
index 4f158f9..79fd490 100644 (file)
@@ -91,7 +91,7 @@
        "config-license-cc-by-nc-sa": "ക്രിയേറ്റീവ് കോമൺസ് ആട്രിബ്യൂഷൻ നോൺ-കൊമേഴ്സ്യൽ ഷെയർ എലൈക്",
        "config-license-pd": "പൊതുസഞ്ചയം",
        "config-email-settings": "ഇമെയിൽ സജ്ജീകരണങ്ങൾ",
-       "config-enable-email-help": "ഇമെയിൽ പ്രവർത്തിക്കണമെങ്കിൽ, [http://www.php.net/manual/en/mail.configuration.php PHP's മെയിൽ സജ്ജീകരണങ്ങൾ] ശരിയായി ക്രമീകരിക്കേണ്ടതുണ്ട്.\nഇമെയിൽ സൗകര്യം ആവശ്യമില്ലെങ്കിൽ, ഇവിടെത്തന്നെ അത് നിർജ്ജീവമാക്കാം.",
+       "config-enable-email-help": "ഇമെയിൽ പ്രവർത്തിക്കണമെങ്കിൽ, [Config-dbsupport-oracle/manual/en/mail.configuration.php PHP's മെയിൽ സജ്ജീകരണങ്ങൾ] ശരിയായി ക്രമീകരിക്കേണ്ടതുണ്ട്.\nഇമെയിൽ സൗകര്യം ആവശ്യമില്ലെങ്കിൽ, ഇവിടെത്തന്നെ അത് നിർജ്ജീവമാക്കാം.",
        "config-email-user": "ഉപയോക്താക്കൾ തമ്മിലുള്ള ഇമെയിൽ പ്രവർത്തനസജ്ജമാക്കുക",
        "config-email-user-help": "സ്വന്തം ക്രമീകരണങ്ങളിൽ ഇമെയിൽ സജ്ജമാക്കിയിട്ടുണ്ടെങ്കിൽ ഉപയോക്താക്കളെ മറ്റുള്ളവർക്ക് ഇമെയിൽ അയയ്ക്കാൻ അനുവദിക്കുക.",
        "config-email-usertalk": "ഉപയോക്തൃസംവാദം താളിൽ മാറ്റങ്ങളുണ്ടായാൽ അറിയിക്കുക",
index 8e7cbee..c00382d 100644 (file)
@@ -52,8 +52,8 @@
        "config-outdated-sqlite": "<strong>इशारा:</strong> आपणापाशी SQLite $1 आहे, जी किमान आवश्यक आवृत्ती $2 पेक्षा, निम्न आहे. SQLite अनुपलब्ध राहील.",
        "config-memory-raised": "पीएचपीची <code>memory_limit</code> ही $1 आहे, त्यास $2 ला वाढविली.",
        "config-memory-bad": "पीएचपीची <code>memory_limit</code> ही $1 आहे.\nही बरीच खालच्या स्तरावरची आहे.\nउभारणी अयशस्वी होऊ शकते!",
-       "config-apc": "[http://www.php.net/apc APC] उभारली आहे",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] उभारली आहे",
+       "config-apc": "[https://secure.php.net/apc APC] उभारली आहे",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] उभारली आहे",
        "config-diff3-bad": "GNU diff3 सापडली नाही.",
        "config-git-bad": "गीट आवृत्ती नियमन संचेतन सापडली नाही.",
        "config-db-type": "डाटाबेसचा प्रकार:",
index c848c42..41e678c 100644 (file)
@@ -58,8 +58,8 @@
        "config-no-fts3": "<strong>Amaran:</strong> SQLite disusun tanpa [//sqlite.org/fts3.html modil FTS3], maka ciri-ciri pencarian tidak akan disediakan pada backend ini.",
        "config-pcre-old": "<strong>Amaran keras:</strong> PCRE $1 ke atas diperlukan.\nBinari PHP anda berpaut dengan PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Keterangan lanjut].",
        "config-memory-bad": "<strong>Amaran:</strong> <code>memory_limit</code> (Had memori) PHP ialah $1.\nIni mungkin terlalu rendah.\nPemasangan mungkin akan gagal!",
-       "config-apc": "[http://www.php.net/apc APC] dipasang",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] dipasang",
+       "config-apc": "[https://secure.php.net/apc APC] dipasang",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] dipasang",
        "config-mod-security": "<strong>Amaran:</strong> Pelayan web anda dihidupkan [https://modsecurity.org/ mod_security]/mod_security2. Kebanyakan konfigurasinya yang umum boleh menimbulkan kesulitan untuk MediaWiki dan perisian-perisian lain yang membolehkan pengguna untuk mengeposkan kandungan yang sewenang-wenang.\nJika boleh, ciri-ciri ini harus dimatikan. Jika tidak, rujuki [https://modsecurity.org/documentation/ dokumentasi mod_security] atau hubungi bantuan hos anda jika anda menghadapi ralat sembarangan.",
        "config-diff3-bad": "GNU diff3 tidak dijumpai.",
        "config-git": "Perisian kawalan versi Git dijumpai: <code>$1</code>.",
index 1763fcd..f7cc024 100644 (file)
@@ -31,9 +31,9 @@
        "config-env-hhvm": "اچ‌اچ‌وی‌ام $1 نصب بیه.",
        "config-unicode-using-intl": "عادی یونیکد وسه [https://pecl.php.net/intl افزونهٔ intl برای PECL] جه استفاده هاکن.",
        "config-memory-raised": "PHP's <code>memory_limit</code>, نسخهٔ $1 هسته، ونه نسخهٔ $2 ره بَیری آپگریت هاکنی.",
-       "config-apc": "[http://www.php.net/apc APC] نصب بیه.",
-       "config-apcu": "[http://www.php.net/apcu APCu] نصب بیه.",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] نصب بیه.",
+       "config-apc": "[https://secure.php.net/apc APC] نصب بیه.",
+       "config-apcu": "[https://secure.php.net/apcu APCu] نصب بیه.",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] نصب بیه.",
        "config-diff3-bad": "GNU diff3 پیدا نیه.",
        "config-mysql-binary": "باینری",
        "config-mysql-utf8": "UTF-8",
index fa41257..5cacc89 100644 (file)
@@ -59,9 +59,9 @@
        "config-pcre-no-utf8": "<strong>Fatale:</strong> 'E module PCRE d' 'o PHP pare ca se so' compilate senza PCRE_UTF8 supporto.\nA MediaWiki serve nu supporto UTF-8 pe' putè funziunà apposto.",
        "config-memory-raised": "'O valore 'e PHP <code>memory_limit</code> è $1, aumentato a $2.",
        "config-memory-bad": "<strong>Attenziò:</strong> 'o valore 'e PHP <code>memory_limit</code> è $1.\nProbabbilmente troppo basso.\n'A installazione se putesse scassà!",
-       "config-apc": "[http://www.php.net/apc APC] è installato",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] è installato",
-       "config-no-cache-apcu": "<strong>Attenziò:</strong> [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] o [http://www.iis.net/download/WinCacheForPhp WinCache] nun so' state truvate.\n'A funziona caching 'e ll'oggette non è apicciata.",
+       "config-apc": "[https://secure.php.net/apc APC] è installato",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] è installato",
+       "config-no-cache-apcu": "<strong>Attenziò:</strong> [https://secure.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] o [https://www.iis.net/downloads/microsoft/wincache-extension WinCache] nun so' state truvate.\n'A funziona caching 'e ll'oggette non è apicciata.",
        "config-mod-security": "<strong>Attenziò:</strong> 'O servitore web vuosto téne [https://modsecurity.org/ mod_security]/mod_security2 appicciato. Ce stanno tante mpustaziune commune ca 'o facessero causà prubbleme a MediaWiki e ll'ati software ca permettessero ll'utente 'e pubbrecà cuntenute.\nSi putite, stutate sta funziona. Sinò, riferite 'a [https://modsecurity.org/documentation/ documentaziona ncopp' 'o mod_security] o cuntattate 'o host vuosto pe' ve dà supporto quanno se scummogliasse cocch'errore.",
        "config-diff3-bad": "GNU diff3 nun truvato.",
        "config-git": "Truvato software 'e cuntrollo d' 'a verziona Git: <code>$1</code>.",
        "config-type-mysql": "MySQL (o compatibbele)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki supporta 'e sisteme 'e database ccà abbascio:\n\n$1\n\nSi nfra chiste ccà nun vedite 'o sistema 'e database ca vulite ausà, allora avite liegge 'e instruziune ccà ncoppa pe' ne dà supporto.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] è 'a configurazione cchiù mmeglio p' 'o MediaWiki e è chilla meglio suppurtata. MediaWiki può faticà pure cu' [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], ca fossero MySQL cumpatibbele. ([http://www.php.net/manual/en/mysqli.installation.php Comme s'adda fà pe' cumpilà PHP cu suppuorto MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] è nu sistema canusciuto 'e database open source ca fosse n'alternativa a MySQL. Putess'avé cocch'errore p'arricettà, e nun è cunzigliato 'e ll'ausà dint'a n'ambiente 'e produziona. ([http://www.php.net/manual/en/pgsql.installation.php Comme s'avess'a cumpilà PHP cu suppuorto PostgreSQL])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] è 'a configurazione cchiù mmeglio p' 'o MediaWiki e è chilla meglio suppurtata. MediaWiki può faticà pure cu' [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], ca fossero MySQL cumpatibbele. ([https://secure.php.net/manual/en/mysqli.installation.php Comme s'adda fà pe' cumpilà PHP cu suppuorto MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] è nu sistema canusciuto 'e database open source ca fosse n'alternativa a MySQL. Putess'avé cocch'errore p'arricettà, e nun è cunzigliato 'e ll'ausà dint'a n'ambiente 'e produziona. ([https://secure.php.net/manual/en/pgsql.installation.php Comme s'avess'a cumpilà PHP cu suppuorto PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]  è nu sistema 'e database leggero, ca fosse assaje buono suppurtato. ([http://www.php.net/manual/en/pdo.installation.php Comme cumpilà PHP cu suppuorto SQLite], aùsa PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] è nu database 'e na fraveca commerciale. ([http://www.php.net/manual/en/oci8.installation.php Comme cumpilà PHP cu suppuorto OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] è nu database 'e na fraveca commerciale p' 'o Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Comme cumpilà PHP cu suppuorto SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] è nu database 'e na fraveca commerciale p' 'o Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Comme cumpilà PHP cu suppuorto SQLSRV])",
        "config-header-mysql": "Mpustaziune MySQL",
        "config-header-postgres": "Mpustaziune PostgreSQL",
        "config-header-sqlite": "Mpustaziune SQLite",
        "config-license-help": "Nu cuofeno 'e wiki pubbrece lassano 'e cuntribbute lloro cu na [https://freedomdefined.org/Definition licienza libbera]. Chesto aiutasse a crià nu senso 'e pruprietà spartuta dint'a communità e ncuraggiasse a cuntribbuiì a nu tèrmene luongo. Nun è generalmente necessario pe' nu wiki privato o aziendale.\n\nSi vulite ausà testi 'a Wikipedia, o vulite ca Wikipedia se pozza miette 'n grado d'accettà teste cupiate d' 'o wiki vuosto, avissev'a scegiere <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nApprimma Wikipedia aveva ausato 'a GNU Free Documentation License. 'A GFDL è una licienza valida, ma è di difficile comprensiona e complica 'o riutilizzo 'e cuntenute.",
        "config-email-settings": "Mpustaziune email",
        "config-enable-email": "Premmette mmasciate elettroniche r'asciuta",
-       "config-enable-email-help": "Si vulite ca 'o sistema 'e mmasciate mail funziunasse, [http://www.php.net/manual/en/mail.configuration.php 'e mpustaziune PHP] s'avesser'a ffà bbuone.\nSi nun vulite 'a funziona mmasciata e-mail, allora stutate chiste llàn.",
+       "config-enable-email-help": "Si vulite ca 'o sistema 'e mmasciate mail funziunasse, [Config-dbsupport-oracle/manual/en/mail.configuration.php 'e mpustaziune PHP] s'avesser'a ffà bbuone.\nSi nun vulite 'a funziona mmasciata e-mail, allora stutate chiste llàn.",
        "config-email-user": "Premmette email utente-utente",
        "config-email-user-help": "Cunzente a ll'utente 'e mannà uno a ll'ato le mail si 'e teneno appicciate dint' 'e preferenze lloro.",
        "config-email-usertalk": "Premmette notifiche p' 'e paggene 'e chiacchiera utente",
index c00cf18..479c3f5 100644 (file)
        "config-pcre-no-utf8": "'''Fatal''': PHPs PCRE modul ser ut til å være kompilert uten PCRE_UTF8-støtte.\nMediaWiki krever UTF-8-støtte for å fungere riktig.",
        "config-memory-raised": "PHPs <code>memory_limit</code> er $1, økt til $2.",
        "config-memory-bad": "'''Advarsel:''' PHPs <code>memory_limit</code> er $1.\nDette er sannsynligvis for lavt.\nInstallasjonen kan mislykkes!",
-       "config-apc": "[http://www.php.net/apc APC] er installert",
-       "config-apcu": "[http://www.php.net/apcu APCu] er installert",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] er installert",
-       "config-no-cache-apcu": "<strong>Advarsel:</strong> Kunne ikke finne [http://www.php.net/apcu APCu] eller [http://www.iis.net/download/WinCacheForPhp WinCache].\nObjekthurtiglagring er ikke aktivert.",
+       "config-apc": "[https://secure.php.net/apc APC] er installert",
+       "config-apcu": "[https://secure.php.net/apcu APCu] er installert",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] er installert",
+       "config-no-cache-apcu": "<strong>Advarsel:</strong> Kunne ikke finne [https://secure.php.net/apcu APCu] eller [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nObjekthurtiglagring er ikke aktivert.",
        "config-mod-security": "'''Advarsel''': Din web-tjener har [https://modsecurity.org/ mod_security] påslått. Hvis denne er feilinnstilt, kan det gi problemer for MediaWiki eller annen programvare som tillater brukere å poste vilkårlig innhold.\nSjekk [https://modsecurity.org/documentation/ mod_security-dokumentasjonen] eller ta kontakt med din nettleverandør hvis du opplever tilfeldige feil.",
        "config-diff3-bad": "GNU diff3 ikke funnet.",
        "config-git": "Har funnet Git version control software: <code>$1</code>.",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQLServer",
        "config-support-info": "MediaWiki støtter følgende databasesystem:\n\n$1\n\nHvis du ikke ser databasesystemet du prøver å bruke i listen nedenfor, følg instruksjonene det er lenket til over for å aktivere støtte.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] er den prefererte databasen for MediaWiki og er derfor best støttet.  MediaWiki fungerer også med [{{int:version-db-mariadb-url}} MariaDB] og [{{int:version-db-percona-url}} Percona Server], som begge er MySQL-kompatible. ([http://www.php.net/manual/en/mysqli.installation.php Hvordan kompilere med PHP med MySQL-støtte])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] er et populært åpen kildekode-databasesystem og et alternativ til MySQL.  ([http://www.php.net/manual/en/pgsql.installation.php Hvordan kompilere PHP med PostgreSQL-støtte])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] er den foretrukne databasetypen for MediaWiki og har best støtte.  MediaWiki fungerer også med [{{int:version-db-mariadb-url}} MariaDB] og [{{int:version-db-percona-url}} Percona Server], som begge er MySQL-kompatible. ([https://secure.php.net/manual/en/mysqli.installation.php Hvordan kompilere PHP med MySQL-støtte])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] er et populært åpen kildekode-databasesystem og et alternativ til MySQL.  ([https://secure.php.net/manual/en/pgsql.installation.php Hvordan kompilere PHP med PostgreSQL-støtte])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] er et lettvekts-databasesystem som har veldig god støtte. ([http://www.php.net/manual/en/pdo.installation.php Hvordan kompilere PHP med SQLite-støtte], bruker PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] er en kommersiell database for bedrifter. ([http://www.php.net/manual/en/oci8.installation.php Hvordan kompilere PHP med OCI8-støtte])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQLServer] er en kommersiell enterprise-database for Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Hvordan kompilere PHP med SQLSRV-støtte])",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] er en kommersiell database for bedrifter. ([https://secure.php.net/manual/en/oci8.installation.php Hvordan kompilere PHP med OCI8-støtte])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] er et kommersielt databasesystem under Windows for bedrifter. ([https://secure.php.net/manual/en/sqlsrv.installation.php Hvordan kompilere PHP med SQLSRV-støtte])",
        "config-header-mysql": "MySQL-innstillinger",
        "config-header-postgres": "PostgreSQL-innstillinger",
        "config-header-sqlite": "SQLite-innstillinger",
        "config-license-help": "Mange åpne wikier legger alle bidrag under en [https://freedomdefined.org/Definition gratislisens].\nDette gir en følelse av felleseie og stimulerer til langvarige bidrag.\nDette er normalt unødvendig for en privat eller virksomhetsbegrenset wiki.\n\nHvis du ønsker å kunne bruke tekst fra Wikipedia, og at Wikipedia skal kunne ta i mot tekst kopiert fra din wiki, bør du velge <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipedia brukte tidligere GNU Free Documentation License.\nGFDL er en grei lisens, med vanskelig å forstå.\nDet er også vanskelig å gjenbruke innhold lisensiert under GFDL.",
        "config-email-settings": "E-postinnstillinger",
        "config-enable-email": "Aktiver utgående e-post",
-       "config-enable-email-help": "Hvis du vil at e-post skal virke må [http://www.php.net/manual/en/mail.configuration.php PHPs e-postinnstillinger] bli konfigurert riktig.\nHvis du ikke ønsker noen e-postfunksjoner kan du deaktivere dem her.",
+       "config-enable-email-help": "Hvis du vil at e-post skal virke, må [https://secure.php.net/manual/en/mail.configuration.php PHPs e-post-innstillinger] konfigureres riktig.\nHvis du ikke ønsker noen e-postfunksjoner, kan du deaktivere dem her.",
        "config-email-user": "Aktiver e-post mellom brukere",
        "config-email-user-help": "Tillat alle brukere å sende hverandre e-post hvis de har aktivert det i deres innstillinger.",
        "config-email-usertalk": "Aktiver brukerdiskusjonssidevarsler",
index 566f72a..dcee489 100644 (file)
@@ -56,7 +56,7 @@
        "config-almost-done": "Je bent bijna klaar!\nAls je wilt kan je de overige instellingen overslaan en de wiki nu installeren.",
        "config-profile-help": "Wiki's werken het beste als ze door zoveel mogelijk gebruikers worden bewerkt.\nIn MediaWiki is het eenvoudig om de recente wijzigingen te controleren en eventuele foutieve of kwaadwillende bewerkingen terug te draaien.\n\nDaarnaast vinden velen MediaWiki goed inzetbaar in vele andere rollen, en soms is het niet handig om helemaal \"op de wikimanier\" te werken.\nDaarom biedt dit installatieprogramma je de volgende keuzes voor de basisinstelling van gebruikersvrijheden:\n\nEen '''{{int:config-profile-wiki}}''' staat iedereen toe te bewerken, zonder zelfs aan te melden.\nEen wiki met '''{{int:config-profile-no-anon}}\" biedt extra verantwoordelijkheid, maar kan afschrikken toevallige gebruikers afschrikken.\n\nHet scenario '''{{int:config-profile-fishbowl}}''' laat gebruikers waarvoor dat is ingesteld bewerkt, maar andere gebruikers kunnen alleen pagina's bekijken, inclusief de bewerkingsgeschiedenis.\nIn een '''{{int:config-profile-private}}''' kunnen alleen goedgekeurde gebruikers pagina's bekijken en bewerken.\n\nMeer complexe instellingen voor gebruikersrechten zijn te maken na de installatie; hierover is meer te lezen in de [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:User_rights handleiding].",
        "config-license-help": "In veel openbare wiki's zijn alle bijdragen beschikbaar onder een [https://freedomdefined.org/Definition vrije licentie].\nDit helpt bij het creëren van een gevoel van gemeenschappelijk eigendom en stimuleert bijdragen op lange termijn.\nDit is over het algemeen niet nodig is voor een particuliere of zakelijke wiki.\n\nAls je teksten uit Wikipedia wilt kunnen gebruiken en je wilt het mogelijk maken teksten uit je wiki naar Wikipedia te kopiëren, kies dan de licentie '''Creative Commons Naamsvermelding-Gelijk delen'''.\n\nDe GNU Free Documentation License is de oude licentie voor inhoud uit Wikipedia.\nDit is nog steeds een geldige licentie, maar deze licentie is lastig te begrijpen.\nHet is ook lastig inhoud te hergebruiken onder de GFDL.",
-       "config-enable-email-help": "Als je wilt dat e-mailen mogelijk is, dan moeten de [http://www.php.net/manual/en/mail.configuration.php e-mailinstellingen van PHP] correct zijn.\nAls je niet wilt dat e-mailen mogelijk is, dan kan je de instellingen hier uitschakelen.",
+       "config-enable-email-help": "Als je wilt dat e-mailen mogelijk is, dan moeten de [Config-dbsupport-oracle/manual/en/mail.configuration.php e-mailinstellingen van PHP] correct zijn.\nAls je niet wilt dat e-mailen mogelijk is, dan kan je de instellingen hier uitschakelen.",
        "config-upload-help": "Het toestaan van het uploaden van bestanden stelt je server mogelijk bloot aan beveiligingsrisico's.\nEr is meer [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security informatie over beveiliging] beschikbaar in de handleiding.\n\nOm het bestandsuploads mogelijk te maken kan je de rechten op de submap <code>images</code> onder de hoofdmap van MediaWiki aanpassen, zodat de webserver erin kan schrijven.\nDaarmee wordt deze functie ingeschakeld.",
        "config-logo-help": "Het standaarduiterlijk van MediaWiki bevat ruimte voor een logo van 135x160 pixels boven het menu.\nUpload een afbeelding met de juiste afmetingen en voer de URL hier in.\n\nAls je geen logo wilt gebruiken, kan je dit veld leeg laten.",
        "config-cc-not-chosen": "Kies de Creative Commonslicentie die je wilt gebruiken en klik op \"proceed\".",
index 81416cc..607926e 100644 (file)
        "config-pcre-no-utf8": "<strong>Onherstelbare fout:</strong> de module PRCE van PHP lijkt te zijn gecompileerd zonder ondersteuning voor PCRE_UTF8.\nMediaWiki heeft ondersteuning voor UTF-8 nodig om correct te kunnen werken.",
        "config-memory-raised": "PHP's <code>memory_limit</code> is $1 en is verhoogd tot $2.",
        "config-memory-bad": "'''Waarschuwing:''' PHP's <code>memory_limit</code> is $1.\nDit is waarschijnlijk te laag.\nDe installatie kan mislukken!",
-       "config-apc": "[http://www.php.net/apc APC] is op dit moment geïnstalleerd",
-       "config-apcu": "[http://www.php.net/apcu APCu] is geïnstalleerd",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] is op dit moment geïnstalleerd",
-       "config-no-cache-apcu": "<strong>Waarschuwing:</strong> [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] of [http://www.iis.net/download/WinCacheForPhp WinCache] is niet aangetroffen.\nHet cachen van objecten is niet ingeschakeld.",
+       "config-apc": "[https://secure.php.net/apc APC] is op dit moment geïnstalleerd",
+       "config-apcu": "[https://secure.php.net/apcu APCu] is geïnstalleerd",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] is op dit moment geïnstalleerd",
+       "config-no-cache-apcu": "<strong>Waarschuwing:</strong> [https://secure.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] of [https://www.iis.net/downloads/microsoft/wincache-extension WinCache] is niet aangetroffen.\nHet cachen van objecten is niet ingeschakeld.",
        "config-mod-security": "<strong>Waarschuwing:</strong> Uw webserver heeft de module [https://modsecurity.org/ mod_security]/mod_security2 ingeschakeld. Veel standaard instellingen hiervan zorgen voor problemen in combinatie met MediaWiki en andere software die gebruikers in staat stelt willekeurige inhoud te posten.\nIndien mogelijk, zou deze moeten worden uitgeschakeld. Lees anders de [https://modsecurity.org/documentation/ documentatie over mod_security] of neem contact op met de helpdesk van uw provider als u tegen problemen aanloopt.",
        "config-diff3-bad": "GNU diff3 niet aangetroffen.",
        "config-git": "Versiecontrolesoftware git is aangetroffen: <code>$1</code>",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki ondersteunt de volgende databasesystemen:\n\n$1\n\nAls u het databasesysteem dat u wilt gebruiken niet in de lijst terugvindt, volg dan de handleiding waarnaar hierboven wordt verwezen om ondersteuning toe te voegen.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] is de primaire database voor MediaWiki en wordt het best ondersteund. MediaWiki werkt ook met [{{int:version-db-mariadb-url}} MariaDB] en [{{int:version-db-percona-url}} Percona Server], die MySQL compatibel zijn ([http://www.php.net/manual/en/mysqli.installation.php hoe PHP te compileren met MySQL-ondersteuning]).",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] is een populair open source databasesysteem als alternatief voor MySQL.([http://www.php.net/manual/en/pgsql.installation.php Hoe u PHP kunt compileren met ondersteuning voor PostgreSQL])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] is de primaire database voor MediaWiki en wordt het best ondersteund. MediaWiki werkt ook met [{{int:version-db-mariadb-url}} MariaDB] en [{{int:version-db-percona-url}} Percona Server], die MySQL compatibel zijn ([https://secure.php.net/manual/en/mysqli.installation.php hoe PHP te compileren met MySQL-ondersteuning]).",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] is een populair open source databasesysteem als alternatief voor MySQL.([https://secure.php.net/manual/en/pgsql.installation.php Hoe u PHP kunt compileren met ondersteuning voor PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] is een zeer goed ondersteund lichtgewicht databasesysteem ([http://www.php.net/manual/en/pdo.installation.php hoe PHP gecompileerd moet zijn met ondersteuning voor SQLite]; gebruikt PDO).",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] is een commerciële database voor grote bedrijven ([http://www.php.net/manual/en/oci8.installation.php PHP compileren met ondersteuning voor OCI8]).",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] is een commerciële enterprisedatabase voor Windows ([http://www.php.net/manual/en/sqlsrv.installation.php PHP compileren met ondersteuning voor SQLSRV]).",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] is een commerciële enterprisedatabase voor Windows ([https://secure.php.net/manual/en/sqlsrv.installation.php PHP compileren met ondersteuning voor SQLSRV]).",
        "config-header-mysql": "MySQL-instellingen",
        "config-header-postgres": "PostgreSQL-instellingen",
        "config-header-sqlite": "SQLite-instellingen",
        "config-license-help": "In veel openbare wiki's zijn alle bijdragen beschikbaar onder een [https://freedomdefined.org/Definition vrije licentie].\nDit helpt bij het creëren van een gevoel van gemeenschappelijk eigendom en stimuleert bijdragen op lange termijn.\nDit is over het algemeen niet nodig is voor een particuliere of zakelijke wiki.\n\nAls u teksten uit Wikipedia wilt kunnen gebruiken en u wilt het mogelijk maken teksten uit uw wiki naar Wikipedia te kopiëren, kies dan de licentie <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nDe GNU Free Documentation License is de oude licentie voor inhoud uit Wikipedia.\nDit is nog steeds een geldige licentie, maar deze licentie is lastig te begrijpen.\nHet is ook lastig inhoud te hergebruiken onder de GFDL.",
        "config-email-settings": "E-mailinstellingen",
        "config-enable-email": "Uitgaande e-mail inschakelen",
-       "config-enable-email-help": "Als u wilt dat e-mailen mogelijk is, dan moeten de [http://www.php.net/manual/en/mail.configuration.php e-mailinstellingen van PHP] correct zijn.\nAls u niet wilt dat e-mailen mogelijk is, dan kunt u de instellingen hier uitschakelen.",
+       "config-enable-email-help": "Als u wilt dat e-mailen mogelijk is, dan moeten de [Config-dbsupport-oracle/manual/en/mail.configuration.php e-mailinstellingen van PHP] correct zijn.\nAls u niet wilt dat e-mailen mogelijk is, dan kunt u de instellingen hier uitschakelen.",
        "config-email-user": "E-mail tussen gebruikers inschakelen",
        "config-email-user-help": "Gebruikers toestaan e-mail aan elkaar te verzenden als dit in de voorkeuren is ingesteld.",
        "config-email-usertalk": "Gebruikersoverlegmeldingen inschakelen",
index 7ac065b..c099895 100644 (file)
@@ -41,8 +41,8 @@
        "config-env-hhvm": "HHVM $1 es installat.",
        "config-unicode-using-intl": "Utilizacion de [https://pecl.php.net/intl l'extension PECL intl] per la normalizacion Unicode.",
        "config-memory-raised": "Lo paramètre <code>memory_limit</code> de PHP èra a $1, portat a $2.",
-       "config-apc": "[http://www.php.net/apc APC] es installat",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] es installat",
+       "config-apc": "[https://secure.php.net/apc APC] es installat",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] es installat",
        "config-diff3-bad": "GNU diff3 pas trobat.",
        "config-git": "Logicial de contraròtle de version Git trobat : <code>$1</code>.",
        "config-git-bad": "Logicial de contraròtle de version Git pas trobat.",
index 5b4718c..f1003c6 100644 (file)
        "config-pcre-no-utf8": "'''Błąd krytyczny''' – wydaje się, że moduł PCRE w PHP został skompilowany bez wsparcia dla UTF‐8.\nMediaWiki wymaga wsparcia dla UTF‐8 do prawidłowego działania.",
        "config-memory-raised": "PHP <code>memory_limit</code> było ustawione na $1, zostanie zwiększone do $2.",
        "config-memory-bad": "'''Uwaga:''' PHP <code>memory_limit</code> jest ustawione na $1.\nTo jest prawdopodobnie zbyt mało.\nInstalacja może się nie udać!",
-       "config-apc": "[Http://www.php.net/apc APC] jest zainstalowany",
-       "config-apcu": "[http://www.php.net/apcu APCu] jest zainstalowany",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] jest zainstalowany",
-       "config-no-cache-apcu": "<strong>Ostrzeżenie:</strong> Nie można było znaleźć [http://www.php.net/apcu APCu] ani [http://www.iis.net/download/WinCacheForPhp WinCache].\nPamięć podręczna obiektów nie została włączona.",
+       "config-apc": "[https://secure.php.net/apc APC] jest zainstalowany",
+       "config-apcu": "[https://secure.php.net/apcu APCu] jest zainstalowany",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] jest zainstalowany",
+       "config-no-cache-apcu": "<strong>Ostrzeżenie:</strong> Nie można było znaleźć [https://secure.php.net/apcu APCu] ani [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nPamięć podręczna obiektów nie została włączona.",
        "config-mod-security": "''' Ostrzeżenie ''': Serwer sieci web ma włączone [https://modsecurity.org/ mod_security]. Jeśli jest niepoprawnie skonfigurowane, może być przyczyną problemów MediaWiki lub innego oprogramowania, które pozwala użytkownikom na wysyłanie dowolnej zawartości.\nSprawdź w [https://modsecurity.org/documentation/ dokumentacji mod_security] lub skontaktuj się z obsługa hosta, jeśli wystąpią losowe błędy.",
        "config-diff3-bad": "Nie znaleziono GNU diff3.",
        "config-git": "Znaleziono oprogramowanie kontroli wersji Git: <code>$1</code>.",
        "config-type-mysql": "MySQL (lub kompatybilna)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki może współpracować z następującymi systemami baz danych:\n\n$1\n\nPoniżej wyświetlone są systemy baz danych gotowe do użycia. Jeżeli poniżej brakuje bazy danych, z której chcesz skorzystać, oznacza to, że brakuje odpowiedniego oprogramowania lub zostało ono niepoprawnie skonfigurowane. Powyżej znajdziesz odnośniki do dokumentacji, która pomoże w konfiguracji odpowiednich komponentów.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] jest bazą danych, na której rozwijane jest oprogramowanie MediaWiki. MediaWiki działa również z [{{int:version-db-mariadb-url}} MariaDB] i [{{int:version-db-percona-url}} Percona Server], które są zgodne z MySQL. ([http://www.php.net/manual/en/mysqli.installation.php Zobacz, jak skompilować PHP ze wsparciem dla MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] jest popularnym systemem baz danych, często stosowanym zamiast MySQL. ([http://www.php.net/manual/pl/pgsql.installation.php Zobacz, jak skompilować PHP z obsługą PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] jest niewielkim systemem bazy danych, z którym MediaWiki bardzo dobrze współpracuje. ([http://www.php.net/manual/en/pdo.installation.php Zobacz, jak skompilować PHP ze wsparciem dla SQLite], korzystając z PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] jest komercyjną profesjonalną bazą danych. ([http://www.php.net/manual/en/oci8.installation.php Jak skompilować PHP ze wsparciem dla OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] jest komercyjną profesjonalną bazą danych. ([http://www.php.net/manual/pl/sqlsrv.installation.php Jak skompilować PHP ze wsparciem dla SQLSRV])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] jest bazą danych, na której rozwijane jest oprogramowanie MediaWiki. MediaWiki działa również z [{{int:version-db-mariadb-url}} MariaDB] i [{{int:version-db-percona-url}} Percona Server], które są zgodne z MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Zobacz, jak skompilować PHP ze wsparciem dla MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] jest popularnym, otawrtym systemem baz danych, często stosowanym jako alternatywa dla MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Zobacz, jak skompilować PHP z obsługą PostgreSQL])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] jest niewielkim systemem bazy danych, z którym MediaWiki bardzo dobrze współpracuje. ([https://secure.php.net/manual/pl/pdo.installation.php Zobacz, jak skompilować PHP ze wsparciem dla SQLite], korzystając z PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] jest komercyjną profesjonalną bazą danych. ([https://secure.php.net/manual/pl/oci8.installation.php Jak skompilować PHP ze wsparciem dla OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] jest komercyjną profesjonalną bazą danych. ([https://secure.php.net/manual/pl/sqlsrv.installation.php Jak skompilować PHP ze wsparciem dla SQLSRV])",
        "config-header-mysql": "Ustawienia MySQL",
        "config-header-postgres": "Ustawienia PostgreSQL",
        "config-header-sqlite": "Ustawienia SQLite",
        "config-license-help": "Wiele publicznych wiki umieszcza wszystkie dopisane treści na [https://freedomdefined.org/Definition wolnej licencji].\nPomaga to tworzyć poczucie wspólnoty i zachęca do długoterminowego wkładu.\nNie jest to zazwyczaj konieczne w prywatnych lub firmowych wiki.\n\nJeśli chcesz móc użyć tekstu z Wikipedii i chcesz Wikipedia mogła zaakceptować tekst skopiowany z twojej wiki, należy wybrać <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipedia używała poprzednio GNU Free Documentation License.\nGFDL jest poprawną licencję, ale trudno ją zrozumieć.\nTrudno także ponowne użyć zawartości na licencji GFDL.",
        "config-email-settings": "Ustawienia e-maili",
        "config-enable-email": "Włącz wychodzące wiadomości e–mail",
-       "config-enable-email-help": "Jeśli chcesz, aby działał e-mail, [http://www.php.net/manual/en/mail.configuration.php Ustawienia poczty PHP] muszą być poprawnie wprowadzone.\nJeśli nie chcesz jakichś funkcji poczty e-mail, można je wyłączyć tutaj.",
+       "config-enable-email-help": "Jeśli chcesz, aby działał e-mail, [https://secure.php.net/manual/pl/mail.configuration.php Ustawienia poczty PHP] muszą być poprawnie wprowadzone.\nJeśli nie chcesz jakichś funkcji poczty e-mail, można je wyłączyć tutaj.",
        "config-email-user": "Włącz możliwość przesyłania e‐maili pomiędzy użytkownikami",
        "config-email-user-help": "Zezwalaj użytkownikom na wysyłanie wzajemnie e‐maili, jeśli będą mieć włączoną tę funkcję w swoich preferencjach.",
        "config-email-usertalk": "Włącz powiadamianie o zmianach na stronie dyskusji użytkownika",
        "config-nofile": "Nie udało się odnaleźć pliku \"$1\". Czy nie został usunięty?",
        "config-extension-link": "Czy wiesz, że twoja wiki obsługuje [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions rozszerzenia]?\n\nMożesz przejrzeć [https://www.mediawiki.org/wiki/Category:Extensions_by_category rozszerzenia według kategorii] lub [https://www.mediawiki.org/wiki/Extension_Matrix Extension Matrix], aby zobaczyć pełną listę rozszerzeń.",
        "config-skins-screenshots": "$1 (zrzut ekranu: $2)",
+       "config-extensions-requires": "$1 (wymaga $2)",
        "config-screenshot": "zrzut ekranu",
        "mainpagetext": "<strong>Instalacja MediaWiki powiodła się.</strong>",
        "mainpagedocfooter": "Zapoznaj się z [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Podręcznikiem użytkownika] zawierającym informacje o tym jak korzystać z oprogramowania wiki.\n\n== Na początek ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista ustawień konfiguracyjnych]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Komunikaty o nowych wersjach MediaWiki (lista dyskusyjna)]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Przetłumacz MediaWiki na swój język]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Dowiedz się, jak walczyć ze spamem na swojej wiki]"
index e89b5db..f397942 100644 (file)
@@ -62,8 +62,8 @@
        "config-pcre-no-utf8": "'''Fatal''': ël mòdul PCRE ëd PHP a smija esse compilà sensa l'apògg PCRE_UTF8.\nMediaWiki a ciama l'apògg d'UTF8 për marcé për da bin.",
        "config-memory-raised": "<code>memory_limit</code> ëd PHP a l'é $1, aussà a $2.",
        "config-memory-bad": "'''Avis:''' <code>memory_limit</code> ëd PHP a l'é $1.\nSossì a l'é probabilment tròp bass.\nL'instalassion a peul falì!",
-       "config-apc": "[http://www.php.net/apc APC] a l'é instalà",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache]  a l'é instalà",
+       "config-apc": "[https://secure.php.net/apc APC] a l'é instalà",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache]  a l'é instalà",
        "config-mod-security": "'''Avis''': Sò servent për l'aragnà a l'ha [https://modsecurity.org/ mod_security] abilità. Se mal configurà, a peul causé dij problema për MediaWiki o d'àutri programa ch'a përmëtto a j'utent dë spedì un contnù qualsëssìa.\nCh'a fasa arferiment a la [https://modsecurity.org/documentation/ mod_security documentassion] o ch'a contata l'echip ëd sò servissi s'a-j rivo dj'eror casuaj.",
        "config-diff3-bad": "GNU diff3 pa trovà.",
        "config-imagemagick": "Trovà ImageMagick: <code>$1</code>.\nLa miniaturisassion ëd figure a sarà abilità s'it abìlite le carie.",
        "config-oracle-def-ts": "Spassi dla tàula dë stàndard:",
        "config-oracle-temp-ts": "Spassi dla tàula temporani:",
        "config-support-info": "MediaWiki a manten ij sistema ëd base ëd dàit sì-dapress:\n\n$1\n\nS'a vëd pa listà sì-sota ël sistema ëd base ëd dàit ch'a preuva a dovré, antlora va andaré a j'istrussion dl'anliura sì-dzora për abilité ël manteniment.",
-       "config-dbsupport-mysql": "* $1 e l'é l'obietiv primari për MediaWiki e a l'é mej mantnù ([http://www.php.net/manual/en/mysql.installation.php com compilé PHP con ël manteniment MySQL])",
-       "config-dbsupport-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-dbsupport-mysql": "* $1 e l'é l'obietiv primari për MediaWiki e a l'é mej mantnù ([https://secure.php.net/manual/en/mysql.installation.php com compilé PHP con ël manteniment MySQL])",
+       "config-dbsupport-postgres": "* $1 e l'é un sistema ëd base ëd dàit popolar a sorgiss duverta com alternativa a MySQL ([https://secure.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-dbsupport-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-dbsupport-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-header-mysql": "Ampostassion MySQL",
        "config-license-help": "Vàire wiki pùbliche a buto tute le contribussion sota na [https://freedomdefined.org/Definition licensa lìbera]. Sòn a giuta a creé un sens d'apartenensa a la comunità e a ancoragia ëd contribussion ëd longa durà.\nA l'é generalment nen necessari për na wiki privà o d'asienda.\n\nS'a veul podèj dovré dij test da Wikipedia, e a veul che Wikipedia a aceta dij test copià da soa wiki, a dovrìa serne '''Creative Commons Attribution Share Alike'''.\n\nWikipedia prima a dovrava la GNU Free Documentation License.\nLa GDFL a l'é anco' na licensa bon-a, ma a l'é complicà capila.\nA l'é ëdcò mal fé riutilisé dël contnù licensià sota la GDFL.",
        "config-email-settings": "Ampostassion ëd pòsta eletrònica",
        "config-enable-email": "Abilité ij mëssagi ëd pòsta eletrònica an surtìa",
-       "config-enable-email-help": "S'a veul che la pòsta eletrònica a marcia, j'[http://www.php.net/manual/en/mail.configuration.php ampostassion ëd pòsta eletrònica PHP] a devo esse configurà për da bin.\nS'a veul pa 'd funsion ëd pòsta eletrònica, a dev disabiliteje ambelessì.",
+       "config-enable-email-help": "S'a veul che la pòsta eletrònica a marcia, j'[Config-dbsupport-oracle/manual/en/mail.configuration.php ampostassion ëd pòsta eletrònica PHP] a devo esse configurà për da bin.\nS'a veul pa 'd funsion ëd pòsta eletrònica, a dev disabiliteje ambelessì.",
        "config-email-user": "Abilité ij mëssagi ëd pòsta eletrònica da utent a utent",
        "config-email-user-help": "A përmët a tùit j'utent ëd mandesse ëd mëssagi ëd pòsta eletrònica se lor a l'han abilità sòn an soe preferense.",
        "config-email-usertalk": "Abilité notìfica dle pàgine ëd discussion dj'utent",
index 68c2376..cad2822 100644 (file)
@@ -30,8 +30,8 @@
        "config-restart": "هو، سر له نوي يې پيل کړه",
        "config-env-php": "د $1 PHP نصب شو.",
        "config-env-hhvm": "HHVM $1 نصب شو.",
-       "config-apc": "[http://www.php.net/apc APC] نصب شو",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] نصب شو",
+       "config-apc": "[https://secure.php.net/apc APC] نصب شو",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] نصب شو",
        "config-diff3-bad": "جي ان يو ډيف3 و نه موندل شو.",
        "config-using-server": "د پالنگر نوم \"<nowiki>$1</nowiki>\" کارېږي.",
        "config-using-uri": "د پالنگر URL \"<nowiki>$1$2</nowiki>\" کارېږي.",
index 723b25e..bc3abc8 100644 (file)
        "config-pcre-no-utf8": "<strong>Erro fatal:</strong> O módulo PCRE do PHP parece ser compilado sem suporte a PCRE_UTF8.\nO MediaWiki requer suporte a UTF-8 para funcionar corretamente.",
        "config-memory-raised": "A configuração <code>memory_limit</code> do PHP era $1; foi aumentada para $2.",
        "config-memory-bad": "<strong>Aviso:</strong> A configuração <code>memory_limit</code> do PHP é $1.\nIsso provavelmente é muito baixo.\nA instalação pode falhar!",
-       "config-apc": "[http://www.php.net/apc APC] está instalado",
-       "config-apcu": "[http://www.php.net/apcu APCu] está instalado",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] está instalado",
-       "config-no-cache-apcu": "<strong>Aviso:</strong> Não foram encontrados o [http://www.php.net/apcu APCu], ou o [http://www.iis.net/download/WinCacheForPhp WinCache].\nA cache de objetos não está ativa.",
+       "config-apc": "[https://secure.php.net/apc APC] está instalado",
+       "config-apcu": "[https://secure.php.net/apcu APCu] está instalado",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] está instalado",
+       "config-no-cache-apcu": "<strong>Aviso:</strong> Não foram encontrados o [https://secure.php.net/apcu APCu], ou o [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nA cache de objetos não está ativa.",
        "config-mod-security": "<strong>Aviso:</strong> Seu servidor web tem [https://modsecurity.org/ mod_security2] habilitado. Muitas configurações comuns de módulo podem causar problemas para o MediaWiki ou outro software que permite aos usuários postar conteúdo arbitrário.\nSe possível, ele dever ser desativad. Consulte a [https://modsecurity.org/documentation/ documentação do mod_security] ou entre em contato com o suporte do seu host se você encontrar erros aleatórios.",
        "config-diff3-bad": "O GNU diff3 não foi encontrado.",
        "config-git": "Foi encontrado o software de controle de versão Git: <code>$1</code>.",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "O MediaWiki suporta os sistemas de banco de dados a seguir:\n\n$1\n\nSe você não vê o sistema de banco de dados que você está tentando usar listados abaixo, siga as instruções relacionadas acima, para ativar o suporte.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] é o principal alvo para o MediaWiki e é melhor suportado. O MediaWiki também funciona com [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], que são compatíveis com MySQL. ([Http://www.php.net/manual/en/mysqli.installation.php Como compilar PHP com suporte a MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] é um popular sistema de banco de dados de código aberto como uma alternativa para o MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Como compilar o PHP com suporte PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] é um sistema de banco de dados leve que é muito bem suportado. ([http://www.php.net/manual/en/pdo.installation.php como compilar o PHP com suporte a SQLite], usa DOP)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] é um banco de dados comercial de empresas. ([http://www.php.net/manual/en/oci8.installation.php Como compilar o PHP com suporte OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] é uma banco de dados comercial do Windows para empresas. ([http://www.php.net/manual/en/sqlsrv.installation.php Como compilar o PHP com suporte SQLSRV])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] é um popular sistema de banco de dados de código aberto como uma alternativa para o MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Como compilar o PHP com suporte PostgreSQL])",
+       "config-dbsupport-sqlite": "* O [{{int:version-db-sqlite-url}} SQLite] é uma plataforma de base de dados ligeira muito bem suportada. ([https://secure.php.net/manual/en/pdo.installation.php Como compilar PHP com suporte para SQLite], usa PDO.)",
+       "config-dbsupport-oracle": "* A [{{int:version-db-oracle-url}} Oracle] é uma base de dados comercial para empresas. ([https://secure.php.net/manual/en/oci8.installation.php Como compilar PHP com suporte para OCI8].)",
+       "config-dbsupport-mssql": "* O [{{int:version-db-mssql-url}} Microsoft SQL Server] é uma base de dados comercial do Windows para empresas. ([https://secure.php.net/manual/en/sqlsrv.installation.php Como compilar PHP com suporte para SQLSRV].)",
        "config-header-mysql": "Configurações MySQL",
        "config-header-postgres": "Configurações PostgreSQL",
        "config-header-sqlite": "Configurações SQLite",
        "config-license-help": "Muitas wikis públicas colocam todas as contribuições sob uma [https://freedomdefined.org/Definition licença livre].\nIsso ajuda a criar um senso de propriedade da comunidade e incentiva a contribuição de longo prazo.\nGeralmente não é necessário para uma empresa privada ou wiki corporativa.\nSe você quiser poder usar o texto da Wikipédia e quiser que a Wikipédia possa aceitar o texto copiado da sua wiki, você deve escolher <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nA Wikipédia usou anteriormente a Licença de Documentação Livre GNU.\n A GFDL é uma licença válida, mas é difícil de entender.\nTambém é difícil reutilizar conteúdo licenciado sob o GFDL.",
        "config-email-settings": "Configurações de e-mail",
        "config-enable-email": "Ativar envio de e-mail",
-       "config-enable-email-help": "Se você quer que o e-mail funcione, estas [http://www.php.net/manual/en/mail.configuration.php configurações de e-mail PHP] precisam ser configuradas corretamente.\nSe você não quiser usar nenhuma das funcionalidades, você pode desabilitá-las aqui.",
+       "config-enable-email-help": "Se você quer que o e-mail funcione, estas [Config-dbsupport-oracle/manual/en/mail.configuration.php configurações de e-mail PHP] precisam ser configuradas corretamente.\nSe você não quiser usar nenhuma das funcionalidades, você pode desabilitá-las aqui.",
        "config-email-user": "Ativar e-mails entre usuários",
        "config-email-user-help": "Permitir que todos os usuários enviem e-mail entre si se eles tiverem habilitado este recurso em suas preferências.",
        "config-email-usertalk": "Ativar notificação de alterações em páginas de discussão de usuário",
index 11f0255..26931f8 100644 (file)
        "config-pcre-no-utf8": "'''Erro fatal''': O módulo PCRE do PHP parece ter sido compilado sem suporte PCRE_UTF8.\nO MediaWiki necessita do suporte UTF-8 para funcionar corretamente.",
        "config-memory-raised": "A configuração <code>memory_limit</code> do PHP era $1; foi aumentada para $2.",
        "config-memory-bad": "<strong>Aviso:</strong> A configuração <code>memory_limit</code> do PHP é $1.\nIsto é provavelmente demasiado baixo.\nA instalação poderá falhar!",
-       "config-apc": "[http://www.php.net/apc APC] instalada",
-       "config-apcu": "[http://www.php.net/apcu APCu] instalado",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] instalada",
-       "config-no-cache-apcu": "<strong>Aviso:</strong> Não foi encontrado o [http://www.php.net/apcu APCu] nem o [http://www.iis.net/download/WinCacheForPhp WinCache].\nA cache de objetos não está ativa.",
+       "config-apc": "[https://secure.php.net/apc APC] instalada",
+       "config-apcu": "[https://secure.php.net/apcu APCu] instalado",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] instalada",
+       "config-no-cache-apcu": "<strong>Aviso:</strong> Não foi encontrado o [https://secure.php.net/apcu APCu] nem o [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nA cache de objetos não está ativa.",
        "config-mod-security": "<strong>Aviso:</strong> O seu servidor de Internet tem o [https://modsecurity.org/ mod_security]/mod_security2 ativado. Muitas das suas configurações normais podem causar problemas ao MediaWiki e a outros programas, permitindo que os utilizadores publiquem conteúdos arbitrários.\nSe possível, isto deve ser desativado. Se não, consulte a [https://modsecurity.org/documentation/ mod_security documentação] ou peça apoio ao fornecedor do alojamento do seu servidor se encontrar erros aleatórios.",
        "config-diff3-bad": "O GNU diff3 não foi encontrado.",
        "config-git": "Foi encontrado o software de controlo de versões Git: <code>$1</code>.",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "O MediaWiki suporta as seguintes plataformas de base de dados:\n\n$1\n\nSe a plataforma que pretende usar não está listada abaixo, siga as instruções nas hiperligações acima para ativar o suporte.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] é a plataforma primária do MediaWiki e é a melhor suportada. O MediaWiki também trabalha com [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], que são compatíveis com MySQL. ([http://www.php.net/manual/en/mysql.installation.php Como compilar PHP com suporte a MySQL])",
-       "config-dbsupport-postgres": "* O [{{int:version-db-postgres-url}} PostgreSQL] é uma plataforma popular de base de dados de código aberto, alternativa ao MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Como compilar o PHP com suporte PostgreSQL])",
-       "config-dbsupport-sqlite": "* O [{{int:version-db-sqlite-url}} SQLite] é uma plataforma de base de dados ligeira muito bem suportada. ([http://www.php.net/manual/en/pdo.installation.php Como compilar o PHP com suporte SQLite], usa PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] é uma base de dados comercial para empresas. ([http://www.php.net/manual/en/oci8.installation.php Como compilar o PHP com suporte OCI8])",
-       "config-dbsupport-mssql": "* O [{{int:version-db-mssql-url}} Microsoft SQL Server] é uma base de dados comercial do Windows para empresas. ([http://www.php.net/manual/en/sqlsrv.installation.php Como compilar o PHP com suporte SQLSRV])",
+       "config-dbsupport-mysql": "* O [{{int:version-db-mysql-url}} MySQL] é a base de dados preferida para o MediaWiki e a melhor suportada. O MediaWiki também trabalha com [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], que são compatíveis com MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Como compilar PHP com suporte para MySQL].)",
+       "config-dbsupport-postgres": "* O [{{int:version-db-postgres-url}} PostgreSQL] é uma plataforma popular de base de dados de código aberto, alternativa ao MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Como compilar PHP com suporte para PostgreSQL].)",
+       "config-dbsupport-sqlite": "* O [{{int:version-db-sqlite-url}} SQLite] é uma plataforma de base de dados ligeira muito bem suportada. ([https://secure.php.net/manual/en/pdo.installation.php Como compilar PHP com suporte para SQLite], usa PDO.)",
+       "config-dbsupport-oracle": "* A [{{int:version-db-oracle-url}} Oracle] é uma base de dados comercial para empresas. ([https://secure.php.net/manual/en/oci8.installation.php Como compilar PHP com suporte para OCI8].)",
+       "config-dbsupport-mssql": "* O [{{int:version-db-mssql-url}} Microsoft SQL Server] é uma base de dados comercial do Windows para empresas. ([https://secure.php.net/manual/en/sqlsrv.installation.php Como compilar PHP com suporte para SQLSRV].)",
        "config-header-mysql": "Definições MySQL",
        "config-header-postgres": "Definições PostgreSQL",
        "config-header-sqlite": "Definições SQLite",
        "config-license-help": "Muitas wikis de acesso público licenciam todas as colaborações com uma [https://freedomdefined.org/Definition licença livre].\nIsto ajuda a criar um sentido de propriedade da comunidade e encoraja as colaborações a longo prazo.\nTal não é geralmente necessário nas wikis privadas ou corporativas.\n\nSe pretende que seja possível usar textos da Wikipédia na sua wiki e que seja possível a Wikipédia aceitar textos copiados da sua wiki, deve escolher a licença <strong>{{int:config-license-cc-by-sa}}</strong>..\n\nA licença anterior da Wikipédia era a licença GNU Free Documentation License.\nA GFDL é uma licença válida, mas de difícil compreensão.\nTambém é difícil reutilizar conteúdos licenciados com a GFDL.",
        "config-email-settings": "Definições do correio eletrónico",
        "config-enable-email": "Ativar mensagens eletrónicas de saída",
-       "config-enable-email-help": "Se quer que o correio eletrónico funcione, as [http://www.php.net/manual/en/mail.configuration.php definições de correio eletrónico do PHP] têm de estar configuradas corretamente.\nSe não pretende viabilizar qualquer funcionalidade de correio eletrónico, pode desativá-lo aqui.",
+       "config-enable-email-help": "Se quer que o correio eletrónico funcione, as [https://secure.php.net/manual/en/mail.configuration.php definições de correio eletrónico do PHP] têm de estar configuradas corretamente.\nSe não pretende viabilizar qualquer funcionalidade de correio eletrónico, pode desativá-lo aqui.",
        "config-email-user": "Ativar mensagens eletrónicas entre utilizadores",
        "config-email-user-help": "Permitir que todos os utilizadores troquem entre si mensagens de correio eletrónico, se tiverem ativado esta funcionalidade nas suas preferências.",
        "config-email-usertalk": "Ativar notificações de alterações à página de discussão dos utilizadores",
index 0d3f312..f5b2ced 100644 (file)
@@ -47,8 +47,8 @@
        "config-env-bad": "Verificarea mediului a fost efectuată.\nNu puteți instala MediaWiki.",
        "config-env-php": "PHP $1 este instalat.",
        "config-env-hhvm": "HHVM $1 este instalat.",
-       "config-apc": "[http://www.php.net/apc APC] este instalat",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] este instalat",
+       "config-apc": "[https://secure.php.net/apc APC] este instalat",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] este instalat",
        "config-diff3-bad": "GNU diff3 nu a fost găsit.",
        "config-no-uri": "<strong>Eroare:</strong> Nu pot determina URI-ul curent.\nInstalare întreruptă.",
        "config-db-type": "Tipul bazei de date:",
index 58637f8..2c262ab 100644 (file)
        "config-pcre-no-utf8": "'''Фатальная ошибка'''. Модуль PCRE для PHP, похоже, собран без поддержки PCRE_UTF8.\nMediaWiki требует поддержки UTF-8 для корректной работы.",
        "config-memory-raised": "Ограничение на доступную PHP память (<code>memory_limit</code>) поднято с $1 до $2.",
        "config-memory-bad": "'''Внимание:''' размер PHP <code>memory_limit</code> составляет $1.\nВероятно, этого слишком мало.\nУстановка может потерпеть неудачу!",
-       "config-apc": "[http://www.php.net/apc APC] установлен",
-       "config-apcu": "[http://www.php.net/apcu APCu] установлен",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] установлен",
-       "config-no-cache-apcu": "<strong>Внимание:</strong> Не найдены [http://www.php.net/apcu APCu] или [http://www.iis.net/download/WinCacheForPhp WinCache].\nКэширование объектов будет отключено.",
+       "config-apc": "[https://secure.php.net/apc APC] установлен",
+       "config-apcu": "[https://secure.php.net/apcu APCu] установлен",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] установлен",
+       "config-no-cache-apcu": "<strong>Внимание:</strong> Не найдены [https://secure.php.net/apcu APCu] или [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nКэширование объектов будет отключено.",
        "config-mod-security": "<strong>Внимание</strong>: На вашем веб-сервере включён [https://modsecurity.org/ mod_security]/mod_security2. Многие его стандартные настройки могут вызывать проблемы для MediaWiki или другого ПО, позволяющего пользователям отправлять на сервер произвольный контент.\nПо возможности он должен быть отключён. Обратитесь к [https://modsecurity.org/documentation/ документации mod_security] или в службу поддержки вашего хостинг-провайдера, если вы сталкиваетесь со случайными ошибками.",
        "config-diff3-bad": "GNU diff3 не найден.",
        "config-git": "Найдена система контроля версий Git: <code>$1</code>.",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki поддерживает следующие СУБД:\n\n$1\n\nЕсли вы не видите своей системы хранения данных в этом списке, следуйте инструкциям, на которые есть ссылка выше, чтобы получить поддержку.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] — основная база данных для MediaWiki, которая поддерживается лучше всего. MediaWiki также работает с [{{int:version-db-mariadb-url}} MariaDB] и [{{int:version-db-percona-url}} Percona Server], которые являются MySQL-совместимым. ([http://www.php.net/manual/ru/mysql.installation.php инструкция, как собрать PHP с поддержкой MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] â\80\94 Ð¿Ð¾Ð¿Ñ\83лÑ\8fÑ\80наÑ\8f Ð¾Ñ\82кÑ\80Ñ\8bÑ\82аÑ\8f Ð¡Ð£Ð\91Ð\94, Ð°Ð»Ñ\8cÑ\82еÑ\80наÑ\82ива MySQL. ([http://www.php.net/manual/ru/pgsql.installation.php Ð¸Ð½Ñ\81Ñ\82Ñ\80Ñ\83кÑ\86иÑ\8f, Ðºак собрать PHP с поддержкой PostgreSQL]).",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] — это легковесная система баз данных, имеющая очень хорошую поддержку. ([http://www.php.net/manual/ru/pdo.installation.php инструкция, как собрать PHP с поддержкой SQLite], работающей посредством PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] â\80\94 Ñ\8dÑ\82о ÐºÐ¾Ð¼Ð¼ÐµÑ\80Ñ\87еÑ\81каÑ\8f Ð±Ð°Ð·Ð° Ð´Ð°Ð½Ð½Ñ\8bÑ\85 Ð¼Ð°Ñ\81Ñ\88Ñ\82аба Ð¿Ñ\80едпÑ\80иÑ\8fÑ\82иÑ\8f. ([http://www.php.net/manual/ru/oci8.installation.php Как собрать PHP с поддержкой OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] â\80\94 Ñ\8dÑ\82о ÐºÐ¾Ð¼Ð¼ÐµÑ\80Ñ\87еÑ\81кое Ð±Ð°Ð·Ð° Ð´Ð°Ð½Ð½Ñ\8bÑ\85 Ð±Ð°Ð·Ð° Ð´Ð°Ð½Ð½Ñ\8bÑ\85 Ð´Ð»Ñ\8f Windows Ð¼Ð°Ñ\81Ñ\88Ñ\82аба Ð¿Ñ\80едпÑ\80иÑ\8fÑ\82иÑ\8f. ([http://www.php.net/manual/ru/sqlsrv.installation.php Как собрать PHP с поддержкой SQLSRV])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] — основная база данных для MediaWiki, которая поддерживается лучше всего. MediaWiki также работает с [{{int:version-db-mariadb-url}} MariaDB] и [{{int:version-db-percona-url}} Percona Server], которые являются MySQL-совместимыми. (См.[https://secure.php.net/manual/ru/mysql.installation.php Как собрать PHP с поддержкой MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] â\80\94 Ð¿Ð¾Ð¿Ñ\83лÑ\8fÑ\80наÑ\8f Ð¡Ð£Ð\91Ð\94 Ñ\81 Ð¾Ñ\82кÑ\80Ñ\8bÑ\82Ñ\8bм Ð¸Ñ\81Ñ\85однÑ\8bм ÐºÐ¾Ð´Ð¾Ð¼, Ð°Ð»Ñ\8cÑ\82еÑ\80наÑ\82ива MySQL. ([https://secure.php.net/manual/ru/pgsql.installation.php Ð\9aак собрать PHP с поддержкой PostgreSQL]).",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] — это легковесная система баз данных, имеющая очень хорошую поддержку. ([https://secure.php.net/manual/ru/pdo.installation.php Как собрать PHP с поддержкой SQLite], работающей посредством PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] â\80\94 Ñ\8dÑ\82о ÐºÐ¾Ð¼Ð¼ÐµÑ\80Ñ\87еÑ\81каÑ\8f ÐºÐ¾Ñ\80поÑ\80аÑ\82ивнаÑ\8f Ð±Ð°Ð·Ð° Ð´Ð°Ð½Ð½Ñ\8bÑ\85. ([https://secure.php.net/manual/ru/oci8.installation.php Как собрать PHP с поддержкой OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] â\80\94 Ñ\8dÑ\82о ÐºÐ¾Ð¼Ð¼ÐµÑ\80Ñ\87еÑ\81каÑ\8f ÐºÐ¾Ñ\80поÑ\80аÑ\82ивнаÑ\8f Ð±Ð°Ð·Ð° Ð´Ð°Ð½Ð½Ñ\8bÑ\85 Ð´Ð»Ñ\8f Windows. ([https://secure.php.net/manual/ru/sqlsrv.installation.php Как собрать PHP с поддержкой SQLSRV])",
        "config-header-mysql": "Настройки MySQL",
        "config-header-postgres": "Настройки PostgreSQL",
        "config-header-sqlite": "Настройки SQLite",
        "config-license-help": "Многие общедоступные вики разрешают использовать свои материалы на условиях [https://freedomdefined.org/Definition/Ru свободных лицензий].\nЭто помогает созданию чувства общности, стимулирует долгосрочное участие.\nНо в этом нет необходимости для частных или корпоративных вики.\n\nЕсли вы хотите использовать тексты из Википедии или хотите, что в Википедию можно было копировать тексты из вашей вики, вам следует выбрать <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nВикипедия ранее использовала лицензию GNU Free Documentation License.\nGFDL может быть использована, но она сложна для понимания и осложняет повторное использование материалов.",
        "config-email-settings": "Настройки электронной почты",
        "config-enable-email": "Включить исходящие e-mail",
-       "config-enable-email-help": "Ð\95Ñ\81ли Ð²Ñ\8b Ñ\85оÑ\82иÑ\82е, Ñ\87Ñ\82обÑ\8b Ñ\8dлекÑ\82Ñ\80оннаÑ\8f Ð¿Ð¾Ñ\87Ñ\82а Ñ\80абоÑ\82ала, Ð½ÐµÐ¾Ð±Ñ\85одимо Ð²Ñ\8bполниÑ\82Ñ\8c [http://www.php.net/manual/ru/mail.configuration.php Ñ\81ооÑ\82веÑ\82Ñ\81Ñ\82вÑ\83Ñ\8eÑ\89ие Ð½Ð°Ñ\81Ñ\82Ñ\80ойки PHP].\nÐ\95Ñ\81ли Ð²Ñ\8b Ð½Ðµ Ñ\85оÑ\82иÑ\82е Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾Ñ\81Ñ\82и Ñ\8dлекÑ\82Ñ\80онной Ð¿Ð¾Ñ\87Ñ\82Ñ\8b Ð² Ð²Ð¸ÐºÐ¸, Ð²Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е ÐµÑ\91 отключить.",
+       "config-enable-email-help": "Ð\95Ñ\81ли Ð²Ñ\8b Ñ\85оÑ\82иÑ\82е, Ñ\87Ñ\82обÑ\8b Ñ\8dлекÑ\82Ñ\80оннаÑ\8f Ð¿Ð¾Ñ\87Ñ\82а Ñ\80абоÑ\82ала, Ð½ÐµÐ¾Ð±Ñ\85одимо Ð¿Ñ\80авилÑ\8cно Ð½Ð°Ñ\81Ñ\82Ñ\80оиÑ\82Ñ\8c [https://secure.php.net/manual/ru/mail.configuration.php Ñ\80абоÑ\82Ñ\83 Ð¿Ð¾Ñ\87Ñ\82Ñ\8b Ð² PHP].\nÐ\95Ñ\81ли Ð²Ñ\8b Ð½Ðµ Ñ\85оÑ\82иÑ\82е Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾Ñ\81Ñ\82и Ñ\8dлекÑ\82Ñ\80онной Ð¿Ð¾Ñ\87Ñ\82Ñ\8b, Ð²Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е ÐµÑ\91 Ð·Ð´ÐµÑ\81Ñ\8c отключить.",
        "config-email-user": "Включить электронную почту от участника к участнику",
        "config-email-user-help": "Разрешить всем пользователям отправлять друг другу электронные письма, если выставлена соответствующая настройка в профиле.",
        "config-email-usertalk": "Включить уведомления пользователей о сообщениях на их странице обсуждения",
index 292e636..d0e3dc8 100644 (file)
@@ -61,9 +61,9 @@
        "config-pcre-no-utf8": "<strong>Fatal:</strong> PHP's PCRE module seems tae be compiled wioot PCRE_UTF8 support.\nMediaWiki requires UTF-8 support tae function correctly.",
        "config-memory-raised": "PHP's <code>memerie_limit</code> is $1, raised til $2.",
        "config-memory-bad": "<strong>Warnishment:</strong> PHP's <code>memerie_limit</code> is $1.\nThis is proably ower low.\nThe installation micht fail!",
-       "config-apc": "[http://www.php.net/apc APC] is installed.",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] is instawed.",
-       "config-no-cache-apcu": "<strong>Wairnin:</strong> Could nae find [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] or [http://www.iis.net/download/WinCacheForPhp WinCache].\nObject cachin isna enabled.",
+       "config-apc": "[https://secure.php.net/apc APC] is installed.",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] is instawed.",
+       "config-no-cache-apcu": "<strong>Wairnin:</strong> Could nae find [https://secure.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] or [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nObject cachin isna enabled.",
        "config-mod-security": "<strong>Warnishment:</strong> Yer wab server haes [https://modsecurity.org/ mod_security] enabled. Gif misconfeegured, it can cause problems fer MediaWiki or ither saffware that allous uisers tae post arbitrie content.\nRefer til [https://modsecurity.org/documentation/ mod_security documentation] or contact yer host's support gif ye encounter random mistaks.",
        "config-diff3-bad": "GNU diff3 naw foond.",
        "config-git": "Foond the Git version control saffware: <code>$1</code>.",
        "config-type-mysql": "MaSQL (or compâtible)",
        "config-type-mssql": "Micræsaff SQL Server",
        "config-support-info": "MediaWiki supports the follaein database systems:\n\n$1\n\nGif ye dinna see the database system ye'r tryin tae uise listed ablow, than follae the instructions linked abuin tae enable support.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] is the primarie tairget fer MediaWiki n is best supported. MediaWiki warks forby wi [{{int:version-db-mariadb-url}} MariaDB] n [{{int:version-db-percona-url}} Percona Server], thir ar MySQL compatible. ([http://www.php.net/manual/en/mysqli.installation.php Hou tae compile PHP wi MySQL support])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] is ae popular apen soorce database system aes aen alternative til MySQL. Thaur micht be some wee bugs still hingin roond, n it's na recommendit fer uiss in ae production environment. ([http://www.php.net/manual/en/pgsql.installation.php Hou tae compile PHP wi PostgreSQL support])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] is the primarie tairget fer MediaWiki n is best supported. MediaWiki warks forby wi [{{int:version-db-mariadb-url}} MariaDB] n [{{int:version-db-percona-url}} Percona Server], thir ar MySQL compatible. ([https://secure.php.net/manual/en/mysqli.installation.php Hou tae compile PHP wi MySQL support])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] is ae popular apen soorce database system aes aen alternative til MySQL. Thaur micht be some wee bugs still hingin roond, n it's na recommendit fer uiss in ae production environment. ([https://secure.php.net/manual/en/pgsql.installation.php Hou tae compile PHP wi PostgreSQL support])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] is ae lichtweicht database system that is ver weel supportit. ([http://www.php.net/manual/en/pdo.installation.php Hou tae compile PHP wi SQLite support], uises PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] is ae commercial enterprise database. ([http://www.php.net/manual/en/oci8.installation.php Hou tae compile PHP wi OCI8 support])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] is ae commercial enterprise database fer Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Hou tae compile PHP wi SQLSRV support])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] is ae commercial enterprise database fer Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Hou tae compile PHP wi SQLSRV support])",
        "config-header-mysql": "MaSQL settins",
        "config-header-postgres": "PostgreSQL settins",
        "config-header-sqlite": "SQLite settins",
        "config-license-help": "Monie publeec wikis pit aw contreebutions unner ae [https://freedomdefined.org/Defineetion free license].\nThis heelps tae creaut ae sense o communitie ainership n encoorages lang-term contreebution.\nIt's naw generallie necessair fer ae preevate or corporate wiki.\n\nGif ye wish tae be able tae uise tex fae Wikipædia, n ye want Wikipædia tae be able tae accept tex copied fae yer wiki, than ye shid chuise <strong>Creative Commons Attribution Shair Alike</strong>.\n\nWikipædia preeveeooslie uised the GNU Free Documentation License.\nThe GFDL is ae valid license, but it's difficult tae unnerstaunn.\nMairower, it's difficult tae reuise content licensed unner the GFDL.",
        "config-email-settings": "Wab-mail settins",
        "config-enable-email": "Enable ootboond wab-mail",
-       "config-enable-email-help": "Gif ye want wab-mail tae wark, [http://www.php.net/manual/en/mail.configuration.php PHP's mail settins] need tae be confeegured jyst richt.\nGif ye dinna want oni wab-mail features, ye can disable theim here.",
+       "config-enable-email-help": "Gif ye want wab-mail tae wark, [Config-dbsupport-oracle/manual/en/mail.configuration.php PHP's mail settins] need tae be confeegured jyst richt.\nGif ye dinna want oni wab-mail features, ye can disable theim here.",
        "config-email-user": "Enable uiser-til-uiser wab-mail",
        "config-email-user-help": "Permit aw uisers tae send each ither wab-mail gif they'v enabled it in their preferences.",
        "config-email-usertalk": "Enable uiser tauk page notifeecâtion",
index 0bd079b..7e110c2 100644 (file)
@@ -51,8 +51,8 @@
        "config-env-hhvm": "HHVM $1 je nameščen.",
        "config-unicode-using-intl": "Uporaba [https://pecl.php.net/intl razširitve PECL intl] za normalizacijo unikoda.",
        "config-memory-raised": "PHP-jev <code>memory_limit</code> je $1, dvignjen na $2.",
-       "config-apc": "[http://www.php.net/apc APC] je nameščen",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] je nameščen",
+       "config-apc": "[https://secure.php.net/apc APC] je nameščen",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] je nameščen",
        "config-diff3-bad": "GNU diff3 ni bilo mogoče najti.",
        "config-using-server": "Uporabljam ime strežnika \"<nowiki>$1</nowiki>\".",
        "config-using-uri": "Uporabljam URL strežnika \"<nowiki>$1$2</nowiki>\".",
index 30e2b9a..015b6ff 100644 (file)
@@ -47,8 +47,8 @@
        "config-env-bad": "Окружење је проверено.\nНе можете инсталирати Медијавики.",
        "config-env-php": "PHP $1 је инсталиран.",
        "config-env-hhvm": "HHVM $1 је инсталиран.",
-       "config-apc": "[http://www.php.net/apc APC] је инсталиран",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] је инсталиран",
+       "config-apc": "[https://secure.php.net/apc APC] је инсталиран",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] је инсталиран",
        "config-db-type": "Тип базе података:",
        "config-db-host": "Хост базе података",
        "config-db-wiki-settings": "Идентификуј овај вики",
index ba2822c..400b959 100644 (file)
        "config-pcre-no-utf8": "'''Kritiskt:''' PHP:s PCRE-modul verkar vara kompilerat utan PCRE_UTF8-stöd.\nMediaWiki kräver stöd för UTF-8 för att fungera korrekt.",
        "config-memory-raised": "PHPs <code>memory_limit</code> är $1, ökad till $2.",
        "config-memory-bad": "''' Varning:''' PHP:s <code>memory_limit</code> är $1.\nDetta är förmodligen för lågt.\nInstallationen kan misslyckas!",
-       "config-apc": "[http://www.php.net/apc APC] är installerat",
-       "config-apcu": "[http://www.php.net/apcu APCu] är installerat",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] är installerat",
-       "config-no-cache-apcu": "<strong>Varning:</strong> Kunde inte hitta [http://www.php.net/apcu APCu] eller [http://www.iis.net/download/WinCacheForPhp WinCache].\nCachelagring av objekt är inte aktiverat.",
+       "config-apc": "[https://secure.php.net/apc APC] är installerat",
+       "config-apcu": "[https://secure.php.net/apcu APCu] är installerat",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] är installerat",
+       "config-no-cache-apcu": "<strong>Varning:</strong> Kunde inte hitta [https://secure.php.net/apcu APCu] eller [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nCachelagring av objekt är inte aktiverat.",
        "config-mod-security": "'''Varning:''' Din webbserver har [https://modsecurity.org/ mod_security] aktiverat. Om felaktigt konfigurerat kan den skapa problem för MediaWiki eller annan programvara som tillåter användaren att posta godtyckligt innehåll.\nTitta på [https://modsecurity.org/documentation/ mod_security-dokumentationen] eller kontakta din värd om du påträffar slumpmässiga fel.",
        "config-diff3-bad": "GNU diff3 hittades inte.",
        "config-git": "Hittade Git-mjukvara för versionskontroll: <code>$1</code>.",
        "config-type-mysql": "MySQL (eller kompatibelt)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki stöder följande databassystem:\n\n$1\n\nOm du inte ser det databassystem som du försöker använda nedanstående, följ då instruktionerna länkade ovan för aktivera stöd för det.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] är det primära målet för MediaWiki och det stöds bäst. MediaWiki fungerar även med [{{int:version-db-mariadb-url}} MariaDB] och [{{int:version-db-percona-url}} Percona Server], som är kompatibla med MySQL. ([http://www.php.net/manual/en/mysqli.installation.php Hur man kompilerar PHP med stöd för MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] är ett populärt databassystem med öppen källkod som ett alternativ till MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Hur man kompilerar PHP med PostgreSQL stöd])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] är en lättviktsdatabassystem med väldigt bra stöd. ([http://www.php.net/manual/en/pdo.installation.php Hur man kompilerar PHP med SQLite stöd], använder PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] är en kommersiellt databas för företag. ([http://www.php.net/manual/en/oci8.installation.php Hur man kompilerar PHP med OCI8 stöd])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] är en kommersiellt databas för företag för Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Hur man kompilerar PHP med SQLSRV stöd])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] är det primära målet för MediaWiki och det stöds bäst. MediaWiki fungerar även med [{{int:version-db-mariadb-url}} MariaDB] och [{{int:version-db-percona-url}} Percona Server], som är kompatibla med MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Hur man kompilerar PHP med stöd för MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] är ett populärt databassystem med öppen källkod som ett alternativ till MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Hur man kompilerar PHP med PostgreSQL-stöd])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] är en lättviktsdatabassystem med väldigt bra stöd. ([https://secure.php.net/manual/en/pdo.installation.php Hur man kompilerar PHP med SQLite stöd], använder PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] är en kommersiellt databas för företag. ([https://secure.php.net/manual/en/oci8.installation.php Hur man kompilerar PHP med OCI8 stöd])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] är en kommersiellt databas för företag för Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Hur man kompilerar PHP med SQLSRV stöd])",
        "config-header-mysql": "MySQL-inställningar",
        "config-header-postgres": "PostgreSQL-inställningar",
        "config-header-sqlite": "SQLite-inställningar",
        "config-license-help": "Många publika wikis släpper alla bidrag under en  [https://freedomdefined.org/Definition fri licens].\nDetta bidrar till en känsla av gemensamt ägandeskap och uppmuntrar till långsiktiga bidrag.\nDet är i allmänhet inte nödvändigt för en privat eller företagswiki.\n\nOm du vill kunna använda text från Wikipedia, och du vill att Wikipedia ska kunna acceptera text kopierad ifrån din wiki bör du välja <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipedia använde tidigare  GNU Free Documentation License.\nGFDL är en giltig licens, men svår att förstå.\nDet är även svårt att återanvända innehåll som licensierats under GFDL.",
        "config-email-settings": "E-postinställningar",
        "config-enable-email": "Aktivera utgående e-post",
-       "config-enable-email-help": "Om du vill att e-post ska fungera behöver,[http://www.php.net/manual/en/mail.configuration.php PHPs e-postinställningar] vara konfigurerad på rätt sätt.\nOm du inte vill ha några e-postfunktioner, kan du inaktivera dem här.",
+       "config-enable-email-help": "Om du vill att e-post ska fungera behöver,[Config-dbsupport-oracle/manual/en/mail.configuration.php PHPs e-postinställningar] vara konfigurerad på rätt sätt.\nOm du inte vill ha några e-postfunktioner, kan du inaktivera dem här.",
        "config-email-user": "Aktivera e-post mellan användare",
        "config-email-user-help": "Tillåta alla användare att skicka e-post till varandra om de har aktiverat det i sina inställningar.",
        "config-email-usertalk": "Aktivera meddelanden för användardiskussionssidor",
index 9f7c531..ce949d1 100644 (file)
@@ -53,8 +53,8 @@
        "config-outdated-sqlite": "<strong>హెచ్చరిక:</strong> మీ వద్ద SQLite $1 ఉంది. అదికావలసిన వెర్షను $2 కంటే దిగువది. SQLite అందుబాటులో ఉండదు.",
        "config-memory-raised": "PHP యొక్క <code>memory_limit</code> $1, దాన్ని $2 కి పెంచాం.",
        "config-memory-bad": "<strong>హెచ్చరిక:</strong> PHP యొక్క <code>memory_limit</code> $1.\nబహుశా ఇది మరీ తక్కువ.\nస్థాపన విఫలం కావచ్చు!",
-       "config-apc": "[http://www.php.net/apc APC] స్థాపించబడింది",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] స్థాపించబడింది",
+       "config-apc": "[https://secure.php.net/apc APC] స్థాపించబడింది",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] స్థాపించబడింది",
        "config-diff3-bad": "GNU diff3 కనబడలేదు.",
        "config-no-uri": "<strong>లోపం:</strong> ప్రస్తుత URI ఏమిటో నిర్ధారించలేకపోయాం.\nస్థాపన ఆగిపోయింది.",
        "config-using-server": "సర్వరు పేరు \"<nowiki>$1</nowiki>\" ను వాడుతున్నాం.",
@@ -89,7 +89,7 @@
        "config-type-mysql": "MySQL (లేదా సరిపోయేది)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki కింది డేటాబేసు వ్యవస్థలకు అనుకూలిస్తుంది:\n\n$1\n\nమీరు వాడదలచిన డేటాబేసు వ్యవస్ కింది జాబితాలో లేకపోతే, పైన లింకు ద్వారా ఇచ్చిన సూచనలను పాటించి, అనుకూలతలను సాధించండి.",
-       "config-dbsupport-postgres": "* MySQL కు ప్రత్యామ్నాయంగా [{{int:version-db-postgres-url}} PostgreSQL] ప్రజామోదం పొందిన ఓపెన్‍సోర్సు డేటాబేసు వ్యవస్థ. దానిలో చిన్న చితకా లోపాలుండే అవకాశం ఉంది. అందుచేత దాన్ని ఉత్పాదక రంగంలో వాడవచ్చని చెప్పలేం.  ([http://www.php.net/manual/en/pgsql.installation.php How to compile PHP with PostgreSQL support])",
+       "config-dbsupport-postgres": "* MySQL కు ప్రత్యామ్నాయంగా [{{int:version-db-postgres-url}} PostgreSQL] ప్రజామోదం పొందిన ఓపెన్‍సోర్సు డేటాబేసు వ్యవస్థ. దానిలో చిన్న చితకా లోపాలుండే అవకాశం ఉంది. అందుచేత దాన్ని ఉత్పాదక రంగంలో వాడవచ్చని చెప్పలేం.  ([https://secure.php.net/manual/en/pgsql.installation.php How to compile PHP with PostgreSQL support])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] ఓ తేలికైన డేటాబేసు వ్యవస్థ. దానికి చక్కటి అనుకూలతలున్నాయి. ([http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], uses PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] ఒక వాణిజ్యపరంగా సంస్థాగతంగా వాడదగ్గ డేటాబేసు. ([http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])",
        "config-header-mysql": "MySQL అమరికలు",
index ba398e5..4c3a32d 100644 (file)
        "config-pcre-no-utf8": "<strong>ข้อผิดพลาดร้ายแรง:</strong> โมดูล PCRE ของ PHP ดูเหมือนจะถูกคอมไพล์โดยไม่มีการรองรับ PCRE_UTF8\nMediaWiki ต้องการการรองรับ UTF-8 เพื่อให้ทำงานได้อย่างถูกต้อง",
        "config-memory-raised": "<code>memory_limit</code> ของ PHP คือ $1 ได้เพิ่มเป็น $2",
        "config-memory-bad": "<strong>คำเตือน:</strong> <code>memory_limit</code> ของ PHP คือ $1.\nเป็นไปได้ว่ามันอาจต่ำเกินไป\nการติดตั้งอาจล้มเหลวได้!",
-       "config-apc": "มี [http://www.php.net/apc APC] ติดตั้งอยู่",
-       "config-apcu": "มี [http://www.php.net/apcu APCu] ติดตั้งอยู่",
-       "config-wincache": "มี [https://www.iis.net/download/WinCacheForPhp WinCache] ติดตั้งอยู่",
-       "config-no-cache-apcu": "<strong>คำเตือน:</strong> ไม่พบ [http://www.php.net/apcu APCu] [http://xcache.lighttpd.net/ XCache] หรือ [http://www.iis.net/download/WinCacheForPhp WinCache]\nการแคชวัตถุไม่ได้ถูกเปิดใช้งาน",
+       "config-apc": "มี [https://secure.php.net/apc APC] ติดตั้งอยู่",
+       "config-apcu": "มี [https://secure.php.net/apcu APCu] ติดตั้งอยู่",
+       "config-wincache": "มี [https://www.iis.net/downloads/microsoft/wincache-extension WinCache] ติดตั้งอยู่",
+       "config-no-cache-apcu": "<strong>คำเตือน:</strong> ไม่พบ [https://secure.php.net/apcu APCu] [http://xcache.lighttpd.net/ XCache] หรือ [https://www.iis.net/downloads/microsoft/wincache-extension WinCache]\nการแคชวัตถุไม่ได้ถูกเปิดใช้งาน",
        "config-mod-security": "<strong>คำเตือน:</strong> เว็บเซิร์ฟเวอร์ของคุณมี [https://modsecurity.org/ mod_security]/mod_security2 เปิดใช้งานอยู่ การตั้งค่าทั่วไปหลายอย่างของสิ่งนี้จะก่อให้เกิดปัญหาสำหรับ MediaWiki และซอฟต์แวร์อื่นที่อนุญาตให้ผู้ใช้สามารถโพสต์เนื้อหาได้ตามที่ผู้ใช้\nหากเป็นไปได้ ควรปิดใช้งานคุณลักษณะนี้ หรือมิฉะนั้นก็ อ้างไปยัง[https://modsecurity.org/documentation/ เอกสารกำกับการใช้งาน mod_security] หรือติดต่อการสนับสนุนจากโฮสต์ของคุณ ถ้าคุณพบข้อผิดพลาดโดยสุ่ม",
        "config-diff3-bad": "ไม่พบ GNU diff3",
        "config-git": "พบซอฟต์แวร์ควบคุมรุ่น Git: <code>$1</code>",
        "config-type-mysql": "MySQL (หรือที่เข้ากันได้)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki สนับสนุนระบบฐานข้อมูลต่อไปนี้:\n\n$1\n\nถ้าคุณไม่พบระบบฐานข้อมูลที่คุณกำลังพยายามใช้ในรายการด้านล่างนี้ ให้ทำตามคำแนะนำที่เชื่อมโยงด้านบนเพื่อเปิดใช้งานการสนับสนุน",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] คือเป้าหมายหลักสำหรับ MediaWiki และได้รับการสนับสนุนดีที่สุด MediaWiki ยังคงสามารถใช้ได้ร่วมกับ [{{int:version-db-mariadb-url}} MariaDB] และ [{{int:version-db-percona-url}} Percona Server] ซึ่งเข้ากันได้กับ MySQL ([http://www.php.net/manual/en/mysqli.installation.php วิธีการคอมไพล์ PHP ด้วยการสนับสนุน MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] คือระบบฐานข้อมูลแบบโอเพนซอร์สที่ได้รับความนิยมสูงที่สามารถใช้แทน MySQL ได้ ([http://www.php.net/manual/en/pgsql.installation.php วิธีการคอมไพล์ PHP ด้วยการสนับสนุน PostgreSQL])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] คือเป้าหมายหลักสำหรับ MediaWiki และได้รับการสนับสนุนดีที่สุด MediaWiki ยังคงสามารถใช้ได้ร่วมกับ [{{int:version-db-mariadb-url}} MariaDB] และ [{{int:version-db-percona-url}} Percona Server] ซึ่งเข้ากันได้กับ MySQL ([https://secure.php.net/manual/en/mysqli.installation.php วิธีการคอมไพล์ PHP ด้วยการสนับสนุน MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] คือระบบฐานข้อมูลแบบโอเพนซอร์สที่ได้รับความนิยมสูงที่สามารถใช้แทน MySQL ได้ ([https://secure.php.net/manual/en/pgsql.installation.php วิธีการคอมไพล์ PHP ด้วยการสนับสนุน PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] คือระบบฐานข้อมูลขนาดเล็กที่ได้รับการสนับสนุนดีมาก ([http://www.php.net/manual/en/pdo.installation.php วิธีการคอมไพล์ PHP ด้วยการสนับสนุน SQLite], ใช้ PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] คือฐานข้อมูลสำหรับองค์กรพาณิชย์ ([http://www.php.net/manual/en/oci8.installation.php วิธีการคอมไพล์ PHP ด้วยการสนับสนุน OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] คือฐานข้อมูลสำหรับองค์กรพาณิชย์สำหรับ Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php วิธีการคอมไพล์ PHP ด้วยการสนับสนุน SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] คือฐานข้อมูลสำหรับองค์กรพาณิชย์สำหรับ Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php วิธีการคอมไพล์ PHP ด้วยการสนับสนุน SQLSRV])",
        "config-header-mysql": "การตั้งค่า MySQL",
        "config-header-postgres": "การตั้งค่า PostgreSQL",
        "config-header-sqlite": "การตั้งค่า SQLite",
index 54a2016..ab6632f 100644 (file)
@@ -63,8 +63,8 @@
        "config-pcre-no-utf8": "'''Malubha''': Tila tinipon ang modyul na PCRE ng PHP na wala ang suporta ng PCRE_UTF8.\nNangangailangan ang MediaWiki ng suporta ng UTF-8 upang maging tama ang pag-andar.",
        "config-memory-raised": "Ang <code>hangganan_ng_alaala</code> ng PHP ay $1, itinaas sa $2.",
        "config-memory-bad": "'''Babala:''' Ang <code>hangganan_ng_alaala</code> ng PHP ay $1.\nIto ay maaaring napakababa.\nMaaaring mabigo ang pagluluklok!",
-       "config-apc": "Ininstala na ang [http://www.php.net/apc APC]",
-       "config-wincache": "Ininstala na ang [https://www.iis.net/download/WinCacheForPhp WinCache]",
+       "config-apc": "Ininstala na ang [https://secure.php.net/apc APC]",
+       "config-wincache": "Ininstala na ang [https://www.iis.net/downloads/microsoft/wincache-extension WinCache]",
        "config-mod-security": "'''Babala''': Ang tagapaghain mo ng sangkasaputan ay pinagana na mayroong [https://modsecurity.org/ mod_security]. Kung mali ang kaayusan, makapagdurulot ito ng mga suliranin para sa MediaWiki o ibang mga sopwer na nagpapahintulot sa mga tagagamit na magpaskil ng hindi makatwirang nilalaman.\nSumangguni sa [https://modsecurity.org/documentation/ mod_security kasulatan] o makipag-ugnayan sa suporta ng iyong tagapagpasinaya kapag nakatagpo ng alin mang mga kamalian.",
        "config-diff3-bad": "Hindi natagpuan ang GNU diff3.",
        "config-imagemagick": "Natagpuan ang ImageMagick: <code>$1</code>.\nPapaganahin ang pagkakagyat ng larawan kapag pinagana mo ang mga pagkakargang paitaas.",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-support-info": "Sinusuportahan ng MediaWiki ang sumusunod na mga sistema ng kalipunan ng dato:\n\n$1\n\nKung hindi mo makita ang sistema ng kalipunan ng dato na sinusubukan mong gamitin na nakatala sa ibaba, kung gayon ay sundi ang mga tagubilin na nakakawing sa itaas upang mapagana ang suporta,",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] ang pangunahing puntirya para sa MediaWiki at ang pinaka sinusuportahan. Gumagana rin ang MediaWiki [{{int:version-db-mariadb-url}} MariaDB] at sa [{{int:version-db-percona-url}} Percona Server], na tugma sa MySQL.  ([http://www.php.net/manual/en/mysql.installation.php Paano magtipon ng PHP na mayroong suporta ng MySQL])",
-       "config-dbsupport-postgres": "* Ang [{{int:version-db-postgres-url}} PostgreSQL] 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]).",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] ang pangunahing puntirya para sa MediaWiki at ang pinaka sinusuportahan. Gumagana rin ang MediaWiki [{{int:version-db-mariadb-url}} MariaDB] at sa [{{int:version-db-percona-url}} Percona Server], na tugma sa MySQL.  ([https://secure.php.net/manual/en/mysql.installation.php Paano magtipon ng PHP na mayroong suporta ng MySQL])",
+       "config-dbsupport-postgres": "* Ang [{{int:version-db-postgres-url}} PostgreSQL] ay isang bantog na sistema ng kalipunan ng dato na bukas ang pinagmulan na panghalili sa MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Paano magtipon ng PHP na mayroong suporta ng PostgreSQL]).",
        "config-dbsupport-sqlite": "* Ang [{{int:version-db-sqlite-url}} SQLite] 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-dbsupport-oracle": "* Ang [{{int:version-db-oracle-url}} Oracle] 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-header-mysql": "Mga katakdaan ng MySQL",
        "config-license-help": "Maraming mga pangmadlang wiki ang naglalagay ng lahat ng mga ambag sa ilalim ng [https://freedomdefined.org/Definition lisensiyang malaya].\nNakakatulong ito sa paglikha ng isang diwa ng pagmamay-ari ng pamayanan at nakapanghihikayat ng ambag na pangmahabang panahon.\nSa pangkalahatan, hindi kailangan ang isang wiking pribado o pangsamahan.\n\nKung nais mong magamit ang teksto magmula sa Wikipedia, at nais mong makatanggap ang Wikipedia ng tekstong kinopya magmula sa wiki mo, dapat mong piliin ang <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nDating ginamit ng Wikipedia ang Lisensiya ng Kasulatang Malaya ng GNU (GNU Free Documentation License o GFDL).\nIsang katanggap-tanggap na lisensiya ang GFDL, subalit mahirap itong maunawaan.\nMahirap din ang paggamit na muli ng nilalaman na nasa ilalim ng GFDL.",
        "config-email-settings": "Mga katakdaan ng e-liham",
        "config-enable-email": "Paganahin ang palabas na e-liham",
-       "config-enable-email-help": "Kung nais mong gumana ang e-liham, ang mga katakdaan ng liham ng [http://www.php.net/manual/en/mail.configuration.php PHP] ay kailangang maging wasto ang pagkakaayos.\nKung ayaw mo nang anumang mga katampukan ng e-liham, maaari mong huwag paganahin ang mga ito rito.",
+       "config-enable-email-help": "Kung nais mong gumana ang e-liham, ang mga katakdaan ng liham ng [Config-dbsupport-oracle/manual/en/mail.configuration.php PHP] ay kailangang maging wasto ang pagkakaayos.\nKung ayaw mo nang anumang mga katampukan ng e-liham, maaari mong huwag paganahin ang mga ito rito.",
        "config-email-user": "Paganahin ang tagagamit-sa-tagagamit na e-liham",
        "config-email-user-help": "Payagan ang lahat ng mga tagagamit na magpadala ng e-liham sa bawat isa kapag pinagana nila ito sa kanilang mga nais.",
        "config-email-usertalk": "Paganahin ang pabatid na pampahina ng usapan ng tagagamit",
index 6d94297..9f63ba8 100644 (file)
        "config-pcre-no-utf8": "<strong>Önemli hata:</strong> PHP'nin PCRE modülü PCRE_UTF8 desteği olmadan derlenmiş gözüküyor.\nMediaWiki'nin doğru çalışabilmesi için UTF-8 desteği gereklidir.",
        "config-memory-raised": "PHP'nin <code>memory_limit</code> (hafıza sınırı) değeri $1, $2'ye yükseltildi.",
        "config-memory-bad": "<strong>Uyarı:</strong> PHP'nin <code>memory_limit</code> (hafıza sınırı) değeri $1.\nBu büyük ihtimalle çok düşük.\nKurulum başarısız olabilir!",
-       "config-apc": "[http://www.php.net/apc APC] kurulu",
-       "config-apcu": "[http://www.php.net/apcu APCu] yüklendi",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] kurulu",
-       "config-no-cache-apcu": "<strong>Uyarı:</strong> [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] ya da [http://www.iis.net/download/WinCacheForPhp WinCache] kurulumu bulunamadı.\nNesne önbellekleme etkin değil.",
+       "config-apc": "[https://secure.php.net/apc APC] kurulu",
+       "config-apcu": "[https://secure.php.net/apcu APCu] yüklendi",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] kurulu",
+       "config-no-cache-apcu": "<strong>Uyarı:</strong> [https://secure.php.net/apcu APCu] ya da [https://www.iis.net/downloads/microsoft/wincache-extension WinCache] kurulumu bulunamadı.\nNesne önbellekleme etkin değil.",
        "config-mod-security": "<strong>'''Uyarı:'''</strong> Web sunucunuz [https://modsecurity.org/mod_security2 mod_security] etkin. Bunun birçok yaygın yapılandırması bulunur ve eğer yanlış yapılandırılmış ise, bu MediaWiki ve kullanıcılara isteğe bağlı içerik göndermesine izin veren diğer yazılımlar için sorun oluşturabilir.\nMümkünse bu devre dışı bırakılmalıdır. Aksi takdirde rastgele hatalar alırsanız [https://modsecurity.org/documentation/ mod_security belgelemesine] bakın ya da sunucunuzun desteğine başvurun.",
        "config-diff3-bad": "GNU diff3 bulunamadı.",
        "config-git": "Sürüm kontrol yazılımı Git bulundu: <code>$1</code>.",
index acd1281..391e8ae 100644 (file)
@@ -27,8 +27,8 @@
        "config-page-upgradedoc": "Яңарту",
        "config-page-existingwiki": "Хәзерге вики",
        "config-restart": "Әйе, яңадан башларга",
-       "config-apc": "[http://www.php.net/apc APC] куелды",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] куелды",
+       "config-apc": "[https://secure.php.net/apc APC] куелды",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] куелды",
        "config-diff3-bad": "GNU diff3 табылмады.",
        "config-git": "Git юрамалар идарә итү системасы табылды: <code>$1</code>.",
        "config-db-type": "Мәгълүмат базасы төре:",
index f57bcd1..9d890f7 100644 (file)
        "config-pcre-no-utf8": "'''Помилка''': PCRE-модуть PHP, вочевидь, було зібрано без підтримки PCRE_UTF8.\nMediaWiki вимагає підтримку UTF-8 для коректної роботи.",
        "config-memory-raised": "Обмеження пам'яті PHP (<code>memory_limit</code>) $1, піднято до $2.",
        "config-memory-bad": "'''Увага:''' Розмір пам'яті PHP (<code>memory_limit</code>) становить $1.\nІмовірно, це замало.\nВстановлення може не вдатись!",
-       "config-apc": "[http://www.php.net/apc APC] встановлено",
-       "config-apcu": "[http://www.php.net/apcu APCu] встановлено",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] встановлено",
-       "config-no-cache-apcu": "<strong>Увага:</strong> Не вдалося знайти [http://www.php.net/apcu APCu] чи [http://www.iis.net/download/WinCacheForPhp WinCache].\nКешування об'єктів не ввімкнено.",
+       "config-apc": "[https://secure.php.net/apc APC] встановлено",
+       "config-apcu": "[https://secure.php.net/apcu APCu] встановлено",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] встановлено",
+       "config-no-cache-apcu": "<strong>Увага:</strong> Не вдалося знайти [https://secure.php.net/apcu APCu] чи [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nКешування об'єктів не ввімкнено.",
        "config-mod-security": "'''Увага''': на Вашому веб-сервері увімкнено [https://modsecurity.org/ mod_security]. У разі неправильних налаштувать, він може викликати проблеми MediaWiki або іншого ПЗ, яке дозволяє користувачам надсилати довільний вміст.\nЗверніться до [https://modsecurity.org/documentation/ документації mod_security] або підтримки Вашого хостера, якщо під час роботи виникають незрозумілі помилки.",
        "config-diff3-bad": "GNU diff3 не знайдено.",
        "config-git": "Знайшов програму управління версіями Git: <code>$1</code>.",
        "config-type-mysql": "MySQL (або сумісний)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki підтримує такі системи баз даних:\n\n$1\n\nЯкщо Ви не бачите серед перерахованих систему баз даних, яку використовуєте, виконайте вказівки, вказані вище, щоб увімкнути підтримку.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] є основною для MediaWiki і найкраще підтримується.  MediaWiki також працює із [{{int:version-db-mariadb-url}} MariaDB] та [{{int:version-db-percona-url}} Percona Server], які сумісні з MySQL.  ([http://www.php.net/manual/en/mysqli.installation.php як зібрати PHP з допомогою MySQL])",
-       "config-dbsupport-postgres": "*  [{{int:version-db-postgres-url}} PostgreSQL] — популярна відкрита СУБД, альтернатива MySQL. ([http://www.php.net/manual/en/pgsql.installation.php як зібрати PHP з допомогою PostgreSQL]).",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] є основною для MediaWiki і найкраще підтримується.  MediaWiki також працює із [{{int:version-db-mariadb-url}} MariaDB] та [{{int:version-db-percona-url}} Percona Server], які сумісні з MySQL.  ([https://secure.php.net/manual/en/mysqli.installation.php як зібрати PHP з допомогою MySQL])",
+       "config-dbsupport-postgres": "*  [{{int:version-db-postgres-url}} PostgreSQL] — популярна відкрита СУБД, альтернатива MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php як зібрати PHP з допомогою PostgreSQL]).",
        "config-dbsupport-sqlite": "*  [{{int:version-db-sqlite-url}} SQLite] — легка система баз даних, яка дуже добре підтримується. ([http://www.php.net/manual/en/pdo.installation.php Як зібрати PHP з допомогою SQLite], що використовує PDO)",
        "config-dbsupport-oracle": "*  [{{int:version-db-oracle-url}} Oracle] — комерційна база даних масштабу підприємства. ([http://www.php.net/manual/en/oci8.installation.php Як зібрати PHP з підтримкою OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] — це комерційна база даних для Windows масштабу підприємства. ([http://www.php.net/manual/ru/sqlsrv.installation.php Як зібрати PHP з підтримкою SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] — це комерційна база даних для Windows масштабу підприємства. ([https://secure.php.net/manual/en/sqlsrv.installation.php Як зібрати PHP з підтримкою SQLSRV])",
        "config-header-mysql": "Налаштування MySQL",
        "config-header-postgres": "Налаштування PostgreSQL",
        "config-header-sqlite": "Налаштування SQLite",
        "config-license-help": "Чимало загальнодоступних вікі публікують увесь свій вміст під [https://freedomdefined.org/Definition вільною ліцензією]. Це розвиває відчуття спільної власності і заохочує довготривалу участь. У загальному випадку для приватної чи корпоративної вікі у цьому немає необхідності.\n\nЯкщо Ви хочете мати змогу використовувати текст з Вікіпедії і дати Вікіпедії змогу використовувати текст, скопійований з Вашої вікі, вам необхідно обрати <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nРаніше Вікіпедія використовувала GNU Free Documentation License.\nGFDL — допустима ліцензія, але у ній важко розібратися, а контент під GFDL важко використовувати повторно.",
        "config-email-settings": "Налаштування електронної пошти",
        "config-enable-email": "Увімкнути вихідну електронну пошту",
-       "config-enable-email-help": "Якщо Ви хочете, що електронна пошта працювала, необхідно виставити коректні [http://www.php.net/manual/en/mail.configuration.php налаштування пошти у PHP].\nЯкщо Вам не потрібні жодні можливості електронної пошти у вікі, можете тут їх відключити.",
+       "config-enable-email-help": "Якщо Ви хочете, що електронна пошта працювала, необхідно виставити коректні [Config-dbsupport-oracle/manual/en/mail.configuration.php налаштування пошти у PHP].\nЯкщо Вам не потрібні жодні можливості електронної пошти у вікі, можете тут їх відключити.",
        "config-email-user": "Увімкнути електронну пошту користувач-користувачеві",
        "config-email-user-help": "Дозволити усім користувачам надсилати один одному електронну пошту, якщо вони увімкнули цю можливість у своїх налаштуваннях.",
        "config-email-usertalk": "Увімкнути сповіщення про повідомлення на сторінці обговорення користувача",
index 4b9da0e..1c2861a 100644 (file)
@@ -6,7 +6,8 @@
                        "Withoutaname",
                        "Dinhxuanduyet",
                        "Nguyên Lê",
-                       "Macofe"
+                       "Macofe",
+                       "Leducthn"
                ]
        },
        "config-desc": "Trình cài đặt MediaWiki",
        "config-pcre-no-utf8": "<strong>Lỗi chí tử:</strong> Mô đun PCRE của PHP dường như được biên dịch mà không có hỗ trợ PCRE_UTF8.\nMediaWiki yêu cầu phải có hỗ trợ UTF-8 để hoạt động chính xác.",
        "config-memory-raised": "<code>memory_limit</code> của PHP là $1, tăng lên $2.",
        "config-memory-bad": "<strong>Cảnh báo:</strong> <code>memory_limit</code> của PHP là $1.\nGiá trị này có lẽ quá thấp.\nCài đặt có thể bị thất bại!",
-       "config-apc": "[http://www.php.net/apc APC] đã được cài đặt",
-       "config-apcu": "[http://www.php.net/apcu APCu] đã được cài đặt",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] đã được cài đặt",
-       "config-no-cache-apcu": "<strong>Cảnh báo:</strong> Không tìm thấy [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache], hoặc [http://www.iis.net/download/WinCacheForPhp WinCache].\nVùng nhớ đệm đối tượng không được kích hoạt.",
+       "config-apc": "[https://secure.php.net/apc APC] đã được cài đặt",
+       "config-apcu": "[https://secure.php.net/apcu APCu] đã được cài đặt",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] đã được cài đặt",
+       "config-no-cache-apcu": "<strong>Cảnh báo:</strong> Không tìm thấy [https://secure.php.net/apcu APCu] hoặc [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nVùng nhớ đệm đối tượng không được kích hoạt.",
        "config-mod-security": "<strong>Cảnh báo:</strong> [https://modsecurity.org/ mod_security]/mod_security2 đã được kích hoạt trên máy chủ Web của bạn. Nhiều cấu hình phổ biến của phần mềm này sẽ gây vấn đề cho MediaWiki và những phần mềm khác cho phép người dùng đăng các nội dung tùy tiện.\nNếu có thể, bạn nên vô hiệu nó. Còn không, tra cứu [https://modsecurity.org/documentation/ tài liệu mod_security] hoặc liên hệ với nhà cung cấp hỗ trợ cho máy chủ nếu bạn gặp những lỗi ngẫu nhiên nào đó.",
        "config-diff3-bad": "Không tìm thấy GNU diff3.",
        "config-git": "Đã tìm thấy phần mềm điều khiển phiên bản Git: <code>$1</code>.",
        "config-type-mysql": "MySQL (hoặc tương hợp)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki hỗ trợ các hệ thống cơ sở dữ liệu sau đây:\n\n$1\n\nNếu bạn không thấy hệ thống cơ sở dữ liệu mà bạn đang muốn sử dụng được liệt kê dưới đây, thì hãy theo chỉ dẫn được liên kết ở trên để kích hoạt tính năng hỗ trợ.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] là mục tiêu chính cho MediaWiki và được hỗ trợ tốt nhất. MediaWiki cũng làm việc với [{{int:version-db-mariadb-url}} MariaDB] và [{{int:version-db-percona-url}} Percona Server], là những cơ sở dữ liệu tương thích với MySQL. ([http://www.php.net/manual/en/mysqli.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] là một hệ thống cơ sở dữ liệu mã nguồn mở phổ biến như là một thay thế cho MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] là một hệ thống cơ sở dữ liệu dung lượng nhẹ được hỗ trợ rất tốt. ([http://www.php.net/manual/en/pdo.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của SQLite], sử dụng PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] là một cơ sở dữ liệu doanh nghiệp thương mại. ([http://www.php.net/manual/en/oci8.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] là một cơ sở dữ liệu doanh nghiệp thương mại cho Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của SQLSRV])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] là mục tiêu chính cho MediaWiki và được hỗ trợ tốt nhất. MediaWiki cũng làm việc với [{{int:version-db-mariadb-url}} MariaDB] và [{{int:version-db-percona-url}} Percona Server], là những cơ sở dữ liệu tương thích với MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] là một hệ thống cơ sở dữ liệu mã nguồn mở phổ biến như là một thay thế cho MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của PostgreSQL])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] là một hệ thống cơ sở dữ liệu dung lượng nhẹ được hỗ trợ rất tốt. ([https://secure.php.net/manual/en/pdo.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của SQLite], sử dụng PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] là một cơ sở dữ liệu doanh nghiệp thương mại. ([https://secure.php.net/manual/en/oci8.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] là một cơ sở dữ liệu doanh nghiệp thương mại cho Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của SQLSRV])",
        "config-header-mysql": "Thiết lập MySQL",
        "config-header-postgres": "Thiết lập PostgreSQL",
        "config-header-sqlite": "Thiết lập SQLite",
        "config-license-help": "Nhiều wiki công khai phát hành tất cả các đóng góp theo một [https://freedomdefined.org/Definition/Vi?uselang=vi giấy phép tự do].\nĐiều này giúp tạo nên thái độ cộng đồng sở hữu và ủng hộ sự đóng góp lâu dài.\nNói chung, một wiki riêng tư hoặc của công ty không nhất thiết phải sử dụng một giấy phép tự do.\n\nNếu bạn muốn được phép sử dụng văn bản từ Wikipedia và muốn Wikipedia nhận được những văn bản được sao chép từ wiki của bạn, bạn nên chọn <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipedia từng sử dụng Giấy phép Tài liệu Tự do GNU.\nGFDL là một giấy phép hợp lệ nhưng khó hiểu trên thực tế.\nNội dung được phát hành theo GFDL cũng khó tái sử dụng.",
        "config-email-settings": "Thiết lập thư điện tử",
        "config-enable-email": "Cho phép gửi thư điện tử đi",
-       "config-enable-email-help": "Nếu bạn muốn khả năng gửi thư điện tử, [http://www.php.net/manual/en/mail.configuration.php thiết lập mail của PHP] cần phải được cấu hình đúng.\nNếu bạn không muốn sử dụng bất kỳ tính năng thư điện tử nào, bạn có thể vô hiệu chúng ở đây.",
+       "config-enable-email-help": "Nếu bạn muốn khả năng gửi thư điện tử, [https://secure.php.net/manual/en/mail.configuration.php thiết lập mail của PHP] cần phải được cấu hình đúng.\nNếu bạn không muốn sử dụng bất kỳ tính năng thư điện tử nào, bạn có thể vô hiệu chúng ở đây.",
        "config-email-user": "Cho phép người dùng gửi thư điện tử cho người dùng khác",
        "config-email-user-help": "Cho phép tất cả người dùng gửi thư điện tử cho nhau, nếu họ đã kích hoạt nó trong cài đặt tùy chọn của họ.",
        "config-email-usertalk": "Gửi thư thông báo về tin nhắn mới",
        "config-cache-options": "Thiết lập bộ nhớ đệm đối tượng:",
        "config-cache-help": "Lưu vào bộ nhớ đệm đối tượng được sử dụng để cải thiện tốc độ của MediaWiki bằng cách lưu vào bộ nhớ đệm những dữ liệu thường xuyên sử dụng.\nCác trang web từ trung bình cho đến các trang web lớn rất được khuyến khích kích hoạt tính năng này, và các trang web nhỏ cũng sẽ nhìn thấy lợi ích tương tự.",
        "config-cache-none": "Không lưu vào bộ nhớ đệm (không có chức năng nhiệm vụ sẽ được loại bỏ, nhưng tốc độ có thể bị ảnh hưởng trên các trang web wiki lớn hơn)",
-       "config-cache-accel": "Bộ nhớ đệm đối tượng PHP (APC, APCu, XCache, hoặc WinCache)",
+       "config-cache-accel": "Bộ nhớ đệm đối tượng PHP (APC, APCu, hoặc WinCache)",
        "config-cache-memcached": "Sử dụng Memcached (cần thiết lập và cấu hình thêm)",
        "config-memcached-servers": "Máy chủ Memcached:",
        "config-memcached-help": "Danh sách các địa chỉ IP để sử dụng cho Memcached .\nNên xác định trên một dòng và chỉ định các cổng được sử dụng. Ví dụ:\n 127.0.0.1:11211\n 192.168.1.25:1234",
        "config-install-mainpage-failed": "Không thể chèn trang đầu: $1",
        "config-install-done": "<strong>Xin chúc mừng!</strong>\nBạn đã cài đặt MediaWiki.\n\nBộ cài đặt đã tạo ra một tập tin <code>LocalSettings.php</code>.\nTập tin này chứa tất cả các cấu hình của bạn.\n\nBạn sẽ cần phải tải nó về và đặt nó trong thư mục cài đặt wiki của bạn (cùng thư mục với index.php). Việc tải về có lẽ sẽ được khởi động tự động.\n\nNếu bản tải về không được cung cấp, hoặc nếu bạn hủy bỏ nó, bạn có thể khởi động lại tải về bằng cách nhấn vào liên kết dưới đây:\n\n$3\n\n<strong>Lưu ý:</strong> Nếu bạn không làm điều này ngay bây giờ, điều này sẽ tạo ra tập tin cấu hình sẽ không có giá trị cho bạn sau này nếu bạn thoát khỏi trình cài đặt mà không tải nó về.\n\nKhi đã việc tải về đã hoàn thành, bạn có thể <strong>[$2 truy cập trang wiki của bạn]</strong>.",
        "config-install-done-path": "<strong>Xin chúc mừng!</strong>\nBạn đã cài đặt MediaWiki.\n\nBộ cài đặt đã tạo ra một tập tin <code>LocalSettings.php</code>.\nTập tin này chứa tất cả các cấu hình của bạn.\n\nBạn sẽ cần phải tải nó về và đặt nó tại <code>$4</code>. Việc tải về có lẽ sẽ được khởi động tự động.\n\nNếu bản tải về không được cung cấp, hoặc nếu bạn hủy bỏ nó, bạn có thể khởi động lại tải về bằng cách nhấn vào liên kết dưới đây:\n\n$3\n\n<strong>Lưu ý:</strong> Nếu bạn không làm điều này ngay bây giờ, điều này sẽ tạo ra tập tin cấu hình sẽ không có giá trị cho bạn sau này nếu bạn thoát khỏi trình cài đặt mà không tải nó về.\n\nKhi đã việc tải về đã hoàn thành, bạn có thể <strong>[$2 truy cập trang wiki của bạn]</strong>.",
+       "config-install-success": "MediaWiki đã được cài đặt thành công. Bây giờ bạn có thể mở <$1$2> để xem wiki của bạn.\nNếu bạn có thắc mắc, hãy đọc các câu thường hỏi:\n<https://www.mediawiki.org/wiki/Manual:FAQ?uselang=vi> hoặc ghé vào một diễn đàn hỗ trợ được liệt kê tại trang đó.",
        "config-download-localsettings": "Tải về <code>LocalSettings.php</code>",
        "config-help": "Trợ giúp",
        "config-help-tooltip": "nhấn chuột để mở rộng",
        "config-nofile": "Không tìm thấy tập tin “$1”. Nó có phải bị xóa không?",
        "config-extension-link": "Bạn có biết rằng wiki của bạn có hỗ trợ [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions mở rộng]?\n\nBạn có thể truy cập [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category phần mở rộng theo thể loại] hoặc [https://www.mediawiki.org/wiki/Extension_Matrix Ma trận Mở rộng] để xem danh sách đầy đủ các phần mở rộng.",
        "config-skins-screenshots": "$1 (ảnh chụp màn hình: $2)",
+       "config-extensions-requires": "$1 (cần $2)",
        "config-screenshot": "ảnh chụp màn hình",
        "mainpagetext": "'''MediaWiki đã được cài đặt.'''",
        "mainpagedocfooter": "Xin đọc [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Hướng dẫn sử dụng] để biết thêm thông tin về cách sử dụng phần mềm wiki.\n\n== Để bắt đầu ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Danh sách các thiết lập cấu hình]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Các câu hỏi thường gặp MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Danh sách gửi thư về việc phát hành MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Tìm hiểu cách chống spam tại wiki của bạn]"
index 75d2350..c598a0b 100644 (file)
@@ -83,7 +83,7 @@
        "config-profile-fishbowl": "Otorisado nga mga editor la",
        "config-profile-private": "Pribado nga wiki",
        "config-license-pd": "Dominyo Publiko",
-       "config-enable-email-help": "Kun naruruyag ka nga gumana an email, an [http://www.php.net/manual/en/mail.configuration.php PHP's mail settings] in kinahanglan nga mai-configure hin asya.\nKun diri ka naruruyag hin bisan ano nga mga email feature, puydi nim igparong dinhi.",
+       "config-enable-email-help": "Kun naruruyag ka nga gumana an email, an [Config-dbsupport-oracle/manual/en/mail.configuration.php PHP's mail settings] in kinahanglan nga mai-configure hin asya.\nKun diri ka naruruyag hin bisan ano nga mga email feature, puydi nim igparong dinhi.",
        "config-email-user": "Igpaandar an gumaramit-ha-gumaramit nga email",
        "config-email-user-help": "Igtugot an ngatanan nga mga gumaramit nga magpadangat hin email ha tagsa-tagsa kun ira ginpaandar ini ha ira karuyagon.",
        "config-email-usertalk": "Igpaandar an pagpasabot ha pakli han hiruhimangraw han gumaramit",
index fe32b22..f85ef6e 100644 (file)
@@ -39,8 +39,8 @@
        "config-env-bad": "מ'האט קאנטראלירט די סביבה.\nאיר קענט נישט אינסטאלירן מעדיעוויקי.",
        "config-env-php": "PHP $1 איז אינצטאלירט.",
        "config-env-hhvm": "HHVM $1 איז אינסטאלירט.",
-       "config-apc": "[http://www.php.net/apc APC] איז אינסטאלירט",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] איז אינסטאלירט",
+       "config-apc": "[https://secure.php.net/apc APC] איז אינסטאלירט",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] איז אינסטאלירט",
        "config-diff3-bad": "GNU diff3 נישט געטראפן.",
        "config-using-server": "באניצן סארווער־נאמען \"<nowiki>$1</nowiki>\".",
        "config-using-uri": "באניצן סארווער־אדרעס \"<nowiki>$1$2</nowiki>\".",
index f3a4321..d75f45e 100644 (file)
        "config-pcre-no-utf8": "<strong>致命错误:</strong>PHP的PCRE模块在编译时可能没有包含PCRE_UTF8支持。\nMediaWiki需要UTF-8支持才能正常工作。",
        "config-memory-raised": "PHP的内存使用上限<code>memory_limit</code>为$1,自动提升到$2。",
        "config-memory-bad": "<strong>警告:</strong>PHP的内存使用上限<code>memory_limit</code>为$1。\n该设定可能过低,并导致安装失败!",
-       "config-apc": "[http://www.php.net/apc APC]已安装",
-       "config-apcu": "已安装[http://www.php.net/apcu APCu]",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache]已安装",
-       "config-no-cache-apcu": "<strong>警告:</strong>找不到[http://www.php.net/apcu APCu]或[http://www.iis.net/download/WinCacheForPhp WinCache]。对象缓存未启用。",
+       "config-apc": "[https://secure.php.net/apc APC]已安装",
+       "config-apcu": "已安装[https://secure.php.net/apcu APCu]",
+       "config-wincache": "已安装[https://www.iis.net/downloads/microsoft/wincache-extension WinCache]",
+       "config-no-cache-apcu": "<strong>警告:</strong>找不到[https://secure.php.net/apcu APCu]或[https://www.iis.net/downloads/microsoft/wincache-extension WinCache]。对象缓存未启用。",
        "config-mod-security": "<strong>警告:</strong>您的web服务器已启用[https://modsecurity.org/ mod_security]/mod_security2。它的很多常见配置可能导致MediaWiki及其他软件允许用户发布任意内容的问题。如果可能,这应当被禁用。否则,当您遭遇随机错误时,请参考[https://modsecurity.org/documentation/ mod_security 文档]或联络您的主机支持。",
        "config-diff3-bad": "找不到GNU diff3。",
        "config-git": "发现Git版本控制软件:<code>$1</code>",
        "config-type-mysql": "MySQL(或兼容程序)",
        "config-type-mssql": "微软SQL服务器",
        "config-support-info": "MediaWiki支持以下数据库系统:\n\n$1\n\n如果您在下面列出的数据库系统中没有找到您希望使用的系统,请根据上方链向的指引启用支持。",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL]是MediaWiki的首选数据库,对它的支持最为完备。MediaWiki也可以在[{{int:version-db-mariadb-url}} MariaDB]和[{{int:version-db-percona-url}} Percona Server]下工作,它们与MySQL兼容。([http://www.php.net/manual/en/mysql.installation.php 如何将对MySQL的支持编译进PHP中])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL]是一种流行的开源数据库系统,可作为MySQL的替代([http://www.php.net/manual/en/pgsql.installation.php 如何将对PostgreSQL的支持编译进PHP中])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]是一种轻量级的数据库系统,能被良好地支持。([http://www.php.net/manual/en/pdo.installation.php 如何将对SQLite的支持编译进PHP中],须使用PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle]是一种商用企业级的数据库。([http://www.php.net/manual/en/oci8.installation.php 如何将对OCI8的支持编译进PHP中])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]是一个适用于Windows的商业性企业数据库。([http://www.php.net/manual/en/sqlsrv.installation.php 如何编译带有SQLSRV支持的PHP])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL]是MediaWiki的首选数据库,对它的支持最为完备。MediaWiki也可以在[{{int:version-db-mariadb-url}} MariaDB]和[{{int:version-db-percona-url}} Percona Server]下工作,它们与MySQL兼容。([https://secure.php.net/manual/en/mysqli.installation.php 如何将对MySQL的支持编译进PHP中])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL]是一种流行的开源数据库系统,可作为MySQL的替代。([https://secure.php.net/manual/en/pgsql.installation.php 如何将对PostgreSQL的支持编译进PHP中])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]是一种轻量级的数据库系统,能被良好地支持。([https://secure.php.net/manual/en/pdo.installation.php 如何将对SQLite的支持编译进PHP中],须使用PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle]是一种商用企业级的数据库。([https://secure.php.net/manual/en/oci8.installation.php 如何将对OCI8的支持编译进PHP中])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]是一个适用于Windows的商业性企业数据库。([https://secure.php.net/manual/en/sqlsrv.installation.php 如何编译带有SQLSRV支持的PHP])",
        "config-header-mysql": "MySQL设置",
        "config-header-postgres": "PostgreSQL设置",
        "config-header-sqlite": "SQLite设置",
        "config-license-help": "许多公共wiki将所有用户贡献置于[https://freedomdefined.org/Definition 自由许可证]之下。这有助于构建社区的主人翁意识,并鼓励长期贡献。对于非公共wiki或公司wiki,这并非必要条件。\n\n如果您希望使用来自维基百科的内容,并希望维基百科能接受复制自您的wiki的内容,您应当选择<strong>{{int:config-license-cc-by-sa}}</strong>。\n\nGNU自由文档许可证是维基百科曾经使用过的许可证,并迄今有效。然而,该许可证难以理解,并会增加重用内容的难度。",
        "config-email-settings": "电子邮件设置",
        "config-enable-email": "启用出站电子邮件",
-       "config-enable-email-help": "如果您希望使用电子邮件功能,请正确配置[http://www.php.net/manual/en/mail.configuration.php PHP的邮件设定]。如果您不需要任何电子邮件功能,请在此处禁用它。",
+       "config-enable-email-help": "如果您希望使用电子邮件功能,请正确配置[https://secure.php.net/manual/en/mail.configuration.php PHP的邮件设定]。如果您不需要任何电子邮件功能,请在此处禁用它。",
        "config-email-user": "启用用户到用户的电子邮件",
        "config-email-user-help": "允许所有用户互发邮件,假若他们启用了该功能。",
        "config-email-usertalk": "启用用户讨论页面通知",
index 93c042e..7c3b00c 100644 (file)
        "config-pcre-no-utf8": "<strong>嚴重:</strong> PHP 的 PCRE 模組在編譯時未包含 PCRE_UTF8 支援。\nMediaWiki 需要支援 UTF-8 才可正常運作。",
        "config-memory-raised": "PHP 的記憶體使用上限 <code>memory_limit</code> 目前為 $1,自動提高到 $2。",
        "config-memory-bad": "<strong>警告:</strong>PHP 的記憶體使用上限 <code>memory_limit</code> 為 $1。\n該設定值可能過低。\n這可能導致後續的安裝失敗!",
-       "config-apc": "[http://www.php.net/apc APC] 已安裝",
-       "config-apcu": "已安裝[http://www.php.net/apcu APCu]",
-       "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] 已安裝",
-       "config-no-cache-apcu": "<strong>警告:</strong>找不到[http://www.php.net/apcu APCu]或[http://www.iis.net/download/WinCacheForPhp WinCache]。未開啟物件快取。",
+       "config-apc": "[https://secure.php.net/apc APC] 已安裝",
+       "config-apcu": "已安裝[https://secure.php.net/apcu APCu]",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] 已安裝",
+       "config-no-cache-apcu": "<strong>警告:</strong>找不到[https://secure.php.net/apcu APCu]或[https://www.iis.net/downloads/microsoft/wincache-extension WinCache]。未開啟物件快取。",
        "config-mod-security": "<strong>警告:</strong>您的網頁伺服器已開啟 [https://modsecurity.org/ mod_security] 模組,如果設定不恰當會導致使用者可在 MediaWiki 或其他應用程式發佈任意的內容。\n若您遇到任何問題,請參考 [https://modsecurity.org/documentation/ mod_security 文件] 或聯繫您的伺服器技術支援人員。",
        "config-diff3-bad": "找不到 GNU diff3。",
        "config-git": "找到 Git 版本控制軟體:<code>$1</code>。",
        "config-type-mysql": "MySQL (或與其相容的程式)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki 支援以下資料庫系統:\n\n$1\n\n如果您下方沒有看到您要使用的資料庫系統,請根據上方連結指示開啟資料庫的支援。",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] 是 MediaWiki 主要支援的資料庫系統。MediaWiki 也同時可運作與於 [{{int:version-db-mariadb-url}} MariaDB] 和[{{int:version-db-percona-url}} Percona 伺服器],上述這些與 MySQL 相容的資料庫系統。([http://www.php.net/manual/en/mysqli.installation.php 如何編譯支援 MySQL 的 PHP])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL]是一套受歡迎的開源資料庫系統,可用來替代 MySQL。([http://www.php.net/manual/en/pgsql.installation.php 如何編譯支援PostgreSQL的PHP])。",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] 是一套輕量級的資料庫系統,MediaWiki 可在此資料庫系統上良好的運作。([http://www.php.net/manual/en/pdo.installation.php 如何編譯支援 SQLite 的 PHP],須透過 PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] 是一套商用企業級的資料庫。([http://www.php.net/manual/en/oci8.installation.php 如何編譯支援 OCI8 的 PHP])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] 是一套 Windows 專用的商用企業級的資料庫。 ([http://www.php.net/manual/en/sqlsrv.installation.php 如何編譯支援 SQLSRV 的 PHP])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] 是 MediaWiki 主要支援的資料庫系統。MediaWiki 也同時可運作與於 [{{int:version-db-mariadb-url}} MariaDB] 和 [{{int:version-db-percona-url}} Percona 伺服器],上述這些與 MySQL 相容的資料庫系統。([https://secure.php.net/manual/en/mysqli.installation.php 如何編譯支援 MySQL 的 PHP])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] 是一套受歡迎的開源資料庫系統,可用來替代 MySQL。([https://secure.php.net/manual/en/pgsql.installation.php 如何編譯支援 PostgreSQL 的 PHP])。",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] 是一套輕量級的資料庫系統,MediaWiki 可在此資料庫系統上良好的運作。([https://secure.php.net/manual/en/pdo.installation.php 如何編譯支援 SQLite 的 PHP],須透過 PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] 是一套商用企業級的資料庫。([https://secure.php.net/manual/en/oci8.installation.php 如何編譯支援 OCI8 的 PHP])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] 是一套 Windows 專用的商用企業級的資料庫。 ([https://secure.php.net/manual/en/sqlsrv.installation.php 如何編譯支援 SQLSRV 的 PHP])",
        "config-header-mysql": "MySQL 設定",
        "config-header-postgres": "PostgreSQL 設定",
        "config-header-sqlite": "SQLite 設定",
        "config-license-help": "許多開放式 Wiki 會以 [https://freedomdefined.org/Definition 自由授權條款] 的方式釋放出編者的所有貢獻,這有助於構建社群的所有權,並且能鼓勵長期貢獻。對於封閉式的 Wiki 或公司 Wiki 則是非必要的。\n\n如果您希望使用來自維基百科(Wikipedia)的內容,並希望維基百科能接受您的 Wiki 內容,請應選擇 <strong>{{int:config-license-cc-by-sa}}</strong> 授權條款。\n\n維基百科(Wikipedia)先前是使用 GNU 自由文件授權條款,\n但該授權條款的內容較難理解,因此較難再利用在該條款底下的內容。",
        "config-email-settings": "E-mail 設定",
        "config-enable-email": "開啟外寄電子郵件",
-       "config-enable-email-help": "如果您要使用電子郵件功能,請正確設定 [http://www.php.net/manual/en/mail.configuration.php PHP 的郵件設定]。\n如果您不需要使用電子郵件功能,請在此處關閉。",
+       "config-enable-email-help": "如果您要使用電子郵件功能,請正確設定 [https://secure.php.net/manual/en/mail.configuration.php PHP 的郵件設定]。\n如果您不需要使用電子郵件功能,請在此處關閉。",
        "config-email-user": "開啟使用者對使用者間的電子郵件互通",
        "config-email-user-help": "若使用者在個人偏好設定開啟了此功能,則可允許使用者間相互傳送郵件。",
        "config-email-usertalk": "開啟使用者討論頁面通知",
index 076c37f..d906498 100644 (file)
@@ -24,7 +24,7 @@ namespace MediaWiki\Interwiki;
  * @since 1.29
  * @ingroup InterwikiLookup
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  */
 
 use Interwiki;
index f9c416f..b16cfa3 100644 (file)
@@ -23,8 +23,7 @@
 
 /**
  * Class to both describe a background job and handle jobs.
- * The queue aspects of this class are now deprecated.
- * Using the class to push jobs onto queues is deprecated (use JobSpecification).
+ * To push jobs onto queues, use JobQueueGroup::singleton()->push();
  *
  * @ingroup JobQueue
  */
@@ -123,23 +122,6 @@ abstract class Job implements IJobSpecification {
                return ( $this->executionFlags && $flag ) === $flag;
        }
 
-       /**
-        * Batch-insert a group of jobs into the queue.
-        * This will be wrapped in a transaction with a forced commit.
-        *
-        * This may add duplicate at insert time, but they will be
-        * removed later on, when the first one is popped.
-        *
-        * @param Job[] $jobs Array of Job objects
-        * @return bool
-        * @deprecated since 1.21
-        */
-       public static function batchInsert( $jobs ) {
-               wfDeprecated( __METHOD__, '1.21' );
-               JobQueueGroup::singleton()->push( $jobs );
-               return true;
-       }
-
        /**
         * @return string
         */
@@ -346,17 +328,6 @@ abstract class Job implements IJobSpecification {
                }
        }
 
-       /**
-        * Insert a single job into the queue.
-        * @return bool True on success
-        * @deprecated since 1.21
-        */
-       public function insert() {
-               wfDeprecated( __METHOD__, '1.21' );
-               JobQueueGroup::singleton()->push( $this );
-               return true;
-       }
-
        /**
         * @return string
         */
index 1f4f179..d2446ab 100644 (file)
@@ -472,7 +472,7 @@ abstract class JobQueue {
                $params = $job->getRootJobParams();
 
                $key = $this->getRootJobCacheKey( $params['rootJobSignature'] );
-               // Callers should call batchInsert() and then this function so that if the insert
+               // Callers should call JobQueueGroup::push() before this method so that if the insert
                // fails, the de-duplication registration will be aborted. Since the insert is
                // deferred till "transaction idle", do the same here, so that the ordering is
                // maintained. Having only the de-duplication registration succeed would cause
index c13f539..a082d64 100644 (file)
@@ -500,7 +500,7 @@ class JobQueueDB extends JobQueue {
                        throw new MWException( "Cannot register root job; missing 'rootJobTimestamp'." );
                }
                $key = $this->getRootJobCacheKey( $params['rootJobSignature'] );
-               // Callers should call batchInsert() and then this function so that if the insert
+               // Callers should call JobQueueGroup::push() before this method so that if the insert
                // fails, the de-duplication registration will be aborted. Since the insert is
                // deferred till "transaction idle", do the same here, so that the ordering is
                // maintained. Having only the de-duplication registration succeed would cause
index a6014b1..da75ed4 100644 (file)
@@ -19,7 +19,7 @@
  * @version 0.1.1 -- 2010-09-11
  * @author Trevor Parscal <tparscal@wikimedia.org>
  * @copyright Copyright 2010 Wikimedia Foundation
- * @license http://www.apache.org/licenses/LICENSE-2.0
+ * @license Apache-2.0
  */
 
 /**
@@ -40,7 +40,7 @@ class CSSMin {
        const EMBED_REGEX = '\/\*\s*\@embed\s*\*\/';
        const COMMENT_REGEX = '\/\*.*?\*\/';
 
-       /** @var array List of common image files extensions and MIME-types */
+       /** @var string[] List of common image files extensions and MIME-types */
        protected static $mimeTypes = [
                'gif' => 'image/gif',
                'jpe' => 'image/jpeg',
@@ -58,7 +58,7 @@ class CSSMin {
         *
         * @param string $source CSS stylesheet source to process
         * @param string $path File path where the source was read from
-        * @return array List of local file references
+        * @return string[] List of local file references
         */
        public static function getLocalFileReferences( $source, $path ) {
                $stripped = preg_replace( '/' . self::COMMENT_REGEX . '/s', '', $source );
@@ -100,7 +100,7 @@ class CSSMin {
         * @param bool $ie8Compat By default, a data URI will only be produced if it can be made short
         *     enough to fit in Internet Explorer 8 (and earlier) URI length limit (32,768 bytes). Pass
         *     `false` to remove this limitation.
-        * @return string|bool Image contents encoded as a data URI or false.
+        * @return string|false Image contents encoded as a data URI or false.
         */
        public static function encodeImageAsDataURI( $file, $type = null, $ie8Compat = true ) {
                // Fast-fail for files that definitely exceed the maximum data URI length
@@ -128,7 +128,7 @@ class CSSMin {
         * @param string $contents File contents to encode.
         * @param string $type File's MIME type.
         * @param bool $ie8Compat See encodeImageAsDataURI().
-        * @return string|bool Image contents encoded as a data URI or false.
+        * @return string|false Image contents encoded as a data URI or false.
         */
        public static function encodeStringAsDataURI( $contents, $type, $ie8Compat = true ) {
                // Try #1: Non-encoded data URI
@@ -173,13 +173,13 @@ class CSSMin {
 
        /**
         * Serialize a string (escape and quote) for use as a CSS string value.
-        * https://www.w3.org/TR/2016/WD-cssom-1-20160317/#serialize-a-string
+        * https://drafts.csswg.org/cssom/#serialize-a-string
         *
         * @param string $value
         * @return string
         */
        public static function serializeStringValue( $value ) {
-               $value = strtr( $value, [ "\0" => "\\fffd ", '\\' => '\\\\', '"' => '\\"' ] );
+               $value = strtr( $value, [ "\0" => "\xEF\xBF\xBD", '\\' => '\\\\', '"' => '\\"' ] );
                $value = preg_replace_callback( '/[\x01-\x1f\x7f]/', function ( $match ) {
                        return '\\' . base_convert( ord( $match[0] ), 10, 16 ) . ' ';
                }, $value );
@@ -387,10 +387,7 @@ class CSSMin {
         * @return bool
         */
        protected static function isLocalUrl( $maybeUrl ) {
-               if ( $maybeUrl !== '' && $maybeUrl[0] === '/' && !self::isRemoteUrl( $maybeUrl ) ) {
-                       return true;
-               }
-               return false;
+               return isset( $maybeUrl[1] ) && $maybeUrl[0] === '/' && $maybeUrl[1] !== '/';
        }
 
        /**
@@ -402,6 +399,7 @@ class CSSMin {
                        // Match these three variants separately to avoid broken urls when
                        // e.g. a double quoted url contains a parenthesis, or when a
                        // single quoted url contains a double quote, etc.
+                       // FIXME: Simplify now we only support PHP 7.0.0+
                        // Note: PCRE doesn't support multiple capture groups with the same name by default.
                        // - PCRE 6.7 introduced the "J" modifier (PCRE_INFO_JCHANGED for PCRE_DUPNAMES).
                        //   https://secure.php.net/manual/en/reference.pcre.pattern.modifiers.php
@@ -511,7 +509,7 @@ class CSSMin {
                                                return $data;
                                        }
                                }
-                               if ( method_exists( 'OutputPage', 'transformFilePath' ) ) {
+                               if ( class_exists( OutputPage::class ) ) {
                                        $url = OutputPage::transformFilePath( $remote, $local, $file );
                                } else {
                                        // Add version parameter as the first five hex digits
index 6b3e4a7..c41aab3 100644 (file)
@@ -217,7 +217,7 @@ class CryptHKDF {
         * @param string $ikm The input keying material
         * @param string $salt The salt to add to the ikm, to get the prk
         * @param string $info Optional context (change the output without affecting
-        *      the randomness properties of the output)
+        *      the randomness properties of the output)
         * @param int $L Number of bytes to return
         * @return string Cryptographically secure pseudorandom binary string
         */
index 79d1374..a9b26ac 100644 (file)
@@ -29,7 +29,7 @@
  *
  * @file
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
 abstract class GenericArrayObject extends ArrayObject {
index f95bb1e..06589d2 100644 (file)
@@ -164,7 +164,7 @@ class IP {
                }
                if ( self::isIPv4( $ip ) ) {
                        // Remove leading 0's from octet representation of IPv4 address
-                       $ip = preg_replace( '/(?:^|(?<=\.))0+(?=[1-9]|0\.|0$)/', '', $ip );
+                       $ip = preg_replace( '!(?:^|(?<=\.))0+(?=[1-9]|0[./]|0$)!', '', $ip );
                        return $ip;
                }
                // Remove any whitespaces, convert to upper case
index 5ecfc7c..43cd7db 100644 (file)
@@ -4,7 +4,10 @@
  *
  * @file
  * @author Paul Copperman <paul.copperman@gmail.com>
- * @license Choose any of Apache, MIT, GPL, LGPL
+ * @license Apache-2.0
+ * @license MIT
+ * @license GPL-2.0-or-later
+ * @license LGPL-2.1-or-later
  */
 
 /**
index 053a5ff..d75d698 100644 (file)
@@ -107,7 +107,7 @@ class MultiHttpClient implements LoggerAwareInterface {
         *   - error     : Any cURL error string
         * The map also stores integer-indexed copies of these values. This lets callers do:
         * @code
-        *              list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $http->run( $req );
+        *              list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $http->run( $req );
         * @endcode
         * @param array $req HTTP request array
         * @param array $opts
@@ -346,16 +346,7 @@ class MultiHttpClient implements LoggerAwareInterface {
                        // Don't interpret POST parameters starting with '@' as file uploads, because this
                        // makes it impossible to POST plain values starting with '@' (and causes security
                        // issues potentially exposing the contents of local files).
-                       // The PHP manual says this option was introduced in PHP 5.5 defaults to true in PHP 5.6,
-                       // but we support lower versions, and the option doesn't exist in HHVM 5.6.99.
-                       if ( defined( 'CURLOPT_SAFE_UPLOAD' ) ) {
-                               curl_setopt( $ch, CURLOPT_SAFE_UPLOAD, true );
-                       } elseif ( is_array( $req['body'] ) ) {
-                               // In PHP 5.2 and later, '@' is interpreted as a file upload if POSTFIELDS
-                               // is an array, but not if it's a string. So convert $req['body'] to a string
-                               // for safety.
-                               $req['body'] = http_build_query( $req['body'] );
-                       }
+                       curl_setopt( $ch, CURLOPT_SAFE_UPLOAD, true );
                        curl_setopt( $ch, CURLOPT_POSTFIELDS, $req['body'] );
                } else {
                        if ( is_resource( $req['body'] ) || $req['body'] !== '' ) {
index 4512a4b..46f9358 100644 (file)
  * Wrapper around strtr() that holds replacements
  */
 class ReplacementArray {
-       private $data = false;
+       private $data = [];
 
        /**
         * Create an object with the specified replacement array
         * The array should have the same form as the replacement array for strtr()
         * @param array $data
         */
-       public function __construct( $data = [] ) {
+       public function __construct( array $data = [] ) {
                $this->data = $data;
        }
 
@@ -44,12 +44,12 @@ class ReplacementArray {
         * Set the whole replacement array at once
         * @param array $data
         */
-       public function setArray( $data ) {
+       public function setArray( array $data ) {
                $this->data = $data;
        }
 
        /**
-        * @return array|bool
+        * @return array
         */
        public function getArray() {
                return $this->data;
index b257e27..d60e768 100644 (file)
@@ -101,7 +101,7 @@ class FSFileBackend extends FileBackendStore {
        public function getFeatures() {
                if ( $this->isWindows && version_compare( PHP_VERSION, '7.1', 'lt' ) ) {
                        // PHP before 7.1 used 8-bit code page for filesystem paths on Windows;
-                       // See http://php.net/manual/en/migration71.windows-support.php
+                       // See https://secure.php.net/manual/en/migration71.windows-support.php
                        return 0;
                } else {
                        return FileBackend::ATTR_UNICODE_PATHS;
index 5695d82..997974e 100644 (file)
@@ -1811,7 +1811,7 @@ class SwiftFileBackend extends FileBackendStore {
                if ( $code == 401 ) { // possibly a stale token
                        $this->srvCache->delete( $this->getCredsCacheKey( $this->swiftUser ) );
                }
-               $msg = "HTTP {code} ({desc}) in '{func}' (given '{params}')";
+               $msg = "HTTP {code} ({desc}) in '{func}' (given '{req_params}')";
                $msgParams = [
                        'code'   => $code,
                        'desc'   => $desc,
index 8420f11..8a88581 100644 (file)
@@ -33,14 +33,25 @@ use Wikimedia\ScopedCallback;
 use Wikimedia\WaitConditionLoop;
 
 /**
- * interface is intended to be more or less compatible with
- * the PHP memcached client.
+ * Class representing a cache/ephemeral data store
  *
- * backends for local hash array and SQL table included:
- * @code
- *   $bag = new HashBagOStuff();
- *   $bag = new SqlBagOStuff(); # connect to db first
- * @endcode
+ * This interface is intended to be more or less compatible with the PHP memcached client.
+ *
+ * Instances of this class should be created with an intended access scope, such as:
+ *   - a) A single PHP thread on a server (e.g. stored in a PHP variable)
+ *   - b) A single application server (e.g. stored in APC or sqlite)
+ *   - c) All application servers in datacenter (e.g. stored in memcached or mysql)
+ *   - d) All application servers in all datacenters (e.g. stored via mcrouter or dynomite)
+ *
+ * Callers should use the proper factory methods that yield BagOStuff instances. Site admins
+ * should make sure the configuration for those factory methods matches their access scope.
+ * BagOStuff subclasses have widely varying levels of support for replication features.
+ *
+ * For any given instance, methods like lock(), unlock(), merge(), and set() with WRITE_SYNC
+ * should semantically operate over its entire access scope; any nodes/threads in that scope
+ * should serialize appropriately when using them. Likewise, a call to get() with READ_LATEST
+ * from one node in its access scope should reflect the prior changes of any other node its access
+ * scope. Any get() should reflect the changes of any prior set() with WRITE_SYNC.
  *
  * @ingroup Cache
  */
@@ -165,7 +176,7 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
        /**
         * Get an item with the given key
         *
-        * If the key includes a determistic input hash (e.g. the key can only have
+        * If the key includes a deterministic input hash (e.g. the key can only have
         * the correct value) or complete staleness checks are handled by the caller
         * (e.g. nothing relies on the TTL), then the READ_VERIFIED flag should be set.
         * This lets tiered backends know they can safely upgrade a cached value to
index 90e697e..8b21ede 100644 (file)
@@ -63,6 +63,8 @@ class ChronologyProtector implements LoggerAwareInterface {
 
        /** @var int Seconds to store positions */
        const POSITION_TTL = 60;
+       /** @var int Seconds to store position write index cookies (safely less than POSITION_TTL) */
+       const POSITION_COOKIE_TTL = 60;
        /** @var int Max time to wait for positions to appear */
        const POS_STORE_WAIT_TIMEOUT = 5;
 
@@ -190,13 +192,14 @@ class ChronologyProtector implements LoggerAwareInterface {
                        implode( ', ', array_keys( $this->shutdownPositions ) ) . "\n"
                );
 
-               // CP-protected writes should overwhemingly go to the master datacenter, so get DC-local
-               // lock to merge the values. Use a DC-local get() and a synchronous all-DC set(). This
-               // makes it possible for the BagOStuff class to write in parallel to all DCs with one RTT.
+               // CP-protected writes should overwhelmingly go to the master datacenter, so use a
+               // DC-local lock to merge the values. Use a DC-local get() and a synchronous all-DC
+               // set(). This makes it possible for the BagOStuff class to write in parallel to all
+               // DCs with one RTT. The use of WRITE_SYNC avoids needing READ_LATEST for the get().
                if ( $store->lock( $this->key, 3 ) ) {
                        if ( $workCallback ) {
-                               // Let the store run the work before blocking on a replication sync barrier. By the
-                               // time it's done with the work, the barrier should be fast if replication caught up.
+                               // Let the store run the work before blocking on a replication sync barrier.
+                               // If replication caught up while the work finished, the barrier will be fast.
                                $store->addBusyCallback( $workCallback );
                        }
                        $ok = $store->set(
index 4a497b0..27e6138 100644 (file)
@@ -35,7 +35,7 @@ use InvalidArgumentException;
 class ConnectionManager {
 
        /**
-        * @var LoadBalancer
+        * @var ILoadBalancer
         */
        private $loadBalancer;
 
@@ -52,14 +52,14 @@ class ConnectionManager {
        private $groups = [];
 
        /**
-        * @param LoadBalancer $loadBalancer
+        * @param ILoadBalancer $loadBalancer
         * @param string|bool $domain Optional logical DB name, defaults to current wiki.
         *        This follows the convention for database names used by $loadBalancer.
         * @param string[] $groups see LoadBalancer::getConnection
         *
         * @throws InvalidArgumentException
         */
-       public function __construct( LoadBalancer $loadBalancer, $domain = false, array $groups = [] ) {
+       public function __construct( ILoadBalancer $loadBalancer, $domain = false, array $groups = [] ) {
                if ( !is_string( $domain ) && $domain !== false ) {
                        throw new InvalidArgumentException( '$dbName must be a string, or false.' );
                }
index 9de16c4..dedf6ea 100644 (file)
@@ -33,7 +33,7 @@ class DBConnRef implements IDatabase {
                $this->lb = $lb;
                if ( $conn instanceof Database ) {
                        $this->conn = $conn; // live handle
-               } elseif ( count( $conn ) >= 4 && $conn[self::FLD_DOMAIN] !== false ) {
+               } elseif ( is_array( $conn ) && count( $conn ) >= 4 && $conn[self::FLD_DOMAIN] !== false ) {
                        $this->params = $conn;
                } else {
                        throw new InvalidArgumentException( "Missing lazy connection arguments." );
@@ -639,4 +639,8 @@ class DBConnRef implements IDatabase {
        }
 }
 
+/**
+ * @since 1.22
+ * @deprecated since 1.29
+ */
 class_alias( DBConnRef::class, 'DBConnRef' );
index aeda5b9..d1230e0 100644 (file)
@@ -4638,5 +4638,12 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 }
 
-class_alias( Database::class, 'DatabaseBase' ); // b/c for old name
-class_alias( Database::class, 'Database' ); // b/c global alias
+/**
+ * @deprecated since 1.28
+ */
+class_alias( Database::class, 'DatabaseBase' );
+
+/**
+ * @deprecated since 1.29
+ */
+class_alias( Database::class, 'Database' );
index 4c187f2..768e0c6 100644 (file)
@@ -1418,4 +1418,7 @@ class DatabaseMssql extends Database {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DatabaseMssql::class, 'DatabaseMssql' );
index 0472139..953f63d 100644 (file)
@@ -1580,4 +1580,7 @@ abstract class DatabaseMysqlBase extends Database {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DatabaseMysqlBase::class, 'DatabaseMysqlBase' );
index 0a5450c..31cdd7c 100644 (file)
@@ -341,4 +341,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DatabaseMysqli::class, 'DatabaseMysqli' );
index 9610839..807d9cc 100644 (file)
@@ -1444,4 +1444,7 @@ SQL;
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DatabasePostgres::class, 'DatabasePostgres' );
index a6a153a..5f37c1d 100644 (file)
@@ -1106,4 +1106,7 @@ class DatabaseSqlite extends Database {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DatabaseSqlite::class, 'DatabaseSqlite' );
index ca3fd52..2145129 100644 (file)
@@ -2117,4 +2117,7 @@ interface IDatabase {
        public function setIndexAliases( array $aliases );
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( IDatabase::class, 'IDatabase' );
index 12e59b5..aeb5d8d 100644 (file)
@@ -62,4 +62,7 @@ class FakeResultWrapper extends ResultWrapper {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( FakeResultWrapper::class, 'FakeResultWrapper' );
index df354af..1355e22 100644 (file)
@@ -119,4 +119,7 @@ class ResultWrapper implements IResultWrapper {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( ResultWrapper::class, 'ResultWrapper' );
index 7bc3eac..6a28e35 100644 (file)
@@ -18,4 +18,7 @@ class Blob implements IBlob {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( Blob::class, 'Blob' );
index 97e03b2..aa545cd 100644 (file)
@@ -31,4 +31,7 @@ class DBAccessError extends DBUnexpectedError {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBAccessError::class, 'DBAccessError' );
index 91d98dc..4c5bc9a 100644 (file)
@@ -38,4 +38,7 @@ class DBConnectionError extends DBExpectedError {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBConnectionError::class, 'DBConnectionError' );
index aad219d..1a5f4a3 100644 (file)
@@ -43,4 +43,7 @@ class DBError extends RuntimeException {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBError::class, 'DBError' );
index 7e46420..73bc1f1 100644 (file)
@@ -55,4 +55,7 @@ class DBExpectedError extends DBError implements MessageSpecifier {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBExpectedError::class, 'DBExpectedError' );
index e6870a7..0be08cd 100644 (file)
@@ -67,4 +67,7 @@ class DBQueryError extends DBExpectedError {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBQueryError::class, 'DBQueryError' );
index 4393343..cdde1a7 100644 (file)
@@ -27,4 +27,7 @@ namespace Wikimedia\Rdbms;
 class DBReadOnlyError extends DBExpectedError {
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBReadOnlyError::class, 'DBReadOnlyError' );
index 457431e..c5dd8ae 100644 (file)
@@ -28,4 +28,7 @@ namespace Wikimedia\Rdbms;
 class DBReplicationWaitError extends DBExpectedError {
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBReplicationWaitError::class, 'DBReplicationWaitError' );
index 62a078c..34b4c91 100644 (file)
@@ -27,4 +27,7 @@ namespace Wikimedia\Rdbms;
 class DBTransactionError extends DBExpectedError {
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBTransactionError::class, 'DBTransactionError' );
index d2622e1..b3f464b 100644 (file)
@@ -30,4 +30,7 @@ class DBTransactionSizeError extends DBTransactionError {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBTransactionSizeError::class, 'DBTransactionSizeError' );
index 9c67eb5..2c506ca 100644 (file)
@@ -27,4 +27,7 @@ namespace Wikimedia\Rdbms;
 class DBUnexpectedError extends DBError {
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBUnexpectedError::class, 'DBUnexpectedError' );
index 7918f36..48d5546 100644 (file)
@@ -32,4 +32,7 @@ interface Field {
        function isNullable();
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( Field::class, 'Field' );
index 45e7cbb..16d0e31 100644 (file)
@@ -321,10 +321,10 @@ interface ILBFactory {
         * Note that unlike cookies, this works accross domains
         *
         * @param string $url
-        * @param float $time UNIX timestamp just before shutdown() was called
+        * @param int $index Write counter index
         * @return string
         */
-       public function appendShutdownCPIndexAsQuery( $url, $time );
+       public function appendShutdownCPIndexAsQuery( $url, $index );
 
        /**
         * @param array $info Map of fields, including:
index 38c7a5c..e8ec250 100644 (file)
@@ -95,6 +95,8 @@ abstract class LBFactory implements ILBFactory {
        const ROUND_BEGINNING = 'within-begin';
        const ROUND_COMMITTING = 'within-commit';
        const ROUND_ROLLING_BACK = 'within-rollback';
+       const ROUND_COMMIT_CALLBACKS = 'within-commit-callbacks';
+       const ROUND_ROLLBACK_CALLBACKS = 'within-rollback-callbacks';
 
        private static $loggerFields =
                [ 'replLogger', 'connLogger', 'queryLogger', 'perfLogger' ];
@@ -137,6 +139,7 @@ abstract class LBFactory implements ILBFactory {
                        'IPAddress' => isset( $_SERVER[ 'REMOTE_ADDR' ] ) ? $_SERVER[ 'REMOTE_ADDR' ] : '',
                        'UserAgent' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '',
                        'ChronologyProtection' => 'true',
+                       // phpcs:ignore MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals -- library can't use $wgRequest
                        'ChronologyPositionIndex' => isset( $_GET['cpPosIndex'] ) ? $_GET['cpPosIndex'] : null
                ];
 
@@ -170,28 +173,28 @@ abstract class LBFactory implements ILBFactory {
        /**
         * @see ILBFactory::newMainLB()
         * @param bool $domain
-        * @return LoadBalancer
+        * @return ILoadBalancer
         */
        abstract public function newMainLB( $domain = false );
 
        /**
         * @see ILBFactory::getMainLB()
         * @param bool $domain
-        * @return LoadBalancer
+        * @return ILoadBalancer
         */
        abstract public function getMainLB( $domain = false );
 
        /**
         * @see ILBFactory::newExternalLB()
         * @param string $cluster
-        * @return LoadBalancer
+        * @return ILoadBalancer
         */
        abstract public function newExternalLB( $cluster );
 
        /**
         * @see ILBFactory::getExternalLB()
         * @param string $cluster
-        * @return LoadBalancer
+        * @return ILoadBalancer
         */
        abstract public function getExternalLB( $cluster );
 
@@ -261,6 +264,7 @@ abstract class LBFactory implements ILBFactory {
                // Actually perform the commit on all master DB connections and revert DBO_TRX
                $this->forEachLBCallMethod( 'commitMasterChanges', [ $fname ] );
                // Run all post-commit callbacks in a separate step
+               $this->trxRoundStage = self::ROUND_COMMIT_CALLBACKS;
                $e = $this->executePostTransactionCallbacks();
                $this->trxRoundStage = self::ROUND_CURSORY;
                // Throw any last post-commit callback error
@@ -275,6 +279,7 @@ abstract class LBFactory implements ILBFactory {
                // Actually perform the rollback on all master DB connections and revert DBO_TRX
                $this->forEachLBCallMethod( 'rollbackMasterChanges', [ $fname ] );
                // Run all post-commit callbacks in a separate step
+               $this->trxRoundStage = self::ROUND_ROLLBACK_CALLBACKS;
                $this->executePostTransactionCallbacks();
                $this->trxRoundStage = self::ROUND_CURSORY;
        }
@@ -547,10 +552,18 @@ abstract class LBFactory implements ILBFactory {
        }
 
        /**
-        * Base parameters to LoadBalancer::__construct()
+        * Base parameters to ILoadBalancer::__construct()
         * @return array
         */
        final protected function baseLoadBalancerParams() {
+               if ( $this->trxRoundStage === self::ROUND_COMMIT_CALLBACKS ) {
+                       $initStage = ILoadBalancer::STAGE_POSTCOMMIT_CALLBACKS;
+               } elseif ( $this->trxRoundStage === self::ROUND_ROLLBACK_CALLBACKS ) {
+                       $initStage = ILoadBalancer::STAGE_POSTROLLBACK_CALLBACKS;
+               } else {
+                       $initStage = null;
+               }
+
                return [
                        'localDomain' => $this->localDomain,
                        'readOnlyReason' => $this->readOnlyReason,
@@ -570,7 +583,8 @@ abstract class LBFactory implements ILBFactory {
                                // Defer ChronologyProtector construction in case setRequestInfo() ends up
                                // being called later (but before the first connection attempt) (T192611)
                                $this->getChronologyProtector()->initLB( $lb );
-                       }
+                       },
+                       'roundStage' => $initStage
                ];
        }
 
@@ -627,6 +641,36 @@ abstract class LBFactory implements ILBFactory {
                return strpos( $url, '?' ) === false ? "$url?cpPosIndex=$index" : "$url&cpPosIndex=$index";
        }
 
+       /**
+        * @param int $index Write index
+        * @param int $time UNIX timestamp
+        * @return string Timestamp-qualified write index of the form "<index>.<timestamp>"
+        * @since 1.32
+        */
+       public static function makeCookieValueFromCPIndex( $index, $time ) {
+               return $index . '@' . $time;
+       }
+
+       /**
+        * @param string $value String possibly of the form "<index>" or "<index>@<timestamp>"
+        * @param int $minTimestamp Lowest UNIX timestamp of non-expired values (if present)
+        * @return int|null Write index or null if $value is empty or expired
+        * @since 1.32
+        */
+       public static function getCPIndexFromCookieValue( $value, $minTimestamp ) {
+               if ( !preg_match( '/^(\d+)(?:@(\d+))?$/', $value, $m ) ) {
+                       return null;
+               }
+
+               $index = (int)$m[1];
+
+               if ( isset( $m[2] ) && $m[2] !== '' && (int)$m[2] < $minTimestamp ) {
+                       return null; // expired
+               }
+
+               return ( $index > 0 ) ? $index : null;
+       }
+
        public function setRequestInfo( array $info ) {
                if ( $this->chronProt ) {
                        throw new LogicException( 'ChronologyProtector already initialized.' );
@@ -669,4 +713,7 @@ abstract class LBFactory implements ILBFactory {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( LBFactory::class, 'LBFactory' );
index 850f9af..81ce4ba 100644 (file)
@@ -89,6 +89,11 @@ interface ILoadBalancer {
        /** @var int Alias for CONN_TRX_AUTOCOMMIT for b/c; deprecated since 1.31 */
        const CONN_TRX_AUTO = 1;
 
+       /** @var string Manager of ILoadBalancer instances is running post-commit callbacks */
+       const STAGE_POSTCOMMIT_CALLBACKS = 'stage-postcommit-callbacks';
+       /** @var string Manager of ILoadBalancer instances is running post-rollback callbacks */
+       const STAGE_POSTROLLBACK_CALLBACKS = 'stage-postrollback-callbacks';
+
        /**
         * Construct a manager of IDatabase connection objects
         *
@@ -112,6 +117,7 @@ interface ILoadBalancer {
         *  - perfLogger: PSR-3 logger instance. [optional]
         *  - errorLogger : Callback that takes an Exception and logs it. [optional]
         *  - deprecationLogger: Callback to log a deprecation warning. [optional]
+        *  - roundStage: STAGE_POSTCOMMIT_* class constant; for internal use [optional]
         * @throws InvalidArgumentException
         */
        public function __construct( array $params );
index 405ed14..eabcbbd 100644 (file)
@@ -261,6 +261,14 @@ class LoadBalancer implements ILoadBalancer {
                if ( isset( $params['chronologyCallback'] ) ) {
                        $this->chronologyCallback = $params['chronologyCallback'];
                }
+
+               if ( isset( $params['roundStage'] ) ) {
+                       if ( $params['roundStage'] === self::STAGE_POSTCOMMIT_CALLBACKS ) {
+                               $this->trxRoundStage = self::ROUND_COMMIT_CALLBACKS;
+                       } elseif ( $params['roundStage'] === self::STAGE_POSTROLLBACK_CALLBACKS ) {
+                               $this->trxRoundStage = self::ROUND_ROLLBACK_CALLBACKS;
+                       }
+               }
        }
 
        /**
@@ -1944,4 +1952,7 @@ class LoadBalancer implements ILoadBalancer {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( LoadBalancer::class, 'LoadBalancer' );
index be80cc5..d29258f 100644 (file)
@@ -77,4 +77,7 @@ class LoadBalancerSingle extends LoadBalancer {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( LoadBalancerSingle::class, 'LoadBalancerSingle' );
index 03ab8ea..c8d111d 100644 (file)
@@ -132,10 +132,10 @@ class PageDataRequestHandler {
                $contentHandler = ContentHandler::getForTitle( $title );
                $mimeTypes = $contentHandler->getSupportedFormats();
 
-               $headers = $request->getAllHeaders();
-               if ( isset( $headers['ACCEPT'] ) ) {
+               $acceptHeader = $request->getHeader( 'Accept' );
+               if ( $acceptHeader !== false ) {
                        $parser = new HttpAcceptParser();
-                       $accept = $parser->parseWeights( $headers['ACCEPT'] );
+                       $accept = $parser->parseWeights( $acceptHeader );
                } else {
                        // anything goes
                        $accept = [
index a5af026..0d22382 100644 (file)
@@ -18,7 +18,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  *
  * @file
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.25
  */
 
index ef00634..8078e2e 100644 (file)
@@ -19,7 +19,7 @@
  *
  * @file
  * @author Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.22
  */
 
index a2a899b..ee67618 100644 (file)
@@ -18,7 +18,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  *
  * @file
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.27
  */
 
index 31c196a..e9e338d 100644 (file)
@@ -24,7 +24,7 @@
  *
  * @file
  * @author Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.19
  */
 
index 93a81cf..9e4a630 100644 (file)
@@ -97,7 +97,7 @@ class LogEventsList extends ContextSource {
         * @param array|string $types
         * @param string $user
         * @param string $page
-        * @param string $pattern
+        * @param bool $pattern
         * @param int|string $year Use 0 to start with no year preselected.
         * @param int|string $month A month in the 1..12 range. Use 0 to start with no month
         *  preselected.
@@ -105,7 +105,7 @@ class LogEventsList extends ContextSource {
         * @param string $tagFilter Tag to select by default
         * @param string $action
         */
-       public function showOptions( $types = [], $user = '', $page = '', $pattern = '', $year = 0,
+       public function showOptions( $types = [], $user = '', $page = '', $pattern = false, $year = 0,
                $month = 0, $filter = null, $tagFilter = '', $action = null
        ) {
                global $wgScript, $wgMiserMode;
@@ -289,7 +289,7 @@ class LogEventsList extends ContextSource {
        }
 
        /**
-        * @param string $pattern
+        * @param bool $pattern
         * @return string Checkbox
         */
        private function getTitlePattern( $pattern ) {
index 0ffe691..0cf3e6d 100644 (file)
@@ -19,7 +19,7 @@
  *
  * @file
  * @author Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.19
  */
 use MediaWiki\Linker\LinkRenderer;
index 28c1a87..9f34264 100644 (file)
@@ -23,6 +23,8 @@
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Class to simplify the use of log pages.
  * The logs are now kept in a table which is easier to manage and trim
@@ -292,22 +294,23 @@ class LogPage {
                        return $title->getPrefixedText();
                }
 
+               $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
                if ( $title->isSpecialPage() ) {
                        list( $name, $par ) = SpecialPageFactory::resolveAlias( $title->getDBkey() );
 
                        # Use the language name for log titles, rather than Log/X
                        if ( $name == 'Log' ) {
                                $logPage = new LogPage( $par );
-                               $titleLink = Linker::link( $title, $logPage->getName()->escaped() );
+                               $titleLink = $linkRenderer->makeLink( $title, $logPage->getName()->text() );
                                $titleLink = wfMessage( 'parentheses' )
                                        ->inLanguage( $lang )
                                        ->rawParams( $titleLink )
                                        ->escaped();
                        } else {
-                               $titleLink = Linker::link( $title );
+                               $titleLink = $linkRenderer->makeLink( $title );
                        }
                } else {
-                       $titleLink = Linker::link( $title );
+                       $titleLink = $linkRenderer->makeLink( $title );
                }
 
                return $titleLink;
index c047e96..84653b1 100644 (file)
@@ -36,8 +36,8 @@ class LogPager extends ReverseChronologicalPager {
        /** @var string|Title Events limited to those about Title when set */
        private $title = '';
 
-       /** @var string */
-       private $pattern = '';
+       /** @var bool */
+       private $pattern = false;
 
        /** @var string */
        private $typeCGI = '';
@@ -59,7 +59,7 @@ class LogPager extends ReverseChronologicalPager {
         * @param string|array $types Log types to show
         * @param string $performer The user who made the log entries
         * @param string|Title $title The page title the log entries are for
-        * @param string $pattern Do a prefix search rather than an exact title match
+        * @param bool $pattern Do a prefix search rather than an exact title match
         * @param array $conds Extra conditions for the query
         * @param int|bool $year The year to start from. Default: false
         * @param int|bool $month The month to start from. Default: false
@@ -68,7 +68,7 @@ class LogPager extends ReverseChronologicalPager {
         * @param int $logId Log entry ID, to limit to a single log entry.
         */
        public function __construct( $list, $types = [], $performer = '', $title = '',
-               $pattern = '', $conds = [], $year = false, $month = false, $tagFilter = '',
+               $pattern = false, $conds = [], $year = false, $month = false, $tagFilter = '',
                $action = '', $logId = false
        ) {
                parent::__construct( $list->getContext() );
@@ -194,7 +194,7 @@ class LogPager extends ReverseChronologicalPager {
         * (For the block and rights logs, this is a user page.)
         *
         * @param string|Title $page Title name
-        * @param string $pattern
+        * @param bool $pattern
         * @return void
         */
        private function limitTitle( $page, $pattern ) {
@@ -398,6 +398,9 @@ class LogPager extends ReverseChronologicalPager {
                return $this->title;
        }
 
+       /**
+        * @return bool
+        */
        public function getPattern() {
                return $this->pattern;
        }
index 8775097..7a6fb9d 100644 (file)
@@ -18,7 +18,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  *
  * @file
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.25
  */
 
index 43ca0ea..637a8e7 100644 (file)
@@ -19,7 +19,7 @@
  *
  * @file
  * @author Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.22
  */
 
index 382e4ad..911ab95 100644 (file)
@@ -19,7 +19,7 @@
  *
  * @file
  * @author Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.22
  */
 
index 694fa7f..a08427a 100644 (file)
@@ -19,7 +19,7 @@
  *
  * @file
  * @author Kunal Grover
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.24
  */
 
index 894f59b..e02a703 100644 (file)
@@ -19,7 +19,7 @@
  *
  * @file
  * @author Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.22
  */
 
index 64ec626..931829a 100644 (file)
@@ -18,7 +18,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  *
  * @file
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.26
  */
 
index 4b4d19f..8cdd2af 100644 (file)
@@ -19,7 +19,7 @@
  *
  * @file
  * @author Alexandre Emsenhuber
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.22
  */
 
index 6c53671..a73052d 100644 (file)
@@ -18,7 +18,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  *
  * @file
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.25
  */
 
index 13b5559..19f5144 100644 (file)
@@ -18,7 +18,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  *
  * @file
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  */
 
 /**
index 7b48ad0..bdd4f44 100644 (file)
@@ -198,14 +198,8 @@ class UserMailer {
        private static function isMailMimeUsable() {
                static $usable = null;
                if ( $usable === null ) {
-                       // If the class is not already loaded, and it's in the include path,
-                       // try requiring it.
-                       if ( !class_exists( 'Mail_mime' ) && stream_resolve_include_path( 'Mail/mime.php' ) ) {
-                               require_once 'Mail/mime.php';
-                       }
                        $usable = class_exists( 'Mail_mime' );
                }
-
                return $usable;
        }
 
@@ -218,11 +212,6 @@ class UserMailer {
        private static function isMailUsable() {
                static $usable = null;
                if ( $usable === null ) {
-                       // If the class is not already loaded, and it's in the include path,
-                       // try requiring it.
-                       if ( !class_exists( 'Mail' ) && stream_resolve_include_path( 'Mail.php' ) ) {
-                               require_once 'Mail.php';
-                       }
                        $usable = class_exists( 'Mail' );
                }
 
@@ -396,7 +385,7 @@ class UserMailer {
                        Wikimedia\suppressWarnings();
 
                        // Create the mail object using the Mail::factory method
-                       $mail_object =& Mail::factory( 'smtp', $wgSMTP );
+                       $mail_object = Mail::factory( 'smtp', $wgSMTP );
                        if ( PEAR::isError( $mail_object ) ) {
                                wfDebug( "PEAR::Mail factory failed: " . $mail_object->getMessage() . "\n" );
                                Wikimedia\restoreWarnings();
index a38e79b..e4de0a1 100644 (file)
@@ -20,7 +20,7 @@
  * @ingroup Media
  * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
  * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason, 2009 Brent Garber
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ * @license GPL-2.0-or-later
  * @see http://exif.org/Exif2-2.PDF The Exif 2.2 specification
  * @file
  */
index f683da2..2a8b375 100644 (file)
@@ -20,7 +20,7 @@
  * @ingroup Media
  * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
  * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason, 2009 Brent Garber, 2010 Brian Wolff
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ * @license GPL-2.0-or-later
  * @see http://exif.org/Exif2-2.PDF The Exif 2.2 specification
  * @file
  */
index fc93b23..e00a5b3 100644 (file)
@@ -22,7 +22,7 @@
  * @author "Derk-Jan Hartman <hartman _at_ videolan d0t org>"
  * @author Brion Vibber
  * @copyright Copyright © 2010-2010 Brion Vibber, Derk-Jan Hartman
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ * @license GPL-2.0-or-later
  */
 
 /**
index b66031c..dfd9602 100644 (file)
@@ -138,6 +138,9 @@ class Parser {
        const TOC_START = '<mw:toc>';
        const TOC_END = '</mw:toc>';
 
+       /** @var int Assume that no output will later be saved this many seconds after parsing */
+       const MAX_TTS = 900;
+
        # Persistent:
        public $mTagHooks = [];
        public $mTransparentTagHooks = [];
@@ -2652,39 +2655,19 @@ class Parser {
                                }
                                break;
                        case 'revisionday':
-                               # Let the edit saving system know we should parse the page
-                               # *after* a revision ID has been assigned. This is for null edits.
-                               $this->mOutput->setFlag( 'vary-revision' );
-                               wfDebug( __METHOD__ . ": {{REVISIONDAY}} used, setting vary-revision...\n" );
-                               $value = intval( substr( $this->getRevisionTimestamp(), 6, 2 ) );
+                               $value = (int)$this->getRevisionTimestampSubstring( 6, 2, self::MAX_TTS, $index );
                                break;
                        case 'revisionday2':
-                               # Let the edit saving system know we should parse the page
-                               # *after* a revision ID has been assigned. This is for null edits.
-                               $this->mOutput->setFlag( 'vary-revision' );
-                               wfDebug( __METHOD__ . ": {{REVISIONDAY2}} used, setting vary-revision...\n" );
-                               $value = substr( $this->getRevisionTimestamp(), 6, 2 );
+                               $value = $this->getRevisionTimestampSubstring( 6, 2, self::MAX_TTS, $index );
                                break;
                        case 'revisionmonth':
-                               # Let the edit saving system know we should parse the page
-                               # *after* a revision ID has been assigned. This is for null edits.
-                               $this->mOutput->setFlag( 'vary-revision' );
-                               wfDebug( __METHOD__ . ": {{REVISIONMONTH}} used, setting vary-revision...\n" );
-                               $value = substr( $this->getRevisionTimestamp(), 4, 2 );
+                               $value = $this->getRevisionTimestampSubstring( 4, 2, self::MAX_TTS, $index );
                                break;
                        case 'revisionmonth1':
-                               # Let the edit saving system know we should parse the page
-                               # *after* a revision ID has been assigned. This is for null edits.
-                               $this->mOutput->setFlag( 'vary-revision' );
-                               wfDebug( __METHOD__ . ": {{REVISIONMONTH1}} used, setting vary-revision...\n" );
-                               $value = intval( substr( $this->getRevisionTimestamp(), 4, 2 ) );
+                               $value = (int)$this->getRevisionTimestampSubstring( 4, 2, self::MAX_TTS, $index );
                                break;
                        case 'revisionyear':
-                               # Let the edit saving system know we should parse the page
-                               # *after* a revision ID has been assigned. This is for null edits.
-                               $this->mOutput->setFlag( 'vary-revision' );
-                               wfDebug( __METHOD__ . ": {{REVISIONYEAR}} used, setting vary-revision...\n" );
-                               $value = substr( $this->getRevisionTimestamp(), 0, 4 );
+                               $value = $this->getRevisionTimestampSubstring( 0, 4, self::MAX_TTS, $index );
                                break;
                        case 'revisiontimestamp':
                                # Let the edit saving system know we should parse the page
@@ -2842,6 +2825,38 @@ class Parser {
                return $value;
        }
 
+       /**
+        * @param int $start
+        * @param int $len
+        * @param int $mtts Max time-till-save; sets vary-revision if result might change by then
+        * @param string $variable Parser variable name
+        * @return string
+        */
+       private function getRevisionTimestampSubstring( $start, $len, $mtts, $variable ) {
+               global $wgContLang;
+
+               # Get the timezone-adjusted timestamp to be used for this revision
+               $resNow = substr( $this->getRevisionTimestamp(), $start, $len );
+               # Possibly set vary-revision if there is not yet an associated revision
+               if ( !$this->getRevisionObject() ) {
+                       # Get the timezone-adjusted timestamp $mtts seconds in the future
+                       $resThen = substr(
+                               $wgContLang->userAdjust( wfTimestamp( TS_MW, time() + $mtts ), '' ),
+                               $start,
+                               $len
+                       );
+
+                       if ( $resNow !== $resThen ) {
+                               # Let the edit saving system know we should parse the page
+                               # *after* a revision ID has been assigned. This is for null edits.
+                               $this->mOutput->setFlag( 'vary-revision' );
+                               wfDebug( __METHOD__ . ": $variable used, setting vary-revision...\n" );
+                       }
+               }
+
+               return $resNow;
+       }
+
        /**
         * initialise the magic variables (like CURRENTMONTHNAME) and substitution modifiers
         *
@@ -2997,7 +3012,7 @@ class Parser {
         *       'expansion-depth-exceeded-category')
         * @param string|int|null $current Current value
         * @param string|int|null $max Maximum allowed, when an explicit limit has been
-        *       exceeded, provide the values (optional)
+        *       exceeded, provide the values (optional)
         */
        public function limitationWarn( $limitationType, $current = '', $max = '' ) {
                # does no harm if $current and $max are present but are unnecessary for the message
@@ -3123,11 +3138,8 @@ class Parser {
                                for ( $i = 0; $i < $argsLength; $i++ ) {
                                        $funcArgs[] = $args->item( $i );
                                }
-                               try {
-                                       $result = $this->callParserFunction( $frame, $func, $funcArgs );
-                               } catch ( Exception $ex ) {
-                                       throw $ex;
-                               }
+
+                               $result = $this->callParserFunction( $frame, $func, $funcArgs );
 
                                // Extract any forwarded flags
                                if ( isset( $result['title'] ) ) {
@@ -3677,8 +3689,10 @@ class Parser {
         * @param Title $title
         * @param array $options Array of options to RepoGroup::findFile
         * @return File|bool
+        * @deprecated since 1.32, use fetchFileAndTitle instead
         */
        public function fetchFile( $title, $options = [] ) {
+               wfDeprecated( __METHOD__, '1.32' );
                return $this->fetchFileAndTitle( $title, $options )[0];
        }
 
@@ -5087,17 +5101,15 @@ class Parser {
                                                                } else {
                                                                        // Guess not, consider it as caption.
                                                                        wfDebug( "$parameterMatch failed parameter validation\n" );
-                                                                       $label = '|' . $parameterMatch;
+                                                                       $label = $parameterMatch;
                                                                }
                                                }
 
                                        } else {
                                                // Last pipe wins.
-                                               $label = '|' . $parameterMatch;
+                                               $label = $parameterMatch;
                                        }
                                }
-                               // Remove the pipe.
-                               $label = substr( $label, 1 );
                        }
 
                        $ig->add( $title, $label, $alt, $link, $handlerOptions );
index 8fb9857..20bd599 100644 (file)
@@ -1275,9 +1275,17 @@ class ParserOptions {
        public function optionsHash( $forOptions, $title = null ) {
                global $wgRenderHashAppend;
 
+               $inCacheKey = self::allCacheVaryingOptions();
+
+               // Resolve any lazy options
+               foreach ( array_intersect( $forOptions, $inCacheKey, array_keys( self::$lazyOptions ) ) as $k ) {
+                       if ( $this->options[$k] === null ) {
+                               $this->options[$k] = call_user_func( self::$lazyOptions[$k], $this, $k );
+                       }
+               }
+
                $options = $this->options;
                $defaults = self::getCanonicalOverrides() + self::getDefaults();
-               $inCacheKey = self::$inCacheKey;
 
                // We only include used options with non-canonical values in the key
                // so adding a new option doesn't invalidate the entire parser cache.
@@ -1285,13 +1293,11 @@ class ParserOptions {
                // requires manual invalidation of existing cache entries, as mentioned
                // in the docs on the relevant methods and hooks.
                $values = [];
-               foreach ( $inCacheKey as $option => $include ) {
-                       if ( $include && in_array( $option, $forOptions, true ) ) {
-                               $v = $this->optionToString( $options[$option] );
-                               $d = $this->optionToString( $defaults[$option] );
-                               if ( $v !== $d ) {
-                                       $values[] = "$option=$v";
-                               }
+               foreach ( array_intersect( $inCacheKey, $forOptions ) as $option ) {
+                       $v = $this->optionToString( $options[$option] );
+                       $d = $this->optionToString( $defaults[$option] );
+                       if ( $v !== $d ) {
+                               $values[] = "$option=$v";
                        }
                }
 
index aa015a6..fc36659 100644 (file)
@@ -906,8 +906,7 @@ class ParserOutput extends CacheTime {
         *   * To implement hidden categories, hiding pages from category listings
         *     by storing a property.
         *
-        *   * Overriding the displayed article title.
-        *   @see ParserOutput::setDisplayTitle()
+        *   * Overriding the displayed article title (ParserOutput::setDisplayTitle()).
         *
         *   * To implement image tagging, for example displaying an icon on an
         *     image thumbnail to indicate that it is listed for deletion on
index bf1f8ac..0c52354 100644 (file)
@@ -68,7 +68,7 @@ class UserPasswordPolicy {
         * @param User $user who's policy we are checking
         * @param string $password the password to check
         * @return Status error to indicate the password didn't meet the policy, or fatal to
-        *      indicate the user shouldn't be allowed to login.
+        *      indicate the user shouldn't be allowed to login.
         */
        public function checkUserPassword( User $user, $password ) {
                $effectivePolicy = $this->getPoliciesForUser( $user );
@@ -88,7 +88,7 @@ class UserPasswordPolicy {
         * @param string $password the password to check
         * @param array $groups list of groups to which we assume the user belongs
         * @return Status error to indicate the password didn't meet the policy, or fatal to
-        *      indicate the user shouldn't be allowed to login.
+        *      indicate the user shouldn't be allowed to login.
         */
        public function checkUserPasswordForGroups( User $user, $password, array $groups ) {
                $effectivePolicy = self::getPoliciesForGroups(
index 2d7d73f..eb94ff1 100644 (file)
@@ -45,8 +45,7 @@ use MWTimestamp;
 use OutputPage;
 use Parser;
 use ParserOptions;
-use PreferencesForm;
-use PreferencesFormOOUI;
+use PreferencesFormLegacy;
 use Psr\Log\LoggerAwareTrait;
 use Psr\Log\NullLogger;
 use Skin;
@@ -413,8 +412,9 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                $languageCode = $this->config->get( 'LanguageCode' );
                if ( !array_key_exists( $languageCode, $languages ) ) {
                        $languages[$languageCode] = $languageCode;
+                       // Sort the array again
+                       ksort( $languages );
                }
-               ksort( $languages );
 
                $options = [];
                foreach ( $languages as $code => $name ) {
@@ -1483,12 +1483,12 @@ class DefaultPreferencesFactory implements PreferencesFactory {
         * @param IContextSource $context
         * @param string $formClass
         * @param array $remove Array of items to remove
-        * @return PreferencesForm
+        * @return HTMLForm
         */
        public function getForm(
                User $user,
                IContextSource $context,
-               $formClass = PreferencesFormOOUI::class,
+               $formClass = PreferencesFormLegacy::class,
                array $remove = []
        ) {
                if ( SpecialPreferences::isOouiEnabled( $context ) ) {
@@ -1510,7 +1510,7 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                }
 
                /**
-                * @var $htmlForm PreferencesForm
+                * @var $htmlForm HTMLForm
                 */
                $htmlForm = new $formClass( $formDescriptor, $context, 'prefs' );
 
@@ -1521,7 +1521,7 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                # Used message keys: 'accesskey-preferences-save', 'tooltip-preferences-save'
                $htmlForm->setSubmitTooltip( 'preferences-save' );
                $htmlForm->setSubmitID( 'prefcontrol' );
-               $htmlForm->setSubmitCallback( function ( array $formData, PreferencesForm $form ) {
+               $htmlForm->setSubmitCallback( function ( array $formData, HTMLForm $form ) {
                        return $this->submitForm( $formData, $form );
                } );
 
@@ -1626,10 +1626,10 @@ class DefaultPreferencesFactory implements PreferencesFactory {
         * Handle the form submission if everything validated properly
         *
         * @param array $formData
-        * @param PreferencesForm $form
+        * @param HTMLForm $form
         * @return bool|Status|string
         */
-       protected function saveFormData( $formData, PreferencesForm $form ) {
+       protected function saveFormData( $formData, HTMLForm $form ) {
                $user = $form->getModifiedUser();
                $hiddenPrefs = $this->config->get( 'HiddenPrefs' );
                $result = true;
@@ -1706,10 +1706,10 @@ class DefaultPreferencesFactory implements PreferencesFactory {
         * @deprecated since 1.31, its inception
         *
         * @param array $formData
-        * @param PreferencesForm $form
+        * @param HTMLForm $form
         * @return bool|Status|string
         */
-       public function legacySaveFormData( $formData, PreferencesForm $form ) {
+       public function legacySaveFormData( $formData, HTMLForm $form ) {
                return $this->saveFormData( $formData, $form );
        }
 
@@ -1717,10 +1717,10 @@ class DefaultPreferencesFactory implements PreferencesFactory {
         * Save the form data and reload the page
         *
         * @param array $formData
-        * @param PreferencesForm $form
+        * @param HTMLForm $form
         * @return Status
         */
-       protected function submitForm( array $formData, PreferencesForm $form ) {
+       protected function submitForm( array $formData, HTMLForm $form ) {
                $res = $this->saveFormData( $formData, $form );
 
                if ( $res ) {
@@ -1758,10 +1758,10 @@ class DefaultPreferencesFactory implements PreferencesFactory {
         * @deprecated since 1.31, its inception
         *
         * @param array $formData
-        * @param PreferencesForm $form
+        * @param HTMLForm $form
         * @return Status
         */
-       public function legacySubmitForm( array $formData, PreferencesForm $form ) {
+       public function legacySubmitForm( array $formData, HTMLForm $form ) {
                return $this->submitForm( $formData, $form );
        }
 
index 685f78c..478edce 100644 (file)
@@ -28,8 +28,8 @@ use User;
  * A PreferencesFactory is a MediaWiki service that provides the definitions of preferences for a
  * given user. These definitions are in the form of an HTMLForm descriptor.
  *
- * PreferencesForm (a subclass of HTMLForm) is used to generate the Preferences form, and handles
- * generic submission, CSRF protection, layout and other logic in a reusable manner.
+ * PreferencesFormLegacy (a subclass of HTMLForm) is used to generate the Preferences form, and
+ * handles generic submission, CSRF protection, layout and other logic in a reusable manner.
  *
  * In order to generate the form, the HTMLForm object needs an array structure detailing the
  * form fields available, and that's what this implementations of this interface provide. Each
@@ -62,7 +62,7 @@ interface PreferencesFactory {
        public function getForm(
                User $user,
                IContextSource $contextSource,
-               $formClass = \PreferencesForm::class,
+               $formClass = \PreferencesFormLegacy::class,
                array $remove = []
        );
 
index 7e3afaa..564ea6b 100644 (file)
@@ -89,20 +89,34 @@ class ExtensionJsonValidator {
                        );
                }
 
-               $licenseError = false;
+               $extraErrors = [];
                // Check if it's a string, if not, schema validation will display an error
                if ( isset( $data->{'license-name'} ) && is_string( $data->{'license-name'} ) ) {
                        $licenses = new SpdxLicenses();
                        $valid = $licenses->validate( $data->{'license-name'} );
                        if ( !$valid ) {
-                               $licenseError = '[license-name] Invalid SPDX license identifier, '
+                               $extraErrors[] = '[license-name] Invalid SPDX license identifier, '
                                        . 'see <https://spdx.org/licenses/>';
                        }
                }
+               if ( isset( $data->url ) && is_string( $data->url ) ) {
+                       $parsed = wfParseUrl( $data->url );
+                       $mwoUrl = false;
+                       if ( $parsed['host'] === 'www.mediawiki.org' ) {
+                               $mwoUrl = true;
+                       } elseif ( $parsed['host'] === 'mediawiki.org' ) {
+                               $mwoUrl = true;
+                               $extraErrors[] = '[url] Should use www.mediawiki.org domain';
+                       }
+
+                       if ( $mwoUrl && $parsed['scheme'] !== 'https' ) {
+                               $extraErrors[] = '[url] Should use HTTPS for www.mediawiki.org URLs';
+                       }
+               }
 
                $validator = new Validator;
                $validator->check( $data, (object)[ '$ref' => 'file://' . $schemaPath ] );
-               if ( $validator->isValid() && !$licenseError ) {
+               if ( $validator->isValid() && !$extraErrors ) {
                        // All good.
                        return true;
                } else {
@@ -110,8 +124,8 @@ class ExtensionJsonValidator {
                        foreach ( $validator->getErrors() as $error ) {
                                $out .= "[{$error['property']}] {$error['message']}\n";
                        }
-                       if ( $licenseError ) {
-                               $out .= "$licenseError\n";
+                       if ( $extraErrors ) {
+                               $out .= implode( "\n", $extraErrors ) . "\n";
                        }
                        throw new ExtensionJsonValidationError( $out );
                }
index 0d0a6e4..14d4a17 100644 (file)
@@ -186,12 +186,6 @@ class ExtensionProcessor implements Processor {
         */
        public function extractInfo( $path, array $info, $version ) {
                $dir = dirname( $path );
-               if ( $version === 2 ) {
-                       $this->extractConfig2( $info, $dir );
-               } else {
-                       // $version === 1
-                       $this->extractConfig1( $info );
-               }
                $this->extractHooks( $info );
                $this->extractExtensionMessagesFiles( $dir, $info );
                $this->extractMessagesDirs( $dir, $info );
@@ -216,6 +210,15 @@ class ExtensionProcessor implements Processor {
                        $this->callbacks[$name] = $info['callback'];
                }
 
+               // config should be after all core globals are extracted,
+               // so duplicate setting detection will work fully
+               if ( $version === 2 ) {
+                       $this->extractConfig2( $info, $dir );
+               } else {
+                       // $version === 1
+                       $this->extractConfig1( $info );
+               }
+
                if ( $version === 2 ) {
                        $this->extractAttributes( $path, $info );
                }
@@ -463,7 +466,7 @@ class ExtensionProcessor implements Processor {
                        }
                        foreach ( $info['config'] as $key => $val ) {
                                if ( $key[0] !== '@' ) {
-                                       $this->addConfigGlobal( "$prefix$key", $val );
+                                       $this->addConfigGlobal( "$prefix$key", $val, $info['name'] );
                                }
                        }
                }
@@ -491,7 +494,7 @@ class ExtensionProcessor implements Processor {
                                if ( isset( $data['path'] ) && $data['path'] ) {
                                        $value = "$dir/$value";
                                }
-                               $this->addConfigGlobal( "$prefix$key", $value );
+                               $this->addConfigGlobal( "$prefix$key", $value, $info['name'] );
                        }
                }
        }
@@ -501,12 +504,13 @@ class ExtensionProcessor implements Processor {
         *
         * @param string $key The config key with the prefix and anything
         * @param mixed $value The value of the config
+        * @param string $extName Name of the extension
         */
-       private function addConfigGlobal( $key, $value ) {
+       private function addConfigGlobal( $key, $value, $extName ) {
                if ( array_key_exists( $key, $this->globals ) ) {
                        throw new RuntimeException(
-                               "The configuration setting '$key' was already set by another extension,"
-                               . " and cannot be set again." );
+                               "The configuration setting '$key' was already set by MediaWiki core or"
+                               . " another extension, and cannot be set again by $extName." );
                }
                $this->globals[$key] = $value;
        }
index 90c3140..f3b6a70 100644 (file)
@@ -1503,13 +1503,24 @@ MESSAGE;
         * startup module if the client has adequate support for MediaWiki JavaScript code.
         *
         * @param string $script JavaScript code
-        * @return WrappedString HTML
+        * @param string $nonce [optional] Content-Security-Policy nonce (from OutputPage::getCSPNonce)
+        * @return string|WrappedString HTML
         */
-       public static function makeInlineScript( $script ) {
+       public static function makeInlineScript( $script, $nonce = null ) {
                $js = self::makeLoaderConditionalScript( $script );
+               $escNonce = '';
+               if ( $nonce === null ) {
+                       wfWarn( __METHOD__ . " did not get nonce. Will break CSP" );
+               } elseif ( $nonce !== false ) {
+                       // If it was false, CSP is disabled, so no nonce attribute.
+                       // Nonce should be only base64 characters, so should be safe,
+                       // but better to be safely escaped than sorry.
+                       $escNonce = ' nonce="' . htmlspecialchars( $nonce ) . '"';
+               }
+
                return new WrappedString(
-                       Html::inlineScript( $js ),
-                       '<script>(window.RLQ=window.RLQ||[]).push(function(){',
+                       Html::inlineScript( $js, $nonce ),
+                       "<script$escNonce>(window.RLQ=window.RLQ||[]).push(function(){",
                        '});</script>'
                );
        }
@@ -1693,12 +1704,14 @@ MESSAGE;
         * Returns LESS compiler set up for use with MediaWiki
         *
         * @since 1.27
-        * @param array $extraVars Associative array of extra (i.e., other than the
-        *   globally-configured ones) that should be used for compilation.
+        * @param array $vars Associative array of variables that should be used
+        *  for compilation. Since 1.32, this method no longer automatically includes
+        *  global LESS vars from ResourceLoader::getLessVars (T191937).
         * @throws MWException
         * @return Less_Parser
         */
-       public function getLessCompiler( $extraVars = [] ) {
+       public function getLessCompiler( $vars = [] ) {
+               global $IP;
                // When called from the installer, it is possible that a required PHP extension
                // is missing (at least for now; see T49564). If this is the case, throw an
                // exception (caught by the installer) to prevent a fatal error later on.
@@ -1707,10 +1720,10 @@ MESSAGE;
                }
 
                $parser = new Less_Parser;
-               $parser->ModifyVars( array_merge( $this->getLessVars(), $extraVars ) );
-               $parser->SetImportDirs(
-                       array_fill_keys( $this->config->get( 'ResourceLoaderLESSImportPaths' ), '' )
-               );
+               $parser->ModifyVars( $vars );
+               $parser->SetImportDirs( [
+                       "$IP/resources/src/mediawiki.less/" => '',
+               );
                $parser->SetOption( 'relativeUrls', false );
 
                return $parser;
index bb8ab32..b9ff732 100644 (file)
@@ -18,6 +18,7 @@
  * @file
  */
 
+use Wikimedia\WrappedString;
 use Wikimedia\WrappedStringList;
 
 /**
@@ -57,12 +58,18 @@ class ResourceLoaderClientHtml {
        /**
         * @param ResourceLoaderContext $context
         * @param array $options [optional] Array of options
-        *  - 'target': Custom parameter passed to StartupModule.
+        *  - 'target': Parameter for modules=startup request, see ResourceLoaderStartUpModule.
+        *  - 'safemode': Parameter for modules=startup request, see ResourceLoaderStartUpModule.
+        *  - 'nonce': From OutputPage::getCSPNonce().
         */
        public function __construct( ResourceLoaderContext $context, array $options = [] ) {
                $this->context = $context;
                $this->resourceLoader = $context->getResourceLoader();
-               $this->options = $options;
+               $this->options = $options + [
+                       'target' => null,
+                       'safemode' => null,
+                       'nonce' => null,
+               ];
        }
 
        /**
@@ -139,7 +146,8 @@ class ResourceLoaderClientHtml {
                                'styles' => [],
                                'general' => [],
                        ],
-
+                       // Deprecations for style-only modules
+                       'styleDeprecations' => [],
                ];
 
                foreach ( $this->modules as $name ) {
@@ -204,6 +212,10 @@ class ResourceLoaderClientHtml {
                                        $data['styles'][] = $name;
                                }
                        }
+                       $deprecation = $module->getDeprecationInformation();
+                       if ( $deprecation ) {
+                               $data['styleDeprecations'][] = $deprecation;
+                       }
                }
 
                foreach ( $this->moduleScripts as $name ) {
@@ -251,6 +263,7 @@ class ResourceLoaderClientHtml {
         * @return string|WrappedStringList HTML
         */
        public function getHeadHtml() {
+               $nonce = $this->options['nonce'];
                $data = $this->getData();
                $chunks = [];
 
@@ -259,13 +272,15 @@ class ResourceLoaderClientHtml {
                // See also #getDocumentAttributes() and /resources/src/startup.js.
                $chunks[] = Html::inlineScript(
                        'document.documentElement.className = document.documentElement.className'
-                       . '.replace( /(^|\s)client-nojs(\s|$)/, "$1client-js$2" );'
+                       . '.replace( /(^|\s)client-nojs(\s|$)/, "$1client-js$2" );',
+                       $nonce
                );
 
                // Inline RLQ: Set page variables
                if ( $this->config ) {
                        $chunks[] = ResourceLoader::makeInlineScript(
-                               ResourceLoader::makeConfigSetScript( $this->config )
+                               ResourceLoader::makeConfigSetScript( $this->config ),
+                               $nonce
                        );
                }
 
@@ -273,7 +288,8 @@ class ResourceLoaderClientHtml {
                $states = array_merge( $this->exemptStates, $data['states'] );
                if ( $states ) {
                        $chunks[] = ResourceLoader::makeInlineScript(
-                               ResourceLoader::makeLoaderStateScript( $states )
+                               ResourceLoader::makeLoaderStateScript( $states ),
+                               $nonce
                        );
                }
 
@@ -281,14 +297,16 @@ class ResourceLoaderClientHtml {
                if ( $data['embed']['general'] ) {
                        $chunks[] = $this->getLoad(
                                $data['embed']['general'],
-                               ResourceLoaderModule::TYPE_COMBINED
+                               ResourceLoaderModule::TYPE_COMBINED,
+                               $nonce
                        );
                }
 
                // Inline RLQ: Load general modules
                if ( $data['general'] ) {
                        $chunks[] = ResourceLoader::makeInlineScript(
-                               Xml::encodeJsCall( 'mw.loader.load', [ $data['general'] ] )
+                               Xml::encodeJsCall( 'mw.loader.load', [ $data['general'] ] ),
+                               $nonce
                        );
                }
 
@@ -296,15 +314,17 @@ class ResourceLoaderClientHtml {
                if ( $data['scripts'] ) {
                        $chunks[] = $this->getLoad(
                                $data['scripts'],
-                               ResourceLoaderModule::TYPE_SCRIPTS
+                               ResourceLoaderModule::TYPE_SCRIPTS,
+                               $nonce
                        );
                }
 
-               // External stylesheets
+               // External stylesheets (only=styles)
                if ( $data['styles'] ) {
                        $chunks[] = $this->getLoad(
                                $data['styles'],
-                               ResourceLoaderModule::TYPE_STYLES
+                               ResourceLoaderModule::TYPE_STYLES,
+                               $nonce
                        );
                }
 
@@ -312,37 +332,53 @@ class ResourceLoaderClientHtml {
                if ( $data['embed']['styles'] ) {
                        $chunks[] = $this->getLoad(
                                $data['embed']['styles'],
-                               ResourceLoaderModule::TYPE_STYLES
+                               ResourceLoaderModule::TYPE_STYLES,
+                               $nonce
                        );
                }
 
                // Async scripts. Once the startup is loaded, inline RLQ scripts will run.
                // Pass-through a custom 'target' from OutputPage (T143066).
-               $startupQuery = isset( $this->options['target'] )
-                       ? [ 'target' => (string)$this->options['target'] ]
-                       : [];
+               $startupQuery = [];
+               foreach ( [ 'target', 'safemode' ] as $param ) {
+                       if ( $this->options[$param] !== null ) {
+                               $startupQuery[$param] = (string)$this->options[$param];
+                       }
+               }
                $chunks[] = $this->getLoad(
                        'startup',
                        ResourceLoaderModule::TYPE_SCRIPTS,
+                       $nonce,
                        $startupQuery
                );
 
-               return WrappedStringList::join( "\n", $chunks );
+               return WrappedString::join( "\n", $chunks );
        }
 
        /**
         * @return string|WrappedStringList HTML
         */
        public function getBodyHtml() {
-               return '';
+               $data = $this->getData();
+               $chunks = [];
+
+               // Deprecations for only=styles modules
+               if ( $data['styleDeprecations'] ) {
+                       $chunks[] = ResourceLoader::makeInlineScript(
+                               implode( '', $data['styleDeprecations'] ),
+                               $this->options['nonce']
+                       );
+               }
+
+               return WrappedString::join( "\n", $chunks );
        }
 
        private function getContext( $group, $type ) {
                return self::makeContext( $this->context, $group, $type );
        }
 
-       private function getLoad( $modules, $only, array $extraQuery = [] ) {
-               return self::makeLoad( $this->context, (array)$modules, $only, $extraQuery );
+       private function getLoad( $modules, $only, $nonce, array $extraQuery = [] ) {
+               return self::makeLoad( $this->context, (array)$modules, $only, $extraQuery, $nonce );
        }
 
        private static function makeContext( ResourceLoaderContext $mainContext, $group, $type,
@@ -370,10 +406,11 @@ class ResourceLoaderClientHtml {
         * @param array $modules One or more module names
         * @param string $only ResourceLoaderModule TYPE_ class constant
         * @param array $extraQuery [optional] Array with extra query parameters for the request
+        * @param string $nonce [optional] Content-Security-Policy nonce (from OutputPage::getCSPNonce)
         * @return string|WrappedStringList HTML
         */
        public static function makeLoad( ResourceLoaderContext $mainContext, array $modules, $only,
-               array $extraQuery = []
+               array $extraQuery = [], $nonce = null
        ) {
                $rl = $mainContext->getResourceLoader();
                $chunks = [];
@@ -385,7 +422,7 @@ class ResourceLoaderClientHtml {
                        $chunks = [];
                        // Recursively call us for every item
                        foreach ( $modules as $name ) {
-                               $chunks[] = self::makeLoad( $mainContext, [ $name ], $only, $extraQuery );
+                               $chunks[] = self::makeLoad( $mainContext, [ $name ], $only, $extraQuery, $nonce );
                        }
                        return new WrappedStringList( "\n", $chunks );
                }
@@ -427,7 +464,8 @@ class ResourceLoaderClientHtml {
                                                        );
                                                } else {
                                                        $chunks[] = ResourceLoader::makeInlineScript(
-                                                               $rl->makeModuleResponse( $context, $moduleSet )
+                                                               $rl->makeModuleResponse( $context, $moduleSet ),
+                                                               $nonce
                                                        );
                                                }
                                        } else {
@@ -461,7 +499,8 @@ class ResourceLoaderClientHtml {
                                                                ] );
                                                        } else {
                                                                $chunk = ResourceLoader::makeInlineScript(
-                                                                       Xml::encodeJsCall( 'mw.loader.load', [ $url ] )
+                                                                       Xml::encodeJsCall( 'mw.loader.load', [ $url ] ),
+                                                                       $nonce
                                                                );
                                                        }
                                                }
index f2f3383..7f8c7f5 100644 (file)
@@ -959,9 +959,12 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                        $cache = ObjectCache::getLocalServerInstance( CACHE_ANYTHING );
                }
 
-               // Construct a cache key from the LESS file name and a hash digest
+               $vars = array_merge(
+                       $context->getResourceLoader()->getLessVars(),
+                       $this->getLessVars( $context )
+               );
+               // Construct a cache key from the LESS file name, and a hash digest
                // of the LESS variables used for compilation.
-               $vars = $this->getLessVars( $context );
                ksort( $vars );
                $varsHash = hash( 'md4', serialize( $vars ) );
                $cacheKey = $cache->makeGlobalKey( 'LESS', $fileName, $varsHash );
index 6d1529b..a0a4e58 100644 (file)
@@ -139,7 +139,7 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
         *
         * @return string JavaScript code
         */
-       protected function getDeprecationInformation() {
+       public function getDeprecationInformation() {
                $deprecationInfo = $this->deprecated;
                if ( $deprecationInfo ) {
                        $name = $this->getName();
@@ -318,9 +318,9 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
        }
 
        /**
-        * Get the origin of this module. Should only be overridden for foreign modules.
+        * Get the source of this module. Should only be overridden for foreign modules.
         *
-        * @return string Origin name, 'local' for local modules
+        * @return string Source name, 'local' for local modules
         */
        public function getSource() {
                // Stub, override expected
index 2e3c6fc..0416c85 100644 (file)
  * the ability to vary based extra query parameters, in addition to those
  * from ResourceLoaderContext:
  *
- * - target: Only register modules in the client allowed within this target.
+ * - target: Only register modules in the client intended for this target.
  *   Default: "desktop".
  *   See also: OutputPage::setTarget(), ResourceLoaderModule::getTargets().
+ *
+ * - safemode: Only register modules that have ORIGIN_CORE as their origin.
+ *   This effectively disables ORIGIN_USER modules. (T185303)
+ *   See also: OutputPage::disallowUserJs()
  */
 class ResourceLoaderStartUpModule extends ResourceLoaderModule {
 
@@ -171,10 +175,10 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
         * Optimize the dependency tree in $this->modules.
         *
         * The optimization basically works like this:
-        *      Given we have module A with the dependencies B and C
-        *              and module B with the dependency C.
-        *      Now we don't have to tell the client to explicitly fetch module
-        *              C as that's already included in module B.
+        *      Given we have module A with the dependencies B and C
+        *              and module B with the dependency C.
+        *      Now we don't have to tell the client to explicitly fetch module
+        *              C as that's already included in module B.
         *
         * This way we can reasonably reduce the amount of module registration
         * data send to the client.
@@ -208,6 +212,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                // Future developers: Use WebRequest::getRawVal() instead getVal().
                // The getVal() method performs slow Language+UTF logic. (f303bb9360)
                $target = $context->getRequest()->getRawVal( 'target', 'desktop' );
+               $safemode = $context->getRequest()->getRawVal( 'safemode' ) === '1';
                // Bypass target filter if this request is Special:JavaScriptTest.
                // To prevent misuse in production, this is only allowed if testing is enabled server-side.
                $byPassTargetFilter = $this->getConfig()->get( 'EnableJavaScriptTest' ) && $target === 'test';
@@ -220,7 +225,10 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                foreach ( $resourceLoader->getModuleNames() as $name ) {
                        $module = $resourceLoader->getModule( $name );
                        $moduleTargets = $module->getTargets();
-                       if ( !$byPassTargetFilter && !in_array( $target, $moduleTargets ) ) {
+                       if (
+                               ( !$byPassTargetFilter && !in_array( $target, $moduleTargets ) )
+                               || ( $safemode && $module->getOrigin() > ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL )
+                       ) {
                                continue;
                        }
 
index e747373..026cea1 100644 (file)
@@ -77,12 +77,4 @@ class ResourceLoaderUserModule extends ResourceLoaderWikiModule {
        public function getGroup() {
                return 'user';
        }
-
-       /**
-        * @param ResourceLoaderContext|null $context
-        * @return array
-        */
-       public function getDependencies( ResourceLoaderContext $context = null ) {
-               return [ 'user.styles' ];
-       }
 }
index 7e6e8e6..bd48e21 100644 (file)
@@ -69,12 +69,25 @@ abstract class SearchEngine {
        /**
         * Perform a full text search query and return a result set.
         * If full text searches are not supported or disabled, return null.
-        * STUB
+        *
+        * As of 1.32 overriding this function is deprecated. It will
+        * be converted to final in 1.34. Override self::doSearchText().
         *
         * @param string $term Raw search term
         * @return SearchResultSet|Status|null
         */
-       function searchText( $term ) {
+       public function searchText( $term ) {
+               return $this->doSearchText( $term );
+       }
+
+       /**
+        * Perform a full text search query and return a result set.
+        *
+        * @param string $term Raw search term
+        * @return SearchResultSet|Status|null
+        * @since 1.32
+        */
+       protected function doSearchText( $term ) {
                return null;
        }
 
@@ -85,11 +98,25 @@ abstract class SearchEngine {
         * The results returned by this methods are only sugegstions and
         * may not end up being shown to the user.
         *
+        * As of 1.32 overriding this function is deprecated. It will
+        * be converted to final in 1.34. Override self::doSearchArchiveTitle().
+        *
         * @param string $term Raw search term
         * @return Status<Title[]>
         * @since 1.29
         */
-       function searchArchiveTitle( $term ) {
+       public function searchArchiveTitle( $term ) {
+               return $this->doSearchArchiveTitle( $term );
+       }
+
+       /**
+        * Perform a title search in the article archive.
+        *
+        * @param string $term Raw search term
+        * @return Status<Title[]>
+        * @since 1.32
+        */
+       protected function doSearchArchiveTitle( $term ) {
                return Status::newGood( [] );
        }
 
@@ -98,10 +125,24 @@ abstract class SearchEngine {
         * If title searches are not supported or disabled, return null.
         * STUB
         *
+        * As of 1.32 overriding this function is deprecated. It will
+        * be converted to final in 1.34. Override self::doSearchTitle().
+        *
+        * @param string $term Raw search term
+        * @return SearchResultSet|null
+        */
+       public function searchTitle( $term ) {
+               return $this->doSearchTitle( $term );
+       }
+
+       /**
+        * Perform a title-only search query and return a result set.
+        *
         * @param string $term Raw search term
         * @return SearchResultSet|null
+        * @since 1.32
         */
-       function searchTitle( $term ) {
+       protected function doSearchTitle( $term ) {
                return null;
        }
 
@@ -335,12 +376,25 @@ abstract class SearchEngine {
                        return false;
                }
                $extractedNamespace = null;
+               $allkeywords = [];
+
+               $allkeywords[] = wfMessage( 'searchall' )->inContentLanguage()->text() . ":";
+               // force all: so that we have a common syntax for all the wikis
+               if ( !in_array( 'all:', $allkeywords ) ) {
+                       $allkeywords[] = 'all:';
+               }
+
+               $allQuery = false;
+               foreach ( $allkeywords as $kw ) {
+                       if ( strncmp( $query, $kw, strlen( $kw ) ) == 0 ) {
+                               $extractedNamespace = null;
+                               $parsed = substr( $query, strlen( $kw ) );
+                               $allQuery = true;
+                               break;
+                       }
+               }
 
-               $allkeyword = wfMessage( 'searchall' )->inContentLanguage()->text() . ":";
-               if ( strncmp( $query, $allkeyword, strlen( $allkeyword ) ) == 0 ) {
-                       $extractedNamespace = null;
-                       $parsed = substr( $query, strlen( $allkeyword ) );
-               } elseif ( strpos( $query, ':' ) !== false ) {
+               if ( !$allQuery && strpos( $query, ':' ) !== false ) {
                        // TODO: should we unify with PrefixSearch::extractNamespace ?
                        $prefix = str_replace( ' ', '_', substr( $query, 0, strpos( $query, ':' ) ) );
                        $index = $wgContLang->getNsIndex( $prefix );
index 57ca06e..43bd3be 100644 (file)
@@ -31,9 +31,8 @@ class SearchMssql extends SearchDatabase {
         *
         * @param string $term Raw search term
         * @return SqlSearchResultSet
-        * @access public
         */
-       function searchText( $term ) {
+       protected function doSearchText( $term ) {
                $resultSet = $this->db->query( $this->getQuery( $this->filter( $term ), true ) );
                return new SqlSearchResultSet( $resultSet, $this->searchTerms );
        }
@@ -43,9 +42,8 @@ class SearchMssql extends SearchDatabase {
         *
         * @param string $term Raw search term
         * @return SqlSearchResultSet
-        * @access public
         */
-       function searchTitle( $term ) {
+       protected function doSearchTitle( $term ) {
                $resultSet = $this->db->query( $this->getQuery( $this->filter( $term ), false ) );
                return new SqlSearchResultSet( $resultSet, $this->searchTerms );
        }
@@ -54,9 +52,8 @@ class SearchMssql extends SearchDatabase {
         * Return a partial WHERE clause to limit the search to the given namespaces
         *
         * @return string
-        * @private
         */
-       function queryNamespaces() {
+       private function queryNamespaces() {
                $namespaces = implode( ',', $this->namespaces );
                if ( $namespaces == '' ) {
                        $namespaces = '0';
@@ -71,7 +68,7 @@ class SearchMssql extends SearchDatabase {
         *
         * @return string
         */
-       function queryLimit( $sql ) {
+       private function queryLimit( $sql ) {
                return $this->db->limitResult( $sql, $this->limit, $this->offset );
        }
 
@@ -95,7 +92,7 @@ class SearchMssql extends SearchDatabase {
         * @param bool $fulltext
         * @return string
         */
-       function getQuery( $filteredTerm, $fulltext ) {
+       private function getQuery( $filteredTerm, $fulltext ) {
                return $this->queryLimit( $this->queryMain( $filteredTerm, $fulltext ) . ' ' .
                        $this->queryNamespaces() . ' ' .
                        $this->queryRanking( $filteredTerm, $fulltext ) . ' ' );
@@ -117,9 +114,8 @@ class SearchMssql extends SearchDatabase {
         * @param string $filteredTerm
         * @param bool $fulltext
         * @return string
-        * @private
         */
-       function queryMain( $filteredTerm, $fulltext ) {
+       private function queryMain( $filteredTerm, $fulltext ) {
                $match = $this->parseQuery( $filteredTerm, $fulltext );
                $page = $this->db->tableName( 'page' );
                $searchindex = $this->db->tableName( 'searchindex' );
@@ -134,7 +130,7 @@ class SearchMssql extends SearchDatabase {
         * @param bool $fulltext
         * @return string
         */
-       function parseQuery( $filteredText, $fulltext ) {
+       private function parseQuery( $filteredText, $fulltext ) {
                global $wgContLang;
                $lc = $this->legalSearchChars( self::CHARS_NO_SYNTAX );
                $this->searchTerms = [];
index c98f7e3..9a03ebe 100644 (file)
@@ -42,7 +42,7 @@ class SearchMySQL extends SearchDatabase {
         *
         * @return array
         */
-       function parseQuery( $filteredText, $fulltext ) {
+       private function parseQuery( $filteredText, $fulltext ) {
                global $wgContLang;
 
                $lc = $this->legalSearchChars( self::CHARS_NO_SYNTAX ); // Minus syntax chars (" and *)
@@ -133,7 +133,7 @@ class SearchMySQL extends SearchDatabase {
                ];
        }
 
-       function regexTerm( $string, $wildcard ) {
+       private function regexTerm( $string, $wildcard ) {
                global $wgContLang;
 
                $regex = preg_quote( $string, '/' );
@@ -167,7 +167,7 @@ class SearchMySQL extends SearchDatabase {
         * @param string $term Raw search term
         * @return SqlSearchResultSet
         */
-       function searchText( $term ) {
+       protected function doSearchText( $term ) {
                return $this->searchInternal( $term, true );
        }
 
@@ -177,7 +177,7 @@ class SearchMySQL extends SearchDatabase {
         * @param string $term Raw search term
         * @return SqlSearchResultSet
         */
-       function searchTitle( $term ) {
+       protected function doSearchTitle( $term ) {
                return $this->searchInternal( $term, false );
        }
 
@@ -264,7 +264,7 @@ class SearchMySQL extends SearchDatabase {
         * @return array
         * @since 1.18 (changed)
         */
-       function getQuery( $filteredTerm, $fulltext ) {
+       private function getQuery( $filteredTerm, $fulltext ) {
                $query = [
                        'tables' => [],
                        'fields' => [],
@@ -286,7 +286,7 @@ class SearchMySQL extends SearchDatabase {
         * @param bool $fulltext
         * @return string
         */
-       function getIndexField( $fulltext ) {
+       private function getIndexField( $fulltext ) {
                return $fulltext ? 'si_text' : 'si_title';
        }
 
@@ -298,7 +298,7 @@ class SearchMySQL extends SearchDatabase {
         * @param bool $fulltext
         * @since 1.18 (changed)
         */
-       function queryMain( &$query, $filteredTerm, $fulltext ) {
+       private function queryMain( &$query, $filteredTerm, $fulltext ) {
                $match = $this->parseQuery( $filteredTerm, $fulltext );
                $query['tables'][] = 'page';
                $query['tables'][] = 'searchindex';
@@ -316,7 +316,7 @@ class SearchMySQL extends SearchDatabase {
         * @param bool $fulltext
         * @return array
         */
-       function getCountQuery( $filteredTerm, $fulltext ) {
+       private function getCountQuery( $filteredTerm, $fulltext ) {
                $match = $this->parseQuery( $filteredTerm, $fulltext );
 
                $query = [
index 8bcd78f..7fe5b53 100644 (file)
@@ -64,7 +64,7 @@ class SearchOracle extends SearchDatabase {
         * @param string $term Raw search term
         * @return SqlSearchResultSet
         */
-       function searchText( $term ) {
+       protected function doSearchText( $term ) {
                if ( $term == '' ) {
                        return new SqlSearchResultSet( false, '' );
                }
@@ -79,7 +79,7 @@ class SearchOracle extends SearchDatabase {
         * @param string $term Raw search term
         * @return SqlSearchResultSet
         */
-       function searchTitle( $term ) {
+       protected function doSearchTitle( $term ) {
                if ( $term == '' ) {
                        return new SqlSearchResultSet( false, '' );
                }
@@ -92,7 +92,7 @@ class SearchOracle extends SearchDatabase {
         * Return a partial WHERE clause to limit the search to the given namespaces
         * @return string
         */
-       function queryNamespaces() {
+       private function queryNamespaces() {
                if ( is_null( $this->namespaces ) ) {
                        return '';
                }
@@ -111,7 +111,7 @@ class SearchOracle extends SearchDatabase {
         *
         * @return string
         */
-       function queryLimit( $sql ) {
+       private function queryLimit( $sql ) {
                return $this->db->limitResult( $sql, $this->limit, $this->offset );
        }
 
@@ -134,7 +134,7 @@ class SearchOracle extends SearchDatabase {
         * @param bool $fulltext
         * @return string
         */
-       function getQuery( $filteredTerm, $fulltext ) {
+       private function getQuery( $filteredTerm, $fulltext ) {
                return $this->queryLimit( $this->queryMain( $filteredTerm, $fulltext ) . ' ' .
                        $this->queryNamespaces() . ' ' .
                        $this->queryRanking( $filteredTerm, $fulltext ) . ' ' );
@@ -145,7 +145,7 @@ class SearchOracle extends SearchDatabase {
         * @param bool $fulltext
         * @return string
         */
-       function getIndexField( $fulltext ) {
+       private function getIndexField( $fulltext ) {
                return $fulltext ? 'si_text' : 'si_title';
        }
 
@@ -172,7 +172,7 @@ class SearchOracle extends SearchDatabase {
         * @param bool $fulltext
         * @return string
         */
-       function parseQuery( $filteredText, $fulltext ) {
+       private function parseQuery( $filteredText, $fulltext ) {
                global $wgContLang;
                $lc = $this->legalSearchChars( self::CHARS_NO_SYNTAX );
                $this->searchTerms = [];
index 5a50b17..729e528 100644 (file)
@@ -37,7 +37,7 @@ class SearchPostgres extends SearchDatabase {
         * @param string $term Raw search term
         * @return SqlSearchResultSet
         */
-       function searchTitle( $term ) {
+       protected function doSearchTitle( $term ) {
                $q = $this->searchQuery( $term, 'titlevector', 'page_title' );
                $olderror = error_reporting( E_ERROR );
                $resultSet = $this->db->query( $q, 'SearchPostgres', true );
@@ -45,7 +45,7 @@ class SearchPostgres extends SearchDatabase {
                return new SqlSearchResultSet( $resultSet, $this->searchTerms );
        }
 
-       function searchText( $term ) {
+       protected function doSearchText( $term ) {
                $q = $this->searchQuery( $term, 'textvector', 'old_text' );
                $olderror = error_reporting( E_ERROR );
                $resultSet = $this->db->query( $q, 'SearchPostgres', true );
@@ -61,7 +61,7 @@ class SearchPostgres extends SearchDatabase {
         *
         * @return string
         */
-       function parseQuery( $term ) {
+       private function parseQuery( $term ) {
                wfDebug( "parseQuery received: $term \n" );
 
                # # No backslashes allowed
@@ -123,7 +123,7 @@ class SearchPostgres extends SearchDatabase {
         * @param string $colname
         * @return string
         */
-       function searchQuery( $term, $fulltext, $colname ) {
+       private function searchQuery( $term, $fulltext, $colname ) {
                # Get the SQL fragment for the given term
                $searchstring = $this->parseQuery( $term );
 
index f25c728..e3eb4c2 100644 (file)
@@ -173,6 +173,7 @@ class SearchResultSet {
         * Fetches next search result, or false.
         * STUB
         * FIXME: refactor as iterator, so we could use nicer interfaces.
+        * @deprecated since 1.32; Use self::extractResults()
         * @return SearchResult|false
         */
        function next() {
@@ -181,6 +182,7 @@ class SearchResultSet {
 
        /**
         * Rewind result set back to beginning
+        * @deprecated since 1.32; Use self::extractResults()
         */
        function rewind() {
        }
index af29212..1dc37d2 100644 (file)
@@ -42,7 +42,7 @@ class SearchSqlite extends SearchDatabase {
         * @param bool $fulltext
         * @return string
         */
-       function parseQuery( $filteredText, $fulltext ) {
+       private function parseQuery( $filteredText, $fulltext ) {
                global $wgContLang;
                $lc = $this->legalSearchChars( self::CHARS_NO_SYNTAX ); // Minus syntax chars (" and *)
                $searchon = '';
@@ -122,7 +122,7 @@ class SearchSqlite extends SearchDatabase {
                return " $field MATCH $searchon ";
        }
 
-       function regexTerm( $string, $wildcard ) {
+       private function regexTerm( $string, $wildcard ) {
                global $wgContLang;
 
                $regex = preg_quote( $string, '/' );
@@ -156,7 +156,7 @@ class SearchSqlite extends SearchDatabase {
         * @param string $term Raw search term
         * @return SqlSearchResultSet
         */
-       function searchText( $term ) {
+       protected function doSearchText( $term ) {
                return $this->searchInternal( $term, true );
        }
 
@@ -166,7 +166,7 @@ class SearchSqlite extends SearchDatabase {
         * @param string $term Raw search term
         * @return SqlSearchResultSet
         */
-       function searchTitle( $term ) {
+       protected function doSearchTitle( $term ) {
                return $this->searchInternal( $term, false );
        }
 
@@ -195,7 +195,7 @@ class SearchSqlite extends SearchDatabase {
         * Return a partial WHERE clause to limit the search to the given namespaces
         * @return string
         */
-       function queryNamespaces() {
+       private function queryNamespaces() {
                if ( is_null( $this->namespaces ) ) {
                        return '';  # search all
                }
@@ -212,7 +212,7 @@ class SearchSqlite extends SearchDatabase {
         * @param string $sql
         * @return string
         */
-       function limitResult( $sql ) {
+       private function limitResult( $sql ) {
                return $this->db->limitResult( $sql, $this->limit, $this->offset );
        }
 
@@ -223,7 +223,7 @@ class SearchSqlite extends SearchDatabase {
         * @param bool $fulltext
         * @return string
         */
-       function getQuery( $filteredTerm, $fulltext ) {
+       private function getQuery( $filteredTerm, $fulltext ) {
                return $this->limitResult(
                        $this->queryMain( $filteredTerm, $fulltext ) . ' ' .
                        $this->queryNamespaces()
@@ -235,7 +235,7 @@ class SearchSqlite extends SearchDatabase {
         * @param bool $fulltext
         * @return string
         */
-       function getIndexField( $fulltext ) {
+       private function getIndexField( $fulltext ) {
                return $fulltext ? 'si_text' : 'si_title';
        }
 
@@ -246,7 +246,7 @@ class SearchSqlite extends SearchDatabase {
         * @param bool $fulltext
         * @return string
         */
-       function queryMain( $filteredTerm, $fulltext ) {
+       private function queryMain( $filteredTerm, $fulltext ) {
                $match = $this->parseQuery( $filteredTerm, $fulltext );
                $page = $this->db->tableName( 'page' );
                $searchindex = $this->db->tableName( 'searchindex' );
@@ -255,7 +255,7 @@ class SearchSqlite extends SearchDatabase {
                        "WHERE page_id=$searchindex.rowid AND $match";
        }
 
-       function getCountQuery( $filteredTerm, $fulltext ) {
+       private function getCountQuery( $filteredTerm, $fulltext ) {
                $match = $this->parseQuery( $filteredTerm, $fulltext );
                $page = $this->db->tableName( 'page' );
                $searchindex = $this->db->tableName( 'searchindex' );
index d9fa82d..8ae517e 100644 (file)
@@ -429,7 +429,7 @@ class Command {
                        }
 
                        // clear get_last_error without actually raising an error
-                       // from http://php.net/manual/en/function.error-get-last.php#113518
+                       // from https://secure.php.net/manual/en/function.error-get-last.php#113518
                        // TODO replace with clear_last_error when requirements are bumped to PHP7
                        set_error_handler( function () {
                        }, 0 );
index f3cd1e8..625c899 100644 (file)
@@ -24,7 +24,7 @@
  * @file
  * @ingroup Site
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  * @author Katie Filbert < aude.wiki@gmail.com >
  */
index 7fcfbe5..b1da25c 100644 (file)
@@ -26,7 +26,7 @@ use Wikimedia\Rdbms\LoadBalancer;
  * @file
  * @ingroup Site
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  * @author Daniel Kinzler
  */
index 9654440..c168a47 100644 (file)
@@ -17,7 +17,7 @@
  *
  * @file
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  */
 
 /**
index 8a12c4f..a81ddca 100644 (file)
@@ -26,7 +26,7 @@ use UtfNormal\Validator;
  *
  * @since 1.27
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author John Erling Blad < jeblad@gmail.com >
  * @author Daniel Kinzler
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
index e1e7ce6..14c9a73 100644 (file)
@@ -22,7 +22,7 @@ use MediaWiki\Site\MediaWikiPageNameNormalizer;
  *
  * @file
  * @ingroup Site
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author John Erling Blad < jeblad@gmail.com >
  * @author Daniel Kinzler
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
index f5e3f22..01b2a3c 100644 (file)
@@ -23,7 +23,7 @@
  * @file
  * @ingroup Site
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
 class Site implements Serializable {
index 01b838e..0c9f996 100644 (file)
@@ -24,7 +24,7 @@
  * @file
  * @ingroup Site
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Daniel Kinzler
  */
 class SiteExporter {
index 5e13d06..956bdab 100644 (file)
@@ -24,7 +24,7 @@
  * @file
  * @ingroup Site
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Daniel Kinzler
  */
 class SiteImporter {
index b942d6e..726ab46 100644 (file)
@@ -23,7 +23,7 @@
  * @file
  * @ingroup Site
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
 class SiteList extends GenericArrayObject {
index 610bf0b..70fc453 100644 (file)
@@ -23,7 +23,7 @@
  * @file
  * @ingroup Site
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  */
 interface SiteLookup {
 
index 2f8a113..e0b8d27 100644 (file)
@@ -23,7 +23,7 @@
  * @file
  * @ingroup Site
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Daniel Kinzler
  */
 class SiteSQLStore {
index 10e0c1b..13800d0 100644 (file)
@@ -23,7 +23,7 @@
  * @file
  * @ingroup Site
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
 interface SiteStore extends SiteLookup {
index b4046e3..f0d6ce1 100644 (file)
@@ -20,7 +20,7 @@
  *
  * @file
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  */
 class SitesCacheFileBuilder {
 
index e1f2969..156df67 100644 (file)
@@ -18,6 +18,9 @@
  * @file
  */
 
+use Wikimedia\WrappedString;
+use Wikimedia\WrappedStringList;
+
 /**
  * New base template for a skin's template extended from QuickTemplate
  * this class features helper methods that provide common ways of interacting
@@ -754,14 +757,14 @@ abstract class BaseTemplate extends QuickTemplate {
         * debug stuff. This should be called right before outputting the closing
         * body and html tags.
         *
-        * @return string
+        * @return string|WrappedStringList HTML
         * @since 1.29
         */
-       function getTrail() {
-               $html = MWDebug::getDebugHTML( $this->getSkin()->getContext() );
-               $html .= $this->get( 'bottomscripts' );
-               $html .= $this->get( 'reporttime' );
-
-               return $html;
+       public function getTrail() {
+               return WrappedString::join( "\n", [
+                       MWDebug::getDebugHTML( $this->getSkin()->getContext() ),
+                       $this->get( 'bottomscripts' ),
+                       $this->get( 'reporttime' )
+               ] );
        }
 }
index 340bc2f..6739c08 100644 (file)
@@ -21,6 +21,8 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use Wikimedia\WrappedString;
+use Wikimedia\WrappedStringList;
 
 /**
  * @defgroup Skins Skins
@@ -401,12 +403,14 @@ abstract class Skin extends ContextSource {
 
        /**
         * @param array $data
-        * @return string
+        * @param string $nonce OutputPage::getCSPNonce()
+        * @return string|WrappedString HTML
         */
-       static function makeVariablesScript( $data ) {
+       static function makeVariablesScript( $data, $nonce = null ) {
                if ( $data ) {
                        return ResourceLoader::makeInlineScript(
-                               ResourceLoader::makeConfigSetScript( $data )
+                               ResourceLoader::makeConfigSetScript( $data ),
+                               $nonce
                        );
                } else {
                        return '';
@@ -673,16 +677,22 @@ abstract class Skin extends ContextSource {
        /**
         * This gets called shortly before the "</body>" tag.
         *
-        * @return string HTML-wrapped JS code to be put before "</body>"
+        * @return string|WrappedStringList HTML containing scripts to put before `</body>`
         */
        function bottomScripts() {
                // TODO and the suckage continues. This function is really just a wrapper around
                // OutputPage::getBottomScripts() which takes a Skin param. This should be cleaned
                // up at some point
-               $bottomScriptText = $this->getOutput()->getBottomScripts();
-               Hooks::run( 'SkinAfterBottomScripts', [ $this, &$bottomScriptText ] );
-
-               return $bottomScriptText;
+               $chunks = [ $this->getOutput()->getBottomScripts() ];
+
+               // Keep the hook appendage separate to preserve WrappedString objects.
+               // This enables BaseTemplate::getTrail() to merge them where possible.
+               $extraHtml = '';
+               Hooks::run( 'SkinAfterBottomScripts', [ $this, &$extraHtml ] );
+               if ( $extraHtml !== '' ) {
+                       $chunks[] = $extraHtml;
+               }
+               return WrappedString::join( "\n", $chunks );
        }
 
        /**
@@ -1093,25 +1103,25 @@ abstract class Skin extends ContextSource {
        }
 
        /**
-        * Return a fully resolved style path url to images or styles stored in the current skins's folder.
-        * This method returns a url resolved using the configured skin style path
-        * and includes the style version inside of the url.
+        * Return a fully resolved style path URL to images or styles stored in the
+        * current skin's folder. This method returns a URL resolved using the
+        * configured skin style path.
         *
         * Requires $stylename to be set, otherwise throws MWException.
         *
         * @param string $name The name or path of a skin resource file
-        * @return string The fully resolved style path url including styleversion
+        * @return string The fully resolved style path URL
         * @throws MWException
         */
        function getSkinStylePath( $name ) {
-               global $wgStylePath, $wgStyleVersion;
+               global $wgStylePath;
 
                if ( $this->stylename === null ) {
                        $class = static::class;
                        throw new MWException( "$class::\$stylename must be set to use getSkinStylePath()" );
                }
 
-               return "$wgStylePath/{$this->stylename}/$name?$wgStyleVersion";
+               return "$wgStylePath/{$this->stylename}/$name";
        }
 
        /* these are used extensively in SkinTemplate, but also some other places */
index 1d5d534..507688d 100644 (file)
@@ -465,7 +465,7 @@ class SkinTemplate extends Skin {
 
                $tpl->set( 'debug', '' );
                $tpl->set( 'debughtml', $this->generateDebugHTML() );
-               $tpl->set( 'reporttime', wfReportTime() );
+               $tpl->set( 'reporttime', wfReportTime( $out->getCSPNonce() ) );
 
                // Avoid PHP 7.1 warning of passing $this by reference
                $skinTemplate = $this;
index ac13f11..9e61ef7 100644 (file)
@@ -785,7 +785,8 @@ abstract class ChangesListSpecialPage extends SpecialPage {
 
                        $out->addHTML(
                                ResourceLoader::makeInlineScript(
-                                       ResourceLoader::makeMessageSetScript( $messages )
+                                       ResourceLoader::makeMessageSetScript( $messages ),
+                                       $out->getCSPNonce()
                                )
                        );
 
index fdf4d52..b3cb806 100644 (file)
@@ -112,6 +112,7 @@ class SpecialPageFactory {
                'Listbots' => SpecialListBots::class,
                'Userrights' => UserrightsPage::class,
                'EditWatchlist' => SpecialEditWatchlist::class,
+               'PasswordPolicies' => SpecialPasswordPolicies::class,
 
                // Recent changes and logs
                'Newimages' => SpecialNewFiles::class,
index f9c917d..ef05dd1 100644 (file)
@@ -126,7 +126,7 @@ class SpecialAllPages extends IncludableSpecialPage {
                                'id' => 'namespace',
                                'label-message' => 'namespace',
                                'all' => null,
-                               'value' => $namespace,
+                               'default' => $namespace,
                        ],
                        'hideredirects' => [
                                'type' => 'check',
@@ -141,7 +141,9 @@ class SpecialAllPages extends IncludableSpecialPage {
                        unset( $fields['hideredirects'] );
                }
 
-               $form = HTMLForm::factory( 'table', $fields, $this->getContext() );
+               $context = new DerivativeContext( $this->getContext() );
+               $context->setTitle( $this->getPageTitle() ); // Remove subpage
+               $form = HTMLForm::factory( 'table', $fields, $context );
                $form->setMethod( 'get' )
                        ->setWrapperLegendMsg( 'allpages' )
                        ->setSubmitTextMsg( 'allpagessubmit' )
index c000d54..034e569 100644 (file)
@@ -37,7 +37,7 @@ class SpecialApiSandbox extends SpecialPage {
 
                $out->addJsConfigVars( 'apihighlimits', $this->getUser()->isAllowed( 'apihighlimits' ) );
                $out->addModuleStyles( [
-                       'mediawiki.special.apisandbox.styles',
+                       'mediawiki.special',
                ] );
                $out->addModules( [
                        'mediawiki.special.apisandbox',
index 7b2d1bc..f03565a 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup SpecialPage
  */
 
+use MediaWiki\Logger\LoggerFactory;
+
 /**
  * Let users manage bot passwords
  *
@@ -40,8 +42,12 @@ class SpecialBotPasswords extends FormSpecialPage {
        /** @var string New password set, for communication between onSubmit() and onSuccess() */
        private $password = null;
 
+       /** @var Psr\Log\LoggerInterface */
+       private $logger = null;
+
        public function __construct() {
                parent::__construct( 'BotPasswords', 'editmyprivateinfo' );
+               $this->logger = LoggerFactory::getInstance( 'authentication' );
        }
 
        /**
@@ -277,6 +283,16 @@ class SpecialBotPasswords extends FormSpecialPage {
                                $bp = BotPassword::newFromCentralId( $this->userId, $this->par );
                                if ( $bp ) {
                                        $bp->delete();
+                                       $this->logger->info(
+                                               "Bot password {op} for {user}@{app_id}",
+                                               [
+                                                       'app_id' => $this->par,
+                                                       'user' => $this->getUser()->getName(),
+                                                       'centralId' => $this->userId,
+                                                       'op' => 'delete',
+                                                       'client_ip' => $this->getRequest()->getIP()
+                                               ]
+                                       );
                                }
                                return Status::newGood();
 
@@ -309,6 +325,18 @@ class SpecialBotPasswords extends FormSpecialPage {
                }
 
                if ( $bp->save( $this->operation, $password ) ) {
+                       $this->logger->info(
+                               "Bot password {op} for {user}@{app_id}",
+                               [
+                                       'op' => $this->operation,
+                                       'user' => $this->getUser()->getName(),
+                                       'app_id' => $this->par,
+                                       'centralId' => $this->userId,
+                                       'restrictions' => $data['restrictions'],
+                                       'grants' => $bp->getGrants(),
+                                       'client_ip' => $this->getRequest()->getIP()
+                               ]
+                       );
                        return Status::newGood();
                } else {
                        // Messages: botpasswords-insert-failed, botpasswords-update-failed
index 35cc6b8..28f04fa 100644 (file)
@@ -49,7 +49,7 @@ class SpecialComparePages extends SpecialPage {
        public function execute( $par ) {
                $this->setHeaders();
                $this->outputHeader();
-               $this->getOutput()->addModuleStyles( 'mediawiki.special.comparepages.styles' );
+               $this->getOutput()->addModuleStyles( 'mediawiki.special' );
 
                $form = HTMLForm::factory( 'ooui', [
                        'Page1' => [
index 73beafc..2f87c47 100644 (file)
@@ -63,6 +63,10 @@ class SpecialCreateAccount extends LoginSignupSpecialPage {
                $user = $this->getUser();
                $status = AuthManager::singleton()->checkAccountCreatePermissions( $user );
                if ( !$status->isGood() ) {
+                       // track block with a cookie if it doesn't exists already
+                       if ( $user->isBlockedFromCreateAccount() ) {
+                               $user->trackBlockWithCookie();
+                       }
                        throw new ErrorPageError( 'createacct-error', $status->getMessage() );
                }
        }
index 60d5fd7..3db7eda 100644 (file)
@@ -76,7 +76,7 @@ class SpecialEditTags extends UnlistedSpecialPage {
                $this->outputHeader();
 
                $this->getOutput()->addModules( [ 'mediawiki.special.edittags',
-                       'mediawiki.special.edittags.styles' ] );
+                       'mediawiki.special' ] );
 
                $this->submitClicked = $request->wasPosted() && $request->getBool( 'wpSubmit' );
 
index d30ff43..0069ea1 100644 (file)
@@ -143,8 +143,8 @@ class MovePageForm extends UnlistedSpecialPage {
 
                $out = $this->getOutput();
                $out->setPageTitle( $this->msg( 'move-page', $this->oldTitle->getPrefixedText() ) );
+               $out->addModuleStyles( 'mediawiki.special' );
                $out->addModules( 'mediawiki.special.movePage' );
-               $out->addModuleStyles( 'mediawiki.special.movePage.styles' );
                $this->addHelpLink( 'Help:Moving a page' );
 
                $out->addWikiMsg( $this->getConfig()->get( 'FixDoubleRedirects' ) ?
index a68f08f..e3485ff 100644 (file)
@@ -82,7 +82,6 @@ class SpecialPageLanguage extends FormSpecialPage {
                // Building a language selector
                $userLang = $this->getLanguage()->getCode();
                $languages = Language::fetchLanguageNames( $userLang, 'mwfile' );
-               ksort( $languages );
                $options = [];
                foreach ( $languages as $code => $name ) {
                        $options["$code - $name"] = $code;
index 34fcc78..46ad31c 100644 (file)
@@ -60,7 +60,7 @@ class SpecialPagesWithProp extends QueryPage {
        public function execute( $par ) {
                $this->setHeaders();
                $this->outputHeader();
-               $this->getOutput()->addModuleStyles( 'mediawiki.special.pagesWithProp' );
+               $this->getOutput()->addModuleStyles( 'mediawiki.special' );
 
                $request = $this->getRequest();
                $propname = $request->getVal( 'propname', $par );
diff --git a/includes/specials/SpecialPasswordPolicies.php b/includes/specials/SpecialPasswordPolicies.php
new file mode 100644 (file)
index 0000000..0a3a679
--- /dev/null
@@ -0,0 +1,164 @@
+<?php
+/**
+ * Implements Special:PasswordPolicies
+ *
+ * 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 SpecialPage
+ */
+
+/**
+ * This special page lists the defined password policies for user groups.
+ * See also @ref $wgPasswordPolicy.
+ *
+ * @ingroup SpecialPage
+ * @since 1.32
+ */
+class SpecialPasswordPolicies extends SpecialPage {
+       public function __construct() {
+               parent::__construct( 'PasswordPolicies' );
+       }
+
+       /**
+        * Show the special page
+        * @param string|null $par
+        */
+       public function execute( $par ) {
+               $this->setHeaders();
+               $this->outputHeader();
+
+               $out = $this->getOutput();
+               $out->addModuleStyles( 'mediawiki.special' );
+
+               // TODO: Have specific user documentation page for this feature
+               $this->addHelpLink( 'Manual:$wgPasswordPolicy' );
+
+               $out->addHTML(
+                       Xml::openElement( 'table', [ 'class' => 'wikitable mw-passwordpolicies-table' ] ) .
+                               '<tr>' .
+                               Xml::element( 'th', null, $this->msg( 'passwordpolicies-group' )->text() ) .
+                               Xml::element( 'th', null, $this->msg( 'passwordpolicies-policies' )->text() ) .
+                               '</tr>'
+               );
+
+               $config = $this->getConfig();
+               $policies = $config->get( 'PasswordPolicy' );
+
+               $groupPermissions = $config->get( 'GroupPermissions' );
+               $revokePermissions = $config->get( 'RevokePermissions' );
+               $addGroups = $config->get( 'AddGroups' );
+               $removeGroups = $config->get( 'RemoveGroups' );
+               $groupsAddToSelf = $config->get( 'GroupsAddToSelf' );
+               $groupsRemoveFromSelf = $config->get( 'GroupsRemoveFromSelf' );
+               $allGroups = array_unique( array_merge(
+                       array_keys( $groupPermissions ),
+                       array_keys( $revokePermissions ),
+                       array_keys( $addGroups ),
+                       array_keys( $removeGroups ),
+                       array_keys( $groupsAddToSelf ),
+                       array_keys( $groupsRemoveFromSelf )
+               ) );
+               asort( $allGroups );
+
+               $linkRenderer = $this->getLinkRenderer();
+
+               foreach ( $allGroups as $group ) {
+                       if ( $group == '*' ) {
+                               continue;
+                       }
+
+                       $groupnameLocalized = UserGroupMembership::getGroupName( $group );
+
+                       $grouppageLocalizedTitle = UserGroupMembership::getGroupPage( $group )
+                               ?: Title::newFromText( MWNamespace::getCanonicalName( NS_PROJECT ) . ':' . $group );
+
+                       $grouppage = $linkRenderer->makeLink(
+                               $grouppageLocalizedTitle,
+                               $groupnameLocalized
+                       );
+
+                       if ( $group === 'user' ) {
+                               // Link to Special:listusers for implicit group 'user'
+                               $grouplink = '<br />' . $linkRenderer->makeKnownLink(
+                                       SpecialPage::getTitleFor( 'Listusers' ),
+                                       $this->msg( 'listgrouprights-members' )->text()
+                               );
+                       } elseif ( !in_array( $group, $config->get( 'ImplicitGroups' ) ) ) {
+                               $grouplink = '<br />' . $linkRenderer->makeKnownLink(
+                                       SpecialPage::getTitleFor( 'Listusers' ),
+                                       $this->msg( 'listgrouprights-members' )->text(),
+                                       [],
+                                       [ 'group' => $group ]
+                               );
+                       } else {
+                               // No link to Special:listusers for other implicit groups as they are unlistable
+                               $grouplink = '';
+                       }
+
+                       $out->addHTML( Html::rawElement( 'tr', [ 'id' => Sanitizer::escapeIdForAttribute( $group ) ], "
+                               <td>$grouppage$grouplink</td>
+                               <td>" . $this->formatPolicies( $policies, $group ) . '</td>
+                               '
+                       ) );
+
+               }
+
+               $out->addHTML( Xml::closeElement( 'table' ) );
+       }
+
+       /**
+        * Create a HTML list of password policies for $group
+        *
+        * @param array $policies Original $wgPasswordPolicy array
+        * @param array $group Group to format password policies for
+        *
+        * @return string HTML list of all applied password policies
+        */
+       private function formatPolicies( $policies, $group ) {
+               $groupPolicies = UserPasswordPolicy::getPoliciesForGroups(
+                       $policies['policies'],
+                       [ $group ],
+                       $policies['policies']['default']
+               );
+
+               $ret = [];
+               foreach ( $groupPolicies as $gp => $val ) {
+                       if ( $val === false ) {
+                               // Policy isn't enabled, so no need to dislpay it
+                               continue;
+                       } elseif ( $val === true ) {
+                               $msg = $this->msg( 'passwordpolicies-policy-' . strtolower( $gp ) );
+                       } else {
+                               $msg = $this->msg( 'passwordpolicies-policy-' . strtolower( $gp ) )->numParams( $val );
+                       }
+                       $ret[] = $this->msg(
+                               'passwordpolicies-policy-display',
+                               $msg,
+                               '<span class="mw-passwordpolicies-policy-name">' . $gp . '</span>'
+                       )->parse();
+               }
+               if ( !count( $ret ) ) {
+                       return '';
+               } else {
+                       return '<ul><li>' . implode( "</li>\n<li>", $ret ) . '</li></ul>';
+               }
+       }
+
+       protected function getGroupName() {
+               return 'users';
+       }
+}
index f67fe9f..41ee353 100644 (file)
@@ -36,12 +36,12 @@ class SpecialPreferences extends SpecialPage {
 
        function __construct() {
                parent::__construct( 'Preferences' );
-
-               $this->oouiEnabled = self::isOouiEnabled( $this->getContext() );
        }
 
        /**
         * Check if OOUI mode is enabled, by config or query string
+        *
+        * @since 1.32
         * @param IContextSource $context The context.
         * @return bool
         */
@@ -56,6 +56,8 @@ class SpecialPreferences extends SpecialPage {
        }
 
        public function execute( $par ) {
+               $this->oouiEnabled = static::isOouiEnabled( $this->getContext() );
+
                $this->setHeaders();
                $this->outputHeader();
                $out = $this->getOutput();
@@ -73,6 +75,7 @@ class SpecialPreferences extends SpecialPage {
                if ( $this->oouiEnabled ) {
                        $out->addModules( 'mediawiki.special.preferences.ooui' );
                        $out->addModuleStyles( 'mediawiki.special.preferences.styles.ooui' );
+                       $out->addModuleStyles( 'oojs-ui-widgets.styles' );
                } else {
                        $out->addModules( 'mediawiki.special.preferences' );
                        $out->addModuleStyles( 'mediawiki.special.preferences.styles' );
@@ -118,9 +121,6 @@ class SpecialPreferences extends SpecialPage {
                                ];
                        }
                        $out->addJsConfigVars( 'wgPreferencesTabs', $prefTabs );
-
-                       // TODO: Render fake tabs here to avoid FOUC.
-                       // $out->addHTML( $fakeTabs );
                } else {
 
                        $prefTabs = '';
@@ -163,7 +163,7 @@ class SpecialPreferences extends SpecialPage {
         * Get the preferences form to use.
         * @param User $user The user.
         * @param IContextSource $context The context.
-        * @return PreferencesForm|HTMLForm
+        * @return PreferencesFormLegacy|HTMLForm
         */
        protected function getFormObject( $user, IContextSource $context ) {
                $preferencesFactory = MediaWikiServices::getInstance()->getPreferencesFactory();
index fac71b2..3ca3a85 100644 (file)
@@ -102,8 +102,10 @@ class SpecialPrefixindex extends SpecialAllPages {
                        'prefix' => [
                                'label-message' => 'allpagesprefix',
                                'name' => 'prefix',
+                               'id' => 'nsfrom',
                                'type' => 'text',
                                'size' => '30',
+                               'default' => str_replace( '_', ' ', $from ),
                        ],
                        'namespace' => [
                                'type' => 'namespaceselect',
@@ -111,7 +113,7 @@ class SpecialPrefixindex extends SpecialAllPages {
                                'id' => 'namespace',
                                'label-message' => 'namespace',
                                'all' => null,
-                               'value' => $namespace,
+                               'default' => $namespace,
                        ],
                        'hidedirects' => [
                                'class' => 'HTMLCheckField',
@@ -124,7 +126,9 @@ class SpecialPrefixindex extends SpecialAllPages {
                                'label-message' => 'prefixindex-strip',
                        ],
                ];
-               $htmlForm = new HTMLForm( $formDescriptor, $this->getContext() );
+               $context = new DerivativeContext( $this->getContext() );
+               $context->setTitle( $this->getPageTitle() ); // Remove subpage
+               $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $context );
                $htmlForm
                        ->setMethod( 'get' )
                        ->setWrapperLegendMsg( 'prefixindex' )
index e503d92..3ee7cea 100644 (file)
@@ -41,7 +41,7 @@ class SpecialTrackingCategories extends SpecialPage {
                $this->outputHeader();
                $this->getOutput()->allowClickjacking();
                $this->getOutput()->addHTML(
-                       Html::openElement( 'table', [ 'class' => 'mw-datatable',
+                       Html::openElement( 'table', [ 'class' => 'mw-datatable sortable',
                                'id' => 'mw-trackingcategories-table' ] ) . "\n" .
                        "<thead><tr>
                        <th>" .
index f7cb654..2eeafe6 100644 (file)
@@ -387,7 +387,7 @@ class SpecialUpload extends SpecialPage {
                }
 
                // Add styles for the warning, reused from the live preview
-               $this->getOutput()->addModuleStyles( 'mediawiki.special.upload.styles' );
+               $this->getOutput()->addModuleStyles( 'mediawiki.special' );
 
                $linkRenderer = $this->getLinkRenderer();
                $warningHtml = '<h2>' . $this->msg( 'uploadwarning' )->escaped() . "</h2>\n"
index 6590756..d4e5151 100644 (file)
@@ -227,15 +227,13 @@ class SpecialVersion extends SpecialPage {
                $software = [];
                $software['[https://www.mediawiki.org/ MediaWiki]'] = self::getVersionLinked();
                if ( wfIsHHVM() ) {
-                       $software['[http://hhvm.com/ HHVM]'] = HHVM_VERSION . " (" . PHP_SAPI . ")";
+                       $software['[https://hhvm.com/ HHVM]'] = HHVM_VERSION . " (" . PHP_SAPI . ")";
                } else {
                        $software['[https://php.net/ PHP]'] = PHP_VERSION . " (" . PHP_SAPI . ")";
                }
                $software[$dbr->getSoftwareLink()] = $dbr->getServerInfo();
 
-               if ( IcuCollation::getICUVersion() ) {
-                       $software['[http://site.icu-project.org/ ICU]'] = IcuCollation::getICUVersion();
-               }
+               $software['[http://site.icu-project.org/ ICU]'] = INTL_ICU_VERSION;
 
                // Allow a hook to add/remove items.
                Hooks::run( 'SoftwareInfo', [ &$software ] );
index dda1dac..ea73347 100644 (file)
@@ -60,11 +60,10 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                $output = $this->getOutput();
                $request = $this->getRequest();
                $this->addHelpLink( 'Help:Watching pages' );
+               $output->addModuleStyles( [ 'mediawiki.special' ] );
                $output->addModules( [
-                       'mediawiki.special.changeslist.visitedstatus',
                        'mediawiki.special.watchlist',
                ] );
-               $output->addModuleStyles( [ 'mediawiki.special.watchlist.styles' ] );
 
                $mode = SpecialEditWatchlist::getMode( $request, $subpage );
                if ( $mode !== false ) {
index 3080fbf..5677ac8 100644 (file)
@@ -208,8 +208,16 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                                        if ( $hidelinks || $hidetrans || $hideredirs || $hideimages ) {
                                                $out->addHTML( $this->getFilterPanel() );
                                        }
-                                       $errMsg = is_int( $namespace ) ? 'nolinkshere-ns' : 'nolinkshere';
-                                       $out->addWikiMsg( $errMsg, $this->target->getPrefixedText() );
+                                       $msgKey = is_int( $namespace ) ? 'nolinkshere-ns-2' : 'nolinkshere-2';
+                                       $link = $this->getLinkRenderer()->makeKnownLink(
+                                               $this->target,
+                                               null,
+                                               [],
+                                               $this->target->isRedirect() ? [ 'redirect' => 'no' ] : []
+                                       );
+
+                                       $errMsg = $this->msg( $msgKey )->rawParams( $link )->parseAsBlock();
+                                       $out->addHTML( $errMsg );
                                        $out->setStatusCode( 404 );
                                }
                        }
@@ -273,7 +281,16 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                        if ( !$this->including() ) {
                                $out->addHTML( $this->whatlinkshereForm() );
                                $out->addHTML( $this->getFilterPanel() );
-                               $out->addWikiMsg( 'linkshere', $this->target->getPrefixedText() );
+
+                               $link = $this->getLinkRenderer()->makeKnownLink(
+                                       $this->target,
+                                       null,
+                                       [],
+                                       $this->target->isRedirect() ? [ 'redirect' => 'no' ] : []
+                               );
+
+                               $msg = $this->msg( 'linkshere-2' )->rawParams( $link )->parseAsBlock();
+                               $out->addHTML( $msg );
 
                                $prevnext = $this->getPrevNext( $prevId, $nextId );
                                $out->addHTML( $prevnext );
diff --git a/includes/specials/forms/PreferencesForm.php b/includes/specials/forms/PreferencesForm.php
deleted file mode 100644 (file)
index a124410..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?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
- */
-
-/**
- * Temporarily define PreferencesForm as an interface, so PreferencesFormOOUI
- * and PreferencesFormLegacy can implement it.
- *
- * When PreferencesFormLegacy we can merge PreferencesFormOOUI with PreferencesForm.
- */
-interface PreferencesForm {
-}
index e6bc494..48bded4 100644 (file)
@@ -22,8 +22,10 @@ use MediaWiki\MediaWikiServices;
 
 /**
  * Form to edit user preferences.
+ *
+ * @since 1.32
  */
-class PreferencesFormLegacy extends HTMLForm implements PreferencesForm {
+class PreferencesFormLegacy extends HTMLForm {
        // Override default value from HTMLForm
        protected $mSubSectionBeforeFields = false;
 
@@ -141,3 +143,11 @@ class PreferencesFormLegacy extends HTMLForm implements PreferencesForm {
                return array_keys( array_filter( $this->mFieldTree, 'is_array' ) );
        }
 }
+
+/**
+ * Retain the old class name for backwards compatibility.
+ * In the future, this alias will be changed to point to PreferencesFormOOUI.
+ *
+ * @deprecated since 1.32
+ */
+class_alias( PreferencesFormLegacy::class, 'PreferencesForm' );
index a781254..47a595f 100644 (file)
 
 /**
  * Form to edit user preferences.
+ *
+ * @since 1.32
  */
-class PreferencesFormOOUI extends OOUIHTMLForm implements PreferencesForm {
+class PreferencesFormOOUI extends OOUIHTMLForm {
        // Override default value from HTMLForm
        protected $mSubSectionBeforeFields = false;
 
@@ -114,12 +116,108 @@ class PreferencesFormOOUI extends OOUIHTMLForm implements PreferencesForm {
                return $data;
        }
 
+       protected function wrapFieldSetSection( $legend, $section, $attributes, $isRoot ) {
+               // to get a user visible effect, wrap the fieldset into a framed panel layout
+               if ( $isRoot ) {
+                       // Mimic TabPanelLayout
+                       $wrapper = new OOUI\PanelLayout( [
+                               'expanded' => false,
+                               'scrollable' => true,
+                               // Framed and padded for no-JS, frame hidden with CSS
+                               'framed' => true,
+                               'infusable' => false,
+                               'classes' => [ 'oo-ui-stackLayout oo-ui-indexLayout-stackLayout' ]
+                       ] );
+                       $layout = new OOUI\PanelLayout( [
+                               'expanded' => false,
+                               'scrollable' => true,
+                               'infusable' => false,
+                               'classes' => [ 'oo-ui-tabPanelLayout' ]
+                       ] );
+                       $wrapper->appendContent( $layout );
+               } else {
+                       $wrapper = $layout = new OOUI\PanelLayout( [
+                               'expanded' => false,
+                               'padded' => true,
+                               'framed' => true,
+                               'infusable' => false,
+                       ] );
+               }
+
+               $layout->appendContent(
+                       new OOUI\FieldsetLayout( [
+                               'label' => $legend,
+                               'infusable' => false,
+                               'items' => [
+                                       new OOUI\Widget( [
+                                               'content' => new OOUI\HtmlSnippet( $section )
+                                       ] ),
+                               ],
+                       ] + $attributes )
+               );
+               return $wrapper;
+       }
+
        /**
         * Get the whole body of the form.
         * @return string
         */
        function getBody() {
-               return $this->displaySection( $this->mFieldTree, '', 'mw-prefsection-' );
+               // Construct fake tabs to avoid FOUC. The structure mimics OOUI's tabPanelLayout.
+               // TODO: Consider creating an infusable TabPanelLayout in OOUI-PHP.
+               $fakeTabs = [];
+               foreach ( $this->getPreferenceSections() as $i => $key ) {
+                       $fakeTabs[] =
+                               Html::rawElement(
+                                       'div',
+                                       [
+                                               'class' =>
+                                                       'oo-ui-widget oo-ui-widget-enabled oo-ui-optionWidget '.
+                                                       'oo-ui-tabOptionWidget oo-ui-labelElement' .
+                                                       ( $i === 0 ? ' oo-ui-optionWidget-selected' : '' )
+                                       ],
+                                       Html::element(
+                                               'a',
+                                               [
+                                                       'class' => 'oo-ui-labelElement-label',
+                                                       // Make this a usable link instead of a span so the tabs
+                                                       // can be used before JS runs
+                                                       'href' => '#mw-prefsection-' . $key
+                                               ],
+                                               $this->getLegend( $key )
+                                       )
+                               );
+               }
+               $fakeTabsHtml = Html::rawElement(
+                       'div',
+                       [ 'class' => 'oo-ui-layout oo-ui-panelLayout oo-ui-indexLayout-tabPanel' ],
+                       Html::rawElement(
+                               'div',
+                               [ 'class' => 'oo-ui-widget oo-ui-widget-enabled oo-ui-selectWidget '.
+                                       'oo-ui-selectWidget-depressed oo-ui-tabSelectWidget' ],
+                               implode( $fakeTabs )
+                       )
+               );
+
+               return Html::rawElement(
+                       'div',
+                       [ 'class' => 'oo-ui-layout oo-ui-panelLayout oo-ui-panelLayout-framed mw-prefs-faketabs' ],
+                       Html::rawElement(
+                               'div',
+                               [ 'class' => 'oo-ui-layout oo-ui-menuLayout oo-ui-menuLayout-static ' .
+                                       'oo-ui-menuLayout-top oo-ui-menuLayout-showMenu oo-ui-indexLayout' ],
+                               Html::rawElement(
+                                       'div',
+                                       [ 'class' => 'oo-ui-menuLayout-menu' ],
+                                       $fakeTabsHtml
+                               ) .
+                               Html::rawElement(
+                                       'div',
+                                       [ 'class' => 'oo-ui-menuLayout-content' ],
+                                       $this->displaySection( $this->mFieldTree, '', 'mw-prefsection-' )
+                               )
+                       )
+               );
        }
 
        /**
index e561fe5..8ab6f29 100644 (file)
@@ -79,7 +79,7 @@ class UploadForm extends HTMLForm {
 
                # Add a link to edit MediaWiki:Licenses
                if ( $this->getUser()->isAllowed( 'editinterface' ) ) {
-                       $this->getOutput()->addModuleStyles( 'mediawiki.special.upload.styles' );
+                       $this->getOutput()->addModuleStyles( 'mediawiki.special' );
                        $licensesLink = $linkRenderer->makeKnownLink(
                                $this->msg( 'licenses' )->inContentLanguage()->getTitle(),
                                $this->msg( 'licenses-edit' )->text(),
index 940f69c..fbd801d 100644 (file)
@@ -21,7 +21,7 @@
  * @ingroup SpecialPage
  * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
  * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  */
 
 /**
index 09d4b5e..d17332f 100644 (file)
@@ -70,6 +70,7 @@ class UsersPager extends AlphabeticPager {
                        $this->requestedGroup = '';
                }
                $this->editsOnly = $request->getBool( 'editsOnly' );
+               $this->temporaryGroupsOnly = $request->getBool( 'temporaryGroupsOnly' );
                $this->creationSort = $request->getBool( 'creationSort' );
                $this->including = $including;
                $this->mDefaultDirection = $request->getBool( 'desc' )
@@ -110,9 +111,13 @@ class UsersPager extends AlphabeticPager {
 
                $options = [];
 
+               if ( $this->requestedGroup != '' || $this->temporaryGroupsOnly ) {
+                       $conds[] = 'ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() ) .
+                       ( !$this->temporaryGroupsOnly ? ' OR ug_expiry IS NULL' : '' );
+               }
+
                if ( $this->requestedGroup != '' ) {
                        $conds['ug_group'] = $this->requestedGroup;
-                       $conds[] = 'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() );
                }
 
                if ( $this->requestedUser != '' ) {
@@ -296,6 +301,13 @@ class UsersPager extends AlphabeticPager {
                                'id' => 'editsOnly',
                                'default' => $this->editsOnly
                        ],
+                       'temporaryGroupsOnly' => [
+                               'type' => 'check',
+                               'label' => $this->msg( 'listusers-temporarygroupsonly' )->text(),
+                               'name' => 'temporaryGroupsOnly',
+                               'id' => 'temporaryGroupsOnly',
+                               'default' => $this->temporaryGroupsOnly
+                       ],
                        'creationSort' => [
                                'type' => 'check',
                                'label' => $this->msg( 'listusers-creationsort' )->text(),
index 890a870..7c2d393 100644 (file)
@@ -275,10 +275,15 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser {
                        'user_case_dbkey' => $dbkey,
                ];
 
-               # Strip Unicode bidi override characters.
+               # Strip soft hyphens (U+00AD) and Unicode directional formatting characters (U+061C, U+200E,
+               # U+200F, U+202A. U+202B, U+202C, U+202D, U+202E, U+2066, U+2067, U+2068, U+2069).
                # Sometimes they slip into cut-n-pasted page titles, where the
-               # override chars get included in list displays.
-               $dbkey = preg_replace( '/\xE2\x80[\x8E\x8F\xAA-\xAE]/S', '', $dbkey );
+               # soft hyphens or override chars get included in list displays.
+               $dbkey = preg_replace(
+                       '/\xC2\xAD|\xD8\x9C|\xE2\x80[\x8E\x8F\xAA-\xAE]|\xE2\x81[\xA6-\xA9]/S',
+                       '',
+                       $dbkey
+               );
 
                # Clean up whitespace
                # Note: use of the /u option on preg_replace here will cause
index e235c18..b5fa97f 100644 (file)
@@ -1345,32 +1345,54 @@ class User implements IDBAccessObject, UserIdentity {
                $user = $session->getUser();
                if ( $user->isLoggedIn() ) {
                        $this->loadFromUserObject( $user );
-
-                       // If this user is autoblocked, set a cookie to track the Block. This has to be done on
-                       // every session load, because an autoblocked editor might not edit again from the same
-                       // IP address after being blocked.
-                       $config = RequestContext::getMain()->getConfig();
-                       if ( $config->get( 'CookieSetOnAutoblock' ) === true ) {
-                               $block = $this->getBlock();
-                               $shouldSetCookie = $this->getRequest()->getCookie( 'BlockID' ) === null
-                                       && $block
-                                       && $block->getType() === Block::TYPE_USER
-                                       && $block->isAutoblocking();
-                               if ( $shouldSetCookie ) {
-                                       wfDebug( __METHOD__ . ': User is autoblocked, setting cookie to track' );
-                                       $block->setCookie( $this->getRequest()->response() );
-                               }
+                       if ( $user->isBlocked() ) {
+                               // If this user is autoblocked, set a cookie to track the Block. This has to be done on
+                               // every session load, because an autoblocked editor might not edit again from the same
+                               // IP address after being blocked.
+                               $this->trackBlockWithCookie();
                        }
 
                        // Other code expects these to be set in the session, so set them.
                        $session->set( 'wsUserID', $this->getId() );
                        $session->set( 'wsUserName', $this->getName() );
                        $session->set( 'wsToken', $this->getToken() );
+
                        return true;
                }
+
                return false;
        }
 
+       /**
+        * Set the 'BlockID' cookie depending on block type and user authentication status.
+        */
+       public function trackBlockWithCookie() {
+               $block = $this->getBlock();
+               if ( $block && $this->getRequest()->getCookie( 'BlockID' ) === null ) {
+                       $config = RequestContext::getMain()->getConfig();
+                       $shouldSetCookie = false;
+
+                       if ( $this->isAnon() && $config->get( 'CookieSetOnIpBlock' ) ) {
+                               // If user is logged-out, set a cookie to track the Block
+                               $shouldSetCookie = in_array( $block->getType(), [
+                                       Block::TYPE_IP, Block::TYPE_RANGE
+                               ] );
+                               if ( $shouldSetCookie ) {
+                                       $block->setCookie( $this->getRequest()->response() );
+
+                                       // temporary measure the use of cookies on ip blocks
+                                       $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
+                                       $stats->increment( 'block.ipblock.setCookie.success' );
+                               }
+                       } elseif ( $this->isLoggedIn() && $config->get( 'CookieSetOnAutoblock' ) ) {
+                               $shouldSetCookie = $block->getType() === Block::TYPE_USER && $block->isAutoblocking();
+                               if ( $shouldSetCookie ) {
+                                       $block->setCookie( $this->getRequest()->response() );
+                               }
+                       }
+               }
+       }
+
        /**
         * Load user and user_group data from the database.
         * $this->mId must be set, this is how the user is identified.
@@ -1813,14 +1835,14 @@ class User implements IDBAccessObject, UserIdentity {
                        if ( self::isLocallyBlockedProxy( $ip ) ) {
                                $block = new Block( [
                                        'byText' => wfMessage( 'proxyblocker' )->text(),
-                                       'reason' => wfMessage( 'proxyblockreason' )->text(),
+                                       'reason' => wfMessage( 'proxyblockreason' )->plain(),
                                        'address' => $ip,
                                        'systemBlock' => 'proxy',
                                ] );
                        } elseif ( $this->isAnon() && $this->isDnsBlacklisted( $ip ) ) {
                                $block = new Block( [
                                        'byText' => wfMessage( 'sorbs' )->text(),
-                                       'reason' => wfMessage( 'sorbsreason' )->text(),
+                                       'reason' => wfMessage( 'sorbsreason' )->plain(),
                                        'address' => $ip,
                                        'systemBlock' => 'dnsbl',
                                ] );
@@ -1841,7 +1863,7 @@ class User implements IDBAccessObject, UserIdentity {
                        if ( $block instanceof Block ) {
                                # Mangle the reason to alert the user that the block
                                # originated from matching the X-Forwarded-For header.
-                               $block->mReason = wfMessage( 'xffblockreason', $block->mReason )->text();
+                               $block->mReason = wfMessage( 'xffblockreason', $block->mReason )->plain();
                        }
                }
 
@@ -1853,7 +1875,7 @@ class User implements IDBAccessObject, UserIdentity {
                        $block = new Block( [
                                'address' => $ip,
                                'byText' => 'MediaWiki default',
-                               'reason' => wfMessage( 'softblockrangesreason', $ip )->text(),
+                               'reason' => wfMessage( 'softblockrangesreason', $ip )->plain(),
                                'anonOnly' => true,
                                'systemBlock' => 'wgSoftBlockRanges',
                        ] );
@@ -1896,12 +1918,24 @@ class User implements IDBAccessObject, UserIdentity {
                        // An ID was found in the cookie.
                        $tmpBlock = Block::newFromID( $blockCookieId );
                        if ( $tmpBlock instanceof Block ) {
-                               // Check the validity of the block.
-                               $blockIsValid = $tmpBlock->getType() == Block::TYPE_USER
-                                       && !$tmpBlock->isExpired()
-                                       && $tmpBlock->isAutoblocking();
                                $config = RequestContext::getMain()->getConfig();
-                               $useBlockCookie = ( $config->get( 'CookieSetOnAutoblock' ) === true );
+
+                               switch ( $tmpBlock->getType() ) {
+                                       case Block::TYPE_USER:
+                                               $blockIsValid = !$tmpBlock->isExpired() && $tmpBlock->isAutoblocking();
+                                               $useBlockCookie = ( $config->get( 'CookieSetOnAutoblock' ) === true );
+                                               break;
+                                       case Block::TYPE_IP:
+                                       case Block::TYPE_RANGE:
+                                               // If block is type IP or IP range, load only if user is not logged in (T152462)
+                                               $blockIsValid = !$tmpBlock->isExpired() && !$this->isLoggedIn();
+                                               $useBlockCookie = ( $config->get( 'CookieSetOnIpBlock' ) === true );
+                                               break;
+                                       default:
+                                               $blockIsValid = false;
+                                               $useBlockCookie = false;
+                               }
+
                                if ( $blockIsValid && $useBlockCookie ) {
                                        // Use the block.
                                        return $tmpBlock;
index 9da0370..89cdc5f 100644 (file)
@@ -230,9 +230,8 @@ class UserGroupMembership {
        public function isExpired() {
                if ( !$this->expiry ) {
                        return false;
-               } else {
-                       return wfTimestampNow() > $this->expiry;
                }
+               return wfTimestampNow() > $this->expiry;
        }
 
        /**
@@ -354,9 +353,8 @@ class UserGroupMembership {
                $ugm = self::newFromRow( $row );
                if ( !$ugm->isExpired() ) {
                        return $ugm;
-               } else {
-                       return false;
                }
+               return false;
        }
 
        /**
@@ -419,9 +417,8 @@ class UserGroupMembership {
                        }
                        return $context->msg( 'group-membership-link-with-expiry' )
                                ->params( $groupLink, $expiryDT, $expiryD, $expiryT )->text();
-               } else {
-                       return $groupLink;
                }
+               return $groupLink;
        }
 
        /**
index 98d2c0e..b437653 100644 (file)
@@ -389,7 +389,7 @@ class ClassCollector {
                        return;
                }
                // Note: When changing class name discovery logic,
-               // AutoLoaderTest.php may also need to be updated.
+               // AutoLoaderStructureTest.php may also need to be updated.
                switch ( $token[0] ) {
                        case T_NAMESPACE:
                        case T_CLASS:
index 9679bfe..78b3f8e 100644 (file)
@@ -94,6 +94,11 @@ class ExecutableFinder {
         * @return bool|string
         */
        public static function findInDefaultPaths( $names, $versionInfo = false ) {
+               if ( Shell::isDisabled() ) {
+                       // If we can't shell out, there's no point looking for executables
+                       return false;
+               }
+
                $paths = self::getPossibleBinPaths();
                foreach ( (array)$names as $name ) {
                        foreach ( $paths as $path ) {
index 1c8d486..d0fe6cc 100644 (file)
@@ -67,7 +67,7 @@ class MWCryptHKDF {
         * @param string $ikm The input keying material
         * @param string $salt The salt to add to the ikm, to get the prk
         * @param string $info Optional context (change the output without affecting
-        *      the randomness properties of the output)
+        *      the randomness properties of the output)
         * @param int $L Number of bytes to return
         * @return string Cryptographically secure pseudorandom binary string
         */
index 506ee00..deb1f28 100644 (file)
@@ -13,7 +13,7 @@ use Wikimedia\Rdbms\LoadBalancer;
  * @file
  * @ingroup Watchlist
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  */
 class WatchedItemQueryService {
 
@@ -320,8 +320,8 @@ class WatchedItemQueryService {
        }
 
        private function getRecentChangeFieldsFromRow( stdClass $row ) {
-               // This can be simplified to single array_filter call filtering by key value,
-               // once we stop supporting PHP 5.5
+               // FIXME: This can be simplified to single array_filter call filtering by key value,
+               // now we have stopped supporting PHP 5.5
                $allFields = get_object_vars( $row );
                $rcKeys = array_filter(
                        array_keys( $allFields ),
index 93d5033..873ae2d 100644 (file)
@@ -11,7 +11,7 @@ use Wikimedia\Rdbms\IDatabase;
  * @file
  * @ingroup Watchlist
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  */
 interface WatchedItemQueryServiceExtension {
 
index c4d1dfc..18c05bf 100644 (file)
@@ -10,7 +10,7 @@ use \OOUI\LabelWidget;
  * Select and input widget.
  *
  * @copyright 2011-2018 MediaWiki Widgets Team and others; see AUTHORS.txt
- * @license The MIT License (MIT); see LICENSE.txt
+ * @license MIT
  */
 class SizeFilterWidget extends \OOUI\Widget {
 
index 18d514f..e61303d 100644 (file)
@@ -14,8 +14,6 @@
                "resources/src/jquery.tipsy",
                "resources/src/jquery/jquery.color.js",
                "resources/src/jquery/jquery.expandableField.js",
-               "resources/src/jquery/jquery.farbtastic.css",
-               "resources/src/jquery/jquery.farbtastic.js",
                "resources/src/jquery/jquery.highlightText.js",
                "resources/src/jquery/jquery.mw-jump.js",
                "resources/src/mediawiki.legacy",
index d750f7d..1320a57 100644 (file)
@@ -273,7 +273,7 @@ class Language {
         * 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
+        * https://www.unicode.org/repos/cldr/trunk/tools/java/org/unicode/cldr/util/data/langtagRegex.txt
         *
         * @param string $code
         * @param bool $lenient Whether to allow '_' as separator. The default is only '-'.
@@ -792,12 +792,12 @@ class Language {
        /**
         * Get an array of language names, indexed by code.
         * @param null|string $inLanguage Code of language in which to return the names
-        *              Use null for autonyms (native names)
+        *              Use null for autonyms (native names)
         * @param string $include One of:
-        *              'all' all available languages
-        *              'mw' only if the language is defined in MediaWiki or wgExtraLanguageNames (default)
-        *              'mwfile' only if the language is in 'mw' *and* has a message file
-        * @return array Language code => language name
+        *              'all' all available languages
+        *              'mw' only if the language is defined in MediaWiki or wgExtraLanguageNames (default)
+        *              'mwfile' only if the language is in 'mw' *and* has a message file
+        * @return array Language code => language name (sorted by key)
         * @since 1.20
         */
        public static function fetchLanguageNames( $inLanguage = null, $include = 'mw' ) {
@@ -823,7 +823,7 @@ class Language {
         *              'all' all available languages
         *              'mw' only if the language is defined in MediaWiki or wgExtraLanguageNames (default)
         *              'mwfile' only if the language is in 'mw' *and* has a message file
-        * @return array Language code => language name
+        * @return array Language code => language name (sorted by key)
         */
        private static function fetchLanguageNamesUncached( $inLanguage = null, $include = 'mw' ) {
                global $wgExtraLanguageNames, $wgUsePigLatinVariant;
@@ -1951,8 +1951,8 @@ class Language {
         * Gets directionality of the first strongly directional codepoint, for embedBidi()
         *
         * This is the rule the BIDI algorithm uses to determine the directionality of
-        * paragraphs ( http://unicode.org/reports/tr9/#The_Paragraph_Level ) and
-        * FSI isolates ( http://unicode.org/reports/tr9/#Explicit_Directional_Isolates ).
+        * paragraphs ( https://www.unicode.org/reports/tr9/#The_Paragraph_Level ) and
+        * FSI isolates ( https://www.unicode.org/reports/tr9/#Explicit_Directional_Isolates ).
         *
         * TODO: Does not handle BIDI control characters inside the text.
         * TODO: Does not handle unallocated characters.
@@ -2990,8 +2990,8 @@ class Language {
                global $wgAllUnicodeFixes;
                $s = UtfNormal\Validator::cleanUp( $s );
                if ( $wgAllUnicodeFixes ) {
-                       $s = $this->transformUsingPairFile( 'normalize-ar.ser', $s );
-                       $s = $this->transformUsingPairFile( 'normalize-ml.ser', $s );
+                       $s = $this->transformUsingPairFile( 'normalize-ar.php', $s );
+                       $s = $this->transformUsingPairFile( 'normalize-ml.php', $s );
                }
 
                return $s;
@@ -3011,12 +3011,10 @@ class Language {
         * @throws MWException
         * @return string
         */
-       function transformUsingPairFile( $file, $string ) {
+       protected function transformUsingPairFile( $file, $string ) {
                if ( !isset( $this->transformData[$file] ) ) {
-                       $data = wfGetPrecompiledData( $file );
-                       if ( $data === false ) {
-                               throw new MWException( __METHOD__ . ": The transformation file $file is missing" );
-                       }
+                       global $IP;
+                       $data = require "$IP/languages/data/{$file}";
                        $this->transformData[$file] = new ReplacementArray( $data );
                }
                return $this->transformData[$file]->replace( $string );
@@ -3485,7 +3483,7 @@ class Language {
         * @param int $length Maximum length (including ellipsis)
         * @param string $ellipsis String to append to the truncated text
         * @param bool $adjustLength Subtract length of ellipsis from $length.
-        *      $adjustLength was introduced in 1.18, before that behaved as if false.
+        *      $adjustLength was introduced in 1.18, before that behaved as if false.
         * @return string
         */
        function truncate( $string, $length, $ellipsis = '...', $adjustLength = true ) {
index f611358..d11838a 100644 (file)
@@ -967,11 +967,11 @@ class LanguageConverter {
         * Parse the conversion table stored in the cache.
         *
         * The tables should be in blocks of the following form:
-        *              -{
-        *                      word => word ;
-        *                      word => word ;
-        *                      ...
-        *              }-
+        *              -{
+        *                      word => word ;
+        *                      word => word ;
+        *                      ...
+        *              }-
         *
         * To make the tables more manageable, subpages are allowed
         * and will be parsed recursively if $recursive == true.
index 90e3751..efdf5a2 100644 (file)
@@ -44,7 +44,7 @@ class LanguageAr extends Language {
                global $wgFixArabicUnicode;
                $s = parent::normalize( $s );
                if ( $wgFixArabicUnicode ) {
-                       $s = $this->transformUsingPairFile( 'normalize-ar.ser', $s );
+                       $s = $this->transformUsingPairFile( 'normalize-ar.php', $s );
                }
                return $s;
        }
index 1f9b767..07005d4 100644 (file)
@@ -19,8 +19,8 @@
  *
  * @file
  * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
- * @license http://www.gnu.org/copyleft/fdl.html GNU Free Documentation License
+ * @license GPL-2.0-or-later
+ * @license GFDL-1.3-or-later
  * @ingroup Language
  */
 
index 1698b9f..e652a52 100644 (file)
@@ -189,7 +189,7 @@ class CrhConverter extends LanguageConverter {
 
        /**
         *  It translates text into variant, specials:
-        *    - ommiting roman numbers
+        *    - omitting roman numbers
         *
         * @param string $text
         * @param bool $toVariant
index 0185a03..2269009 100644 (file)
@@ -52,28 +52,28 @@ class LanguageKsh extends Language {
         * Word order is irrelevant.
         *
         * Possible values specifying the grammatical case are:
-        *      1, Nominative
-        *      2, Genitive
-        *      3, Dative
-        *      4, Accusative, -omitted-
+        *      1, Nominative
+        *      2, Genitive
+        *      3, Dative
+        *      4, Accusative, -omitted-
         *
         * Possible values specifying the article type are:
-        *      Betoont               focussed or stressed article
-        *      -omitted-             unstressed or unfocussed article
+        *      Betoont               focussed or stressed article
+        *      -omitted-             unstressed or unfocussed article
         *
         * Possible values for the type of genitive are:
-        *      Sing, Iehr            prepositioned genitive = possessive dative
-        *      Vun, Fon, -omitted-   postpositioned genitive = preposition "vun" with dative
+        *      Sing, Iehr            prepositioned genitive = possessive dative
+        *      Vun, Fon, -omitted-   postpositioned genitive = preposition "vun" with dative
         *
         * Values of case overrides & prepositions, in the order of preceedence:
-        *      Sing, Iehr            possessive dative = prepositioned genitive
-        *      Vun, Fon              preposition "vun" with dative = postpositioned genitive
-        *      En, em                preposition "en" with dative
+        *      Sing, Iehr            possessive dative = prepositioned genitive
+        *      Vun, Fon              preposition "vun" with dative = postpositioned genitive
+        *      En, em                preposition "en" with dative
         *
         * Values for object gender specifiers of the possessive dative, or
         * prepositioned genitive, evaluated with "Sing, Iehr" of above only:
-        *      Male                  a singular male object follows
-        *      -omitted-             a non-male or plural object follows
+        *      Male                  a singular male object follows
+        *      -omitted-             a non-male or plural object follows
         *
         * We currently handle definite articles of the singular only.
         * There is a full set of test cases at:
index df894a1..cf45762 100644 (file)
@@ -45,7 +45,7 @@ class LanguageMl extends Language {
                global $wgFixMalayalamUnicode;
                $s = parent::normalize( $s );
                if ( $wgFixMalayalamUnicode ) {
-                       $s = $this->transformUsingPairFile( 'normalize-ml.ser', $s );
+                       $s = $this->transformUsingPairFile( 'normalize-ml.php', $s );
                }
                return $s;
        }
index e3bb156..c759220 100644 (file)
@@ -13,6 +13,8 @@ use CrhConverter as Crh;
 
 class CrhExceptions {
 
+       const WB = '\b'; # default word boundary; may be updated in the future
+
        function __construct() {
                $this->loadRegs();
        }
@@ -102,9 +104,9 @@ class CrhExceptions {
 
                # load C2L and L2C bidirectional affix mappings
                $this->addMappings( $this->prefixMapping,
-                       $this->Cyrl2LatnPatterns, $this->Latn2CyrlPatterns, false, '/\b', '/u' );
+                       $this->Cyrl2LatnPatterns, $this->Latn2CyrlPatterns, false, '/'.self::WB, '/u' );
                $this->addMappings( $this->suffixMapping,
-                       $this->Cyrl2LatnPatterns, $this->Latn2CyrlPatterns, false, '/', '\b/u' );
+                       $this->Cyrl2LatnPatterns, $this->Latn2CyrlPatterns, false, '/', self::WB.'/u' );
 
                # tack on one-way mappings to the ends of the prefix and suffix patterns
                $this->Cyrl2LatnPatterns += $this->Cyrl2LatnRegexes;
@@ -124,6 +126,7 @@ class CrhExceptions {
                'beyude' => 'бейуде', 'beyüde' => 'бейуде',
                'curat' => 'джурьат', 'cürat' => 'джурьат',
                'mesul' => 'месуль', 'mesül' => 'месуль',
+               'yetsin' => 'етсин', 'etsin' => 'етсин',
        ];
 
        # map Cyrillic to Latin and back, simple string match only (no regex)
@@ -211,7 +214,6 @@ class CrhExceptions {
                'оригинал' => 'original', 'оригиналь' => 'original',
                'пускю' => 'püskü', 'пуськю' => 'püskü',
                'къарагоз' => 'qaragöz', 'къарагозь' => 'qaragöz',
-               'етсин' => 'yetsin', 'етсин' => 'etsin',
 
                #### Latin to Cyrillic (deduped from above)
 
@@ -284,7 +286,13 @@ class CrhExceptions {
                'доцент' => 'dotsent', 'фармацевт' => 'farmatsevt', 'глицер' => 'glitser',
                'люцерна' => 'lütserna', 'лицей' => 'litsey', 'меццо' => 'metstso', 'наци' => 'natsi',
                'проце' => 'protse', 'рецеп' => 'retsep', 'реценз' => 'retsenz', 'теплица' => 'teplitsa',
-               'вице' => 'vitse', 'швейцар' => 'şveytsar',
+               'вице' => 'vitse', 'швейцар' => 'şveytsar', 'богородиц' => 'bogorodits',
+               'бруцел' => 'brutsel', 'дацюк' => 'datsük', 'доницетти' => 'donitsetti',
+               'драцена' => 'dratsena', 'контрацеп' => 'kontratsep', 'коцюб' => 'kotsüb',
+               'меценат' => 'metsenat', 'мицел' => 'mitsel', 'моцарт' => 'motsart', 'плац' => 'plats',
+               'плацен' => 'platsen', 'прецедент' => 'pretsedent', 'прецес' => 'pretses',
+               'прицеп' => 'pritsep', 'спец' => 'spets', 'троиц' => 'troits', 'шприц' => 'şprits',
+               'эпицентр' => 'epitsentr', 'яценюк' => 'yatsenük',
 
                # слова с тс
                # words with тс
@@ -403,76 +411,76 @@ class CrhExceptions {
                        // TODO: refactor upper/lower/first capital whole words without
                        // regexes into simpler list
 
-                       '/\bКъЮШ\b/u' => 'QYŞ',
-                       '/\bЮШ\b/u' => 'YŞ',
-
-                       '/\bкок\b/u' => 'kök',
-                       '/\bКок\b/u' => 'Kök',
-                       '/\bКОК\b/u' => 'KÖK',
-                       '/\bком-кок\b/u' => 'köm-kök',
-                       '/\bКом-кок\b/u' => 'Köm-kök',
-                       '/\bКОМ-КОК\b/u' => 'KÖM-KÖK',
-
-                       '/\bкоп\b/u' => 'köp',
-                       '/\bКоп\b/u' => 'Köp',
-                       '/\bКОП\b/u' => 'KÖP',
-
-                       '/\bкурк\b/u' => 'kürk',
-                       '/\bКурк\b/u' => 'Kürk',
-                       '/\bКУРК\b/u' => 'KÜRK',
-
-                       '/\bог\b/u' => 'ög',
-                       '/\bОг\b/u' => 'Ög',
-                       '/\bОГ\b/u' => 'ÖG',
-
-                       '/\bюрип\b/u' => 'yürip',
-                       '/\bЮрип\b/u' => 'Yürip',
-                       '/\bЮРИП\b/u' => 'YÜRİP',
-
-                       '/\bюз\b/u' => 'yüz',
-                       '/\bЮз\b/u' => 'Yüz',
-                       '/\bЮЗ\b/u' => 'YÜZ',
-
-                       '/\bюк\b/u' => 'yük',
-                       '/\bЮк\b/u' => 'Yük',
-                       '/\bЮК\b/u' => 'YÜK',
-
-                       '/\bбуюп\b/u' => 'büyüp',
-                       '/\bБуюп\b/u' => 'Büyüp',
-                       '/\bБУЮП\b/u' => 'BÜYÜP',
-
-                       '/\bбуюк\b/u' => 'büyük',
-                       '/\bБуюк\b/u' => 'Büyük',
-                       '/\bБУЮК\b/u' => 'BÜYÜK',
-
-                       '/\bджонк\b/u' => 'cönk',
-                       '/\bДжонк\b/u' => 'Cönk',
-                       '/\bДЖОНК\b/u' => 'CÖNK',
-                       '/\bджонкю\b/u' => 'cönkü',
-                       '/\bДжонкю\b/u' => 'Cönkü',
-                       '/\bДЖОНКЮ\b/u' => 'CÖNKÜ',
-
-                       '/\bустке\b/u' => 'üstke',
-                       '/\bУстке\b/u' => 'Üstke',
-                       '/\bУСТКЕ\b/u' => 'ÜSTKE',
-                       '/\bустте\b/u' => 'üstte',
-                       '/\bУстте\b/u' => 'Üstte',
-                       '/\bУСТТЕ\b/u' => 'ÜSTTE',
-                       '/\bусттен\b/u' => 'üstten',
-                       '/\bУсттен\b/u' => 'Üstten',
-                       '/\bУСТТЕН\b/u' => 'ÜSTTEN',
+                       '/'.self::WB.'КъЮШ'.self::WB.'/u' => 'QYŞ',
+                       '/'.self::WB.'ЮШ'.self::WB.'/u' => 'YŞ',
+
+                       '/'.self::WB.'кок'.self::WB.'/u' => 'kök',
+                       '/'.self::WB.'Кок'.self::WB.'/u' => 'Kök',
+                       '/'.self::WB.'КОК'.self::WB.'/u' => 'KÖK',
+                       '/'.self::WB.'ком-кок'.self::WB.'/u' => 'köm-kök',
+                       '/'.self::WB.'Ком-кок'.self::WB.'/u' => 'Köm-kök',
+                       '/'.self::WB.'КОМ-КОК'.self::WB.'/u' => 'KÖM-KÖK',
+
+                       '/'.self::WB.'коп'.self::WB.'/u' => 'köp',
+                       '/'.self::WB.'Коп'.self::WB.'/u' => 'Köp',
+                       '/'.self::WB.'КОП'.self::WB.'/u' => 'KÖP',
+
+                       '/'.self::WB.'курк'.self::WB.'/u' => 'kürk',
+                       '/'.self::WB.'Курк'.self::WB.'/u' => 'Kürk',
+                       '/'.self::WB.'КУРК'.self::WB.'/u' => 'KÜRK',
+
+                       '/'.self::WB.'ог'.self::WB.'/u' => 'ög',
+                       '/'.self::WB.'Ог'.self::WB.'/u' => 'Ög',
+                       '/'.self::WB.'ОГ'.self::WB.'/u' => 'ÖG',
+
+                       '/'.self::WB.'юрип'.self::WB.'/u' => 'yürip',
+                       '/'.self::WB.'Юрип'.self::WB.'/u' => 'Yürip',
+                       '/'.self::WB.'ЮРИП'.self::WB.'/u' => 'YÜRİP',
+
+                       '/'.self::WB.'юз'.self::WB.'/u' => 'yüz',
+                       '/'.self::WB.'Юз'.self::WB.'/u' => 'Yüz',
+                       '/'.self::WB.'ЮЗ'.self::WB.'/u' => 'YÜZ',
+
+                       '/'.self::WB.'юк'.self::WB.'/u' => 'yük',
+                       '/'.self::WB.'Юк'.self::WB.'/u' => 'Yük',
+                       '/'.self::WB.'ЮК'.self::WB.'/u' => 'YÜK',
+
+                       '/'.self::WB.'буюп'.self::WB.'/u' => 'büyüp',
+                       '/'.self::WB.'Буюп'.self::WB.'/u' => 'Büyüp',
+                       '/'.self::WB.'БУЮП'.self::WB.'/u' => 'BÜYÜP',
+
+                       '/'.self::WB.'буюк'.self::WB.'/u' => 'büyük',
+                       '/'.self::WB.'Буюк'.self::WB.'/u' => 'Büyük',
+                       '/'.self::WB.'БУЮК'.self::WB.'/u' => 'BÜYÜK',
+
+                       '/'.self::WB.'джонк'.self::WB.'/u' => 'cönk',
+                       '/'.self::WB.'Джонк'.self::WB.'/u' => 'Cönk',
+                       '/'.self::WB.'ДЖОНК'.self::WB.'/u' => 'CÖNK',
+                       '/'.self::WB.'джонкю'.self::WB.'/u' => 'cönkü',
+                       '/'.self::WB.'Джонкю'.self::WB.'/u' => 'Cönkü',
+                       '/'.self::WB.'ДЖОНКЮ'.self::WB.'/u' => 'CÖNKÜ',
+
+                       '/'.self::WB.'устке'.self::WB.'/u' => 'üstke',
+                       '/'.self::WB.'Устке'.self::WB.'/u' => 'Üstke',
+                       '/'.self::WB.'УСТКЕ'.self::WB.'/u' => 'ÜSTKE',
+                       '/'.self::WB.'устте'.self::WB.'/u' => 'üstte',
+                       '/'.self::WB.'Устте'.self::WB.'/u' => 'Üstte',
+                       '/'.self::WB.'УСТТЕ'.self::WB.'/u' => 'ÜSTTE',
+                       '/'.self::WB.'усттен'.self::WB.'/u' => 'üstten',
+                       '/'.self::WB.'Усттен'.self::WB.'/u' => 'Üstten',
+                       '/'.self::WB.'УСТТЕН'.self::WB.'/u' => 'ÜSTTEN',
 
                        # отдельно стоящие Ё и Я
                        # stand-alone Ё and Я
-                       '/\bЯ\b/u' => 'Ya',
-                       '/\bЁ\b/u' => 'Yo',
+                       '/'.self::WB.'Я'.self::WB.'/u' => 'Ya',
+                       '/'.self::WB.'Ё'.self::WB.'/u' => 'Yo',
 
                        ############################
                        # относятся к началу слова #
                        # word prefixes            #
                        ############################
-                       '/\bКъЮШн/u' => 'QYŞn',
-                       '/\bЮШн/u' => 'YŞn',
+                       '/'.self::WB.'КъЮШн/u' => 'QYŞn',
+                       '/'.self::WB.'ЮШн/u' => 'YŞn',
 
                        # need to convert digraphs (гъ, къ, нъ, дж) now to match patterns
                        '/гъ/u' => 'ğ',
@@ -485,58 +493,63 @@ class CrhExceptions {
                        '/Д[жЖ]/u' => 'C',
 
                        # о => ö
-                       '/\b(['.Crh::C_M_CONS.'])о(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => '$1ö$2$3$4',
-                       '/\bо(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ö$1$2$3',
-                       '/\b(['.Crh::C_M_CONS.'])О(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' =>
-                               '$1Ö$2$3$4',
-                       '/\bО(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => 'Ö$1$2$3',
-
-                       '/\b(['.Crh::C_M_CONS.'])о(['.Crh::C_CONS.'])([еиэюьü])/u' => '$1ö$2$3',
-                       '/\bо(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ö$1$2',
-                       '/\b(['.Crh::C_M_CONS.'])О(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => '$1Ö$2$3',
-                       '/\bО(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => 'Ö$1$2',
+                       '/'.self::WB.'(['.Crh::C_M_CONS.'])о(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u'
+                               => '$1ö$2$3$4',
+                       '/'.self::WB.'о(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ö$1$2$3',
+                       '/'.self::WB.'(['.Crh::C_M_CONS.'])О(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u'
+                               => '$1Ö$2$3$4',
+                       '/'.self::WB.'О(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => 'Ö$1$2$3',
+
+                       '/'.self::WB.'(['.Crh::C_M_CONS.'])о(['.Crh::C_CONS.'])([еиэюьü])/u' => '$1ö$2$3',
+                       '/'.self::WB.'о(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ö$1$2',
+                       '/'.self::WB.'(['.Crh::C_M_CONS.'])О(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => '$1Ö$2$3',
+                       '/'.self::WB.'О(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => 'Ö$1$2',
 
                        # ё => yö
-                       '/\bё(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([ьеюü])/u' => 'yö$1$2$3',
-                       '/\bЁ(['.Crh::C_CONS_LC.'])(['.Crh::C_CONS_LC.'])([ьеюü])/u' => 'Yö$1$2$3',
-                       '/\bЁ(['.Crh::C_CONS_UC.'])(['.Crh::C_CONS_UC.'])([ЬЕЮÜ])/u' => 'YÖ$1$2$3',
-                       '/\bё(['.Crh::C_CONS.'])([ьеюü])/u' => 'yö$1$2',
-                       '/\bЁ(['.Crh::C_CONS_LC.'])([ьеюü])/u' => 'Yö$1$2',
-                       '/\bЁ(['.Crh::C_CONS_UC.'])([ЬЕЮÜ])/u' => 'YÖ$1$2',
+                       '/'.self::WB.'ё(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([ьеюü])/u' => 'yö$1$2$3',
+                       '/'.self::WB.'Ё(['.Crh::C_CONS_LC.'])(['.Crh::C_CONS_LC.'])([ьеюü])/u' => 'Yö$1$2$3',
+                       '/'.self::WB.'Ё(['.Crh::C_CONS_UC.'])(['.Crh::C_CONS_UC.'])([ЬЕЮÜ])/u' => 'YÖ$1$2$3',
+                       '/'.self::WB.'ё(['.Crh::C_CONS.'])([ьеюü])/u' => 'yö$1$2',
+                       '/'.self::WB.'Ё(['.Crh::C_CONS_LC.'])([ьеюü])/u' => 'Yö$1$2',
+                       '/'.self::WB.'Ё(['.Crh::C_CONS_UC.'])([ЬЕЮÜ])/u' => 'YÖ$1$2',
 
                        # у => ü, ую => üyü
-                       '/\b(['.Crh::C_M_CONS.'])у(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => '$1ü$2$3$4',
-                       '/\bу(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ü$1$2$3',
-                       '/\bую(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'üyü$1$2$3',
-                       '/\b(['.Crh::C_M_CONS.'])У(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' =>
-                               '$1Ü$2$3$4',
-                       '/\bУ(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => 'Ü$1$2$3',
-                       '/\bУю(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'Üyü$1$2$2',
-                       '/\bУЮ(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ÜYÜ$1$2$3',
-
-                       '/\b(['.Crh::C_M_CONS.'])у(['.Crh::C_CONS.'])([еиэюьü])/u' => '$1ü$2$3',
-                       '/\bу(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ü$1$2',
-                       '/\bую(['.Crh::C_CONS.'])([еиэюьü])/u' => 'üyü$1$2',
-                       '/\b(['.Crh::C_M_CONS.'])У(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => '$1Ü$2$3',
-                       '/\bУ(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => 'Ü$1$2',
-                       '/\bУю(['.Crh::C_CONS.'])([еиэюьü])/u' => 'Üyü$1$2',
-                       '/\bУЮ(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ÜYÜ$1$2',
+                       '/'.self::WB.'(['.Crh::C_M_CONS.'])у(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u'
+                               => '$1ü$2$3$4',
+                       '/'.self::WB.'у(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ü$1$2$3',
+                       '/'.self::WB.'ую(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'üyü$1$2$3',
+                       '/'.self::WB.'(['.Crh::C_M_CONS.'])У(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u'
+                               => '$1Ü$2$3$4',
+                       '/'.self::WB.'У(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => 'Ü$1$2$3',
+                       '/'.self::WB.'Ую(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'Üyü$1$2$3',
+                       '/'.self::WB.'УЮ(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ÜYÜ$1$2$3',
+
+                       '/'.self::WB.'(['.Crh::C_M_CONS.'])у(['.Crh::C_CONS.'])([еиэюьü])/u' => '$1ü$2$3',
+                       '/'.self::WB.'у(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ü$1$2',
+                       '/'.self::WB.'ую(['.Crh::C_CONS.'])([еиэюьü])/u' => 'üyü$1$2',
+                       '/'.self::WB.'(['.Crh::C_M_CONS.'])У(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => '$1Ü$2$3',
+                       '/'.self::WB.'У(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => 'Ü$1$2',
+                       '/'.self::WB.'Ую(['.Crh::C_CONS.'])([еиэюьü])/u' => 'Üyü$1$2',
+                       '/'.self::WB.'УЮ(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ÜYÜ$1$2',
 
                        # ю => yü
-                       '/\b([аыоуеиёюАЫОУЕИЁЮ]?)ю(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([ьеюü])/u' => '$1yü$2$3$4',
-                       '/\b([АЫОУЕИЁЮ]?)Ю(['.Crh::C_CONS_LC.'])(['.Crh::C_CONS_LC.'])([ьеюü])/u' => '$1Yü$2$3$4',
-                       '/\b([АЫОУЕИЁЮ]?)Ю(['.Crh::C_CONS_UC.'])(['.Crh::C_CONS_UC.'])([ЬЕЮÜ])/u' => '$1YÜ$2$3$4',
-                       '/\b([аыоуеиёюАЫОУЕИЁЮ]?)ю(['.Crh::C_CONS.'])([ьеюü])/u' => '$1yü$2$3',
-                       '/\b([АЫОУЕИЁЮ]?)Ю(['.Crh::C_CONS_LC.'])([ьеюü])/u' => '$1Yü$2$3',
-                       '/\b([АЫОУЕИЁЮ]?)Ю(['.Crh::C_CONS_UC.'])([ЬЕЮÜ])/u' => '$1YÜ$2$3',
+                       '/'.self::WB.'([аыоуеиёюАЫОУЕИЁЮ]?)ю(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([ьеюü])/u'
+                               => '$1yü$2$3$4',
+                       '/'.self::WB.'([АЫОУЕИЁЮ]?)Ю(['.Crh::C_CONS_LC.'])(['.Crh::C_CONS_LC.'])([ьеюü])/u'
+                               => '$1Yü$2$3$4',
+                       '/'.self::WB.'([АЫОУЕИЁЮ]?)Ю(['.Crh::C_CONS_UC.'])(['.Crh::C_CONS_UC.'])([ЬЕЮÜ])/u'
+                               => '$1YÜ$2$3$4',
+                       '/'.self::WB.'([аыоуеиёюАЫОУЕИЁЮ]?)ю(['.Crh::C_CONS.'])([ьеюü])/u' => '$1yü$2$3',
+                       '/'.self::WB.'([АЫОУЕИЁЮ]?)Ю(['.Crh::C_CONS_LC.'])([ьеюü])/u' => '$1Yü$2$3',
+                       '/'.self::WB.'([АЫОУЕИЁЮ]?)Ю(['.Crh::C_CONS_UC.'])([ЬЕЮÜ])/u' => '$1YÜ$2$3',
 
                        # e => ye, я => ya
-                       '/\bе/u' => 'ye',
-                       '/\bЕ(['.Crh::C_LC.'cğñqöü])/u' => 'Ye$1',
-                       '/\bЕ(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'YE$1',
-                       '/\bя/u' => 'ya',
-                       '/\bЯ(['.Crh::C_LC.'cğñqöü])/u' => 'Ya$1',
-                       '/\bЯ(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'YA$1',
+                       '/'.self::WB.'е/u' => 'ye',
+                       '/'.self::WB.'Е(['.Crh::C_LC.'cğñqöü])/u' => 'Ye$1',
+                       '/'.self::WB.'Е(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'YE$1',
+                       '/'.self::WB.'я/u' => 'ya',
+                       '/'.self::WB.'Я(['.Crh::C_LC.'cğñqöü])/u' => 'Ya$1',
+                       '/'.self::WB.'Я(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'YA$1',
                        '/([аеёиоуыэюяйьъaeöüАЕЁИОУЫЭЮЯЙЬЪAEÖÜ])е/u' => '$1ye',
                        '/([аеёиоуыэюяйьъaeöüАЕЁИОУЫЭЮЯЙЬЪAEÖÜ])Е(['.Crh::C_LC.'cğñqöü])/u' => '$1Ye$2',
                        '/([аеёиоуыэюяйьъaeöüАЕЁИОУЫЭЮЯЙЬЪAEÖÜ])Е(['.Crh::C_UC.'CĞÑQÖÜ])/u' => '$1YE$2',
@@ -567,12 +580,12 @@ class CrhExceptions {
 
                        # остальные вхождения о, у, ё, ю
                        # other occurences of о, у, ё, ю
-                       '/Ё(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'YO$2',
-                       '/Ю(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'YU$2',
+                       '/Ё(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'YO$1',
+                       '/Ю(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'YU$1',
 
                        # Ц & Щ
-                       '/Ц(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'TS$2',
-                       '/Щ(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'ŞÇ$2',
+                       '/Ц(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'TS$1',
+                       '/Щ(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'ŞÇ$1',
                ];
 
                $this->Latn2CyrlRegexes = [
@@ -580,97 +593,103 @@ class CrhExceptions {
                        // TODO: refactor upper/lower/first capital whole words without
                        // regexes into simpler list
 
-                       '/\ban\b/u' => 'ань',
-                       '/\bAn\b/u' => 'Ань',
-                       '/\bAN\b/u' => 'АНЬ',
-                       '/\bange\b/u' => 'аньге',
-                       '/\bAnge\b/u' => 'Аньге',
-                       '/\bANGE\b/u' => 'АНЬГЕ',
-                       '/\bande\b/u' => 'аньде',
-                       '/\bAnde\b/u' => 'Аньде',
-                       '/\bANDE\b/u' => 'АНЬДЕ',
-                       '/\banki\b/u' => 'аньки',
-                       '/\bAnki\b/u' => 'Аньки',
-                       '/\bANKİ\b/u' => 'АНЬКИ',
-                       '/\bderal\b/u' => 'деръал',
-                       '/\bDeral\b/u' => 'Деръал',
-                       '/\bDERAL\b/u' => 'ДЕРЪАЛ',
-                       '/\bkör\b/u' => 'кёр',
-                       '/\bKör\b/u' => 'Кёр',
-                       '/\bKÖR\b/u' => 'КЁР',
-                       '/\bmer\b/u' => 'мэр',
-                       '/\bMer\b/u' => 'Мэр',
-                       '/\bMER\b/u' => 'МЭР',
-
-                       '/\bджонк/u' => 'cönk',
-                       '/\bДжонк/u' => 'Cönk',
-                       '/\bДЖОНК/u' => 'CÖNK',
-
-                       '/\bкуркчи/u' => 'kürkçi',
-                       '/\bКуркчи/u' => 'Kürkçi',
-                       '/\bКУРКЧИ/u' => 'KÜRKÇI',
+                       '/'.self::WB.'an'.self::WB.'/u' => 'ань',
+                       '/'.self::WB.'An'.self::WB.'/u' => 'Ань',
+                       '/'.self::WB.'AN'.self::WB.'/u' => 'АНЬ',
+                       '/'.self::WB.'ange'.self::WB.'/u' => 'аньге',
+                       '/'.self::WB.'Ange'.self::WB.'/u' => 'Аньге',
+                       '/'.self::WB.'ANGE'.self::WB.'/u' => 'АНЬГЕ',
+                       '/'.self::WB.'ande'.self::WB.'/u' => 'аньде',
+                       '/'.self::WB.'Ande'.self::WB.'/u' => 'Аньде',
+                       '/'.self::WB.'ANDE'.self::WB.'/u' => 'АНЬДЕ',
+                       '/'.self::WB.'anki'.self::WB.'/u' => 'аньки',
+                       '/'.self::WB.'Anki'.self::WB.'/u' => 'Аньки',
+                       '/'.self::WB.'ANKİ'.self::WB.'/u' => 'АНЬКИ',
+                       '/'.self::WB.'deral'.self::WB.'/u' => 'деръал',
+                       '/'.self::WB.'Deral'.self::WB.'/u' => 'Деръал',
+                       '/'.self::WB.'DERAL'.self::WB.'/u' => 'ДЕРЪАЛ',
+                       '/'.self::WB.'kör'.self::WB.'/u' => 'кёр',
+                       '/'.self::WB.'Kör'.self::WB.'/u' => 'Кёр',
+                       '/'.self::WB.'KÖR'.self::WB.'/u' => 'КЁР',
+                       '/'.self::WB.'mer'.self::WB.'/u' => 'мэр',
+                       '/'.self::WB.'Mer'.self::WB.'/u' => 'Мэр',
+                       '/'.self::WB.'MER'.self::WB.'/u' => 'МЭР',
+
+                       '/'.self::WB.'джонк/u' => 'cönk',
+                       '/'.self::WB.'Джонк/u' => 'Cönk',
+                       '/'.self::WB.'ДЖОНК/u' => 'CÖNK',
+
+                       '/'.self::WB.'куркчи/u' => 'kürkçi',
+                       '/'.self::WB.'Куркчи/u' => 'Kürkçi',
+                       '/'.self::WB.'КУРКЧИ/u' => 'KÜRKÇI',
 
                        # буква Ё - первый заход
                        # расставляем Ь после согласных
-                       '/\b([yY])ö(['.Crh::L_N_CONS.'])([aAuU'.Crh::L_CONS.']|\b)/u' => '$1ö$2ь$3',
-                       '/\b([yY])Ö(['.Crh::L_N_CONS.'])([aAuU'.Crh::L_CONS.']|\b)/u' => '$1Ö$2Ь$3',
-                       '/\bAQŞ([^AEI]|\b)/u' => 'АКъШ$1',
+                       '/'.self::WB.'([yY])ö(['.Crh::L_N_CONS.'])([aAuU'.Crh::L_CONS.']|'.self::WB.')/u' => '$1ö$2ь$3',
+                       '/'.self::WB.'([yY])Ö(['.Crh::L_N_CONS.'])([aAuU'.Crh::L_CONS.']|'.self::WB.')/u' => '$1Ö$2Ь$3',
+                       '/'.self::WB.'AQŞ([^AEI]|'.self::WB.')/u' => 'АКъШ$1',
 
                        # буква Ю - первый заход
                        # расставляем Ь после согласных
-                       '/\b([yY])ü(['.Crh::L_N_CONS.'])([aAuU'.Crh::L_CONS.']|\b)/u' => '$1ü$2ь$3',
-                       '/\b([yY])Ü(['.Crh::L_N_CONS.'])([aAuU'.Crh::L_CONS.']|\b)/u' => '$1Ü$2Ь$3',
-
-                       '/\b([bcgkpşBCGKPŞ])ö(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|\b)/u' => '$1ö$2ь$3',
-                       '/\b([bcgkpşBCGKPŞ])Ö(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|\b)/u' => '$1Ö$2Ь$3',
-                       '/\b([bcgkpşBCGKPŞ])Ö(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|\b)/u' => '$1Ö$2Ь$3',
-                       '/\b([bcgkpşBCGKPŞ])ü(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|\b)/u' => '$1ü$2ь$3',
-                       '/\b([bcgkpşBCGKPŞ])Ü(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|\b)/u' => '$1Ü$2Ь$3',
-                       '/\b([bcgkpşBCGKPŞ])Ü(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|\b)/u' => '$1Ü$2Ь$3',
+                       '/'.self::WB.'([yY])ü(['.Crh::L_N_CONS.'])([aAuU'.Crh::L_CONS.']|'.self::WB.')/u' => '$1ü$2ь$3',
+                       '/'.self::WB.'([yY])Ü(['.Crh::L_N_CONS.'])([aAuU'.Crh::L_CONS.']|'.self::WB.')/u' => '$1Ü$2Ь$3',
+
+                       '/'.self::WB.'([bcgkpşBCGKPŞ])ö(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|'.self::WB.')/u'
+                               => '$1ö$2ь$3',
+                       '/'.self::WB.'([bcgkpşBCGKPŞ])Ö(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|'.self::WB.')/u'
+                               => '$1Ö$2Ь$3',
+                       '/'.self::WB.'([bcgkpşBCGKPŞ])Ö(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|'.self::WB.')/u'
+                               => '$1Ö$2Ь$3',
+                       '/'.self::WB.'([bcgkpşBCGKPŞ])ü(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|'.self::WB.')/u'
+                               => '$1ü$2ь$3',
+                       '/'.self::WB.'([bcgkpşBCGKPŞ])Ü(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|'.self::WB.')/u'
+                               => '$1Ü$2Ь$3',
+                       '/'.self::WB.'([bcgkpşBCGKPŞ])Ü(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|'.self::WB.')/u'
+                               => '$1Ü$2Ь$3',
 
                         # ö и ü в начале слова
                         # случаи, когда нужен Ь
-                       '/\bö(['.Crh::L_N_CONS.'pP])(['.Crh::L_CONS.']|\b)/u' => 'ö$1ь$2',
-                       '/\bÖ(['.Crh::L_N_CONS_LC.'p])(['.Crh::L_CONS.']|\b)/u' => 'Ö$1ь$2',
-                       '/\bÖ(['.Crh::L_N_CONS_UC.'P])(['.Crh::L_CONS.']|\b)/u' => 'Ö$1Ь$2',
-                       '/\bü(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|\b)/u' => 'ü$1ь$2',
-                       '/\bÜ(['.Crh::L_N_CONS_LC.'])(['.Crh::L_CONS.']|\b)/u' => 'Ü$1ь$2',
-                       '/\bÜ(['.Crh::L_N_CONS_UC.'])(['.Crh::L_CONS.']|\b)/u' => 'Ü$1Ь$2',
-
-                       '/ts\b/u' => 'ц',
-                       '/şç\b/u' => 'щ',
-                       '/Ş[çÇ]\b/u' => 'Щ',
-                       '/T[sS]\b/u' => 'Ц',
+                       '/'.self::WB.'ö(['.Crh::L_N_CONS.'pP])(['.Crh::L_CONS.']|'.self::WB.')/u' => 'ö$1ь$2',
+                       '/'.self::WB.'Ö(['.Crh::L_N_CONS_LC.'p])(['.Crh::L_CONS.']|'.self::WB.')/u' => 'Ö$1ь$2',
+                       '/'.self::WB.'Ö(['.Crh::L_N_CONS_UC.'P])(['.Crh::L_CONS.']|'.self::WB.')/u' => 'Ö$1Ь$2',
+                       '/'.self::WB.'ü(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|'.self::WB.')/u' => 'ü$1ь$2',
+                       '/'.self::WB.'Ü(['.Crh::L_N_CONS_LC.'])(['.Crh::L_CONS.']|'.self::WB.')/u' => 'Ü$1ь$2',
+                       '/'.self::WB.'Ü(['.Crh::L_N_CONS_UC.'])(['.Crh::L_CONS.']|'.self::WB.')/u' => 'Ü$1Ь$2',
+
+                       '/ts'.self::WB.'/u' => 'ц',
+                       '/şç'.self::WB.'/u' => 'щ',
+                       '/Ş[çÇ]'.self::WB.'/u' => 'Щ',
+                       '/T[sS]'.self::WB.'/u' => 'Ц',
 
                        # Ь после Л
                        # add Ь after Л
-                       '/(['.Crh::L_F.'])l(['.Crh::L_CONS_LC.']|\b)/u' => '$1ль$2',
-                       '/(['.Crh::L_F_UC.'])L(['.Crh::L_CONS.']|\b)/u' => '$1ЛЬ$2',
+                       '/(['.Crh::L_F.'])l(['.Crh::L_CONS_LC.']|'.self::WB.')/u' => '$1ль$2',
+                       '/(['.Crh::L_F_UC.'])L(['.Crh::L_CONS.']|'.self::WB.')/u' => '$1ЛЬ$2',
 
-                       '/etsin\b/u' => 'етсин',
-                       '/Etsin\b/u' => 'Етсин',
-                       '/ETSİN\b/u' => 'ЕТСИН',
+                       '/etsin'.self::WB.'/u' => 'етсин',
+                       '/Etsin'.self::WB.'/u' => 'Етсин',
+                       '/ETSİN'.self::WB.'/u' => 'ЕТСИН',
 
                        # относятся к началу слова
-                       '/\bts/u' => 'ц',
-                       '/\bT[sS]/u' => 'Ц',
+                       '/'.self::WB.'ts/u' => 'ц',
+                       '/'.self::WB.'T[sS]/u' => 'Ц',
 
-                       '/\bşç/u' => 'щ',
-                       '/\bŞ[çÇ]/u' => 'Щ',
+                       '/'.self::WB.'şç/u' => 'щ',
+                       '/'.self::WB.'Ş[çÇ]/u' => 'Щ',
 
                        # Э
-                       '/(\b|['.Crh::L_VOW.'аеэяАЕЭЯ])e/u' => '$1э',
-                       '/(\b|['.Crh::L_VOW_UC.'АЕЭЯ])E/u' => '$1Э',
+                       '/('.self::WB.'|['.Crh::L_VOW.'аеэяАЕЭЯ])e/u' => '$1э',
+                       '/('.self::WB.'|['.Crh::L_VOW_UC.'АЕЭЯ])E/u' => '$1Э',
 
-                       '/\b(['.Crh::L_M_CONS.'])ö/u' => '$1о',
-                       '/\b(['.Crh::L_M_CONS.'])Ö/u' => '$1О',
-                       '/\b(['.Crh::L_M_CONS.'])ü/u' => '$1у',
-                       '/\b(['.Crh::L_M_CONS.'])Ü/u' => '$1У',
+                       '/'.self::WB.'(['.Crh::L_M_CONS.'])ö/u' => '$1о',
+                       '/'.self::WB.'(['.Crh::L_M_CONS.'])Ö/u' => '$1О',
+                       '/'.self::WB.'(['.Crh::L_M_CONS.'])ü/u' => '$1у',
+                       '/'.self::WB.'(['.Crh::L_M_CONS.'])Ü/u' => '$1У',
 
-                       '/\bö/u' => 'о',
-                       '/\bÖ/u' => 'О',
-                       '/\bü/u' => 'у',
-                       '/\bÜ/u' => 'У',
+                       '/'.self::WB.'ö/u' => 'о',
+                       '/'.self::WB.'Ö/u' => 'О',
+                       '/'.self::WB.'ü/u' => 'у',
+                       '/'.self::WB.'Ü/u' => 'У',
 
                        # некоторые исключения
                        # some exceptions
@@ -685,7 +704,7 @@ class CrhExceptions {
                        '/KÖZ([^EÜ])/u' => 'КОЗЬ$1',
 
                        # Punctuation
-                       '/#|No\./' => '№',
+                       '/#|No\./u' => '№',
 
                        # некоторые случаи употребления Ц
                        '/tsi([^zñ])/u' => 'ци$1',
index 9943212..737c20f 100644 (file)
@@ -271,7 +271,7 @@ class Names {
                'li' => 'Limburgs', # Limburgian
                'lij' => 'Ligure', # Ligurian
                'liv' => 'Līvõ kēļ', # Livonian
-               'lki' => 'لەکی', # Laki
+               'lki' => 'لەکی', # Laki
                'lmo' => 'lumbaart', # Lombard
                'ln' => 'lingála', # Lingala
                'lo' => 'ລາວ', # Laotian
@@ -386,6 +386,7 @@ class Names {
                'shi-tfng' => 'ⵜⴰⵛⵍⵃⵉⵜ', # Tachelhit (Tifinagh script)
                'shi-latn' => 'Tašlḥiyt', # Tachelhit (Latin script)
                'shn' => 'ၽႃႇသႃႇတႆး ', # Shan
+               'shy-latn' => 'tachawit', # Shawiya (Latin script) - T194047
                'si' => 'සිංහල', # Sinhalese
                'simple' => 'Simple English', # Simple English
                'sk' => 'slovenčina', # Slovak
diff --git a/languages/data/normalize-ar.php b/languages/data/normalize-ar.php
new file mode 100644 (file)
index 0000000..c1daf20
--- /dev/null
@@ -0,0 +1,735 @@
+<?php
+// File created by maintenance/generateNormalizerDataAr.php
+return [
+       'ﭐ' => 'ٱ',
+       'ﭑ' => 'ٱ',
+       'ﭒ' => 'ٻ',
+       'ﭓ' => 'ٻ',
+       'ﭔ' => 'ٻ',
+       'ﭕ' => 'ٻ',
+       'ﭖ' => 'پ',
+       'ﭗ' => 'پ',
+       'ﭘ' => 'پ',
+       'ﭙ' => 'پ',
+       'ﭚ' => 'ڀ',
+       'ﭛ' => 'ڀ',
+       'ﭜ' => 'ڀ',
+       'ﭝ' => 'ڀ',
+       'ﭞ' => 'ٺ',
+       'ﭟ' => 'ٺ',
+       'ﭠ' => 'ٺ',
+       'ﭡ' => 'ٺ',
+       'ﭢ' => 'ٿ',
+       'ﭣ' => 'ٿ',
+       'ﭤ' => 'ٿ',
+       'ﭥ' => 'ٿ',
+       'ﭦ' => 'ٹ',
+       'ﭧ' => 'ٹ',
+       'ﭨ' => 'ٹ',
+       'ﭩ' => 'ٹ',
+       'ﭪ' => 'ڤ',
+       'ﭫ' => 'ڤ',
+       'ﭬ' => 'ڤ',
+       'ﭭ' => 'ڤ',
+       'ﭮ' => 'ڦ',
+       'ﭯ' => 'ڦ',
+       'ﭰ' => 'ڦ',
+       'ﭱ' => 'ڦ',
+       'ﭲ' => 'ڄ',
+       'ﭳ' => 'ڄ',
+       'ﭴ' => 'ڄ',
+       'ﭵ' => 'ڄ',
+       'ﭶ' => 'ڃ',
+       'ﭷ' => 'ڃ',
+       'ﭸ' => 'ڃ',
+       'ﭹ' => 'ڃ',
+       'ﭺ' => 'چ',
+       'ﭻ' => 'چ',
+       'ﭼ' => 'چ',
+       'ﭽ' => 'چ',
+       'ﭾ' => 'ڇ',
+       'ﭿ' => 'ڇ',
+       'ﮀ' => 'ڇ',
+       'ﮁ' => 'ڇ',
+       'ﮂ' => 'ڍ',
+       'ﮃ' => 'ڍ',
+       'ﮄ' => 'ڌ',
+       'ﮅ' => 'ڌ',
+       'ﮆ' => 'ڎ',
+       'ﮇ' => 'ڎ',
+       'ﮈ' => 'ڈ',
+       'ﮉ' => 'ڈ',
+       'ﮊ' => 'ژ',
+       'ﮋ' => 'ژ',
+       'ﮌ' => 'ڑ',
+       'ﮍ' => 'ڑ',
+       'ﮎ' => 'ک',
+       'ﮏ' => 'ک',
+       'ﮐ' => 'ک',
+       'ﮑ' => 'ک',
+       'ﮒ' => 'گ',
+       'ﮓ' => 'گ',
+       'ﮔ' => 'گ',
+       'ﮕ' => 'گ',
+       'ﮖ' => 'ڳ',
+       'ﮗ' => 'ڳ',
+       'ﮘ' => 'ڳ',
+       'ﮙ' => 'ڳ',
+       'ﮚ' => 'ڱ',
+       'ﮛ' => 'ڱ',
+       'ﮜ' => 'ڱ',
+       'ﮝ' => 'ڱ',
+       'ﮞ' => 'ں',
+       'ﮟ' => 'ں',
+       'ﮠ' => 'ڻ',
+       'ﮡ' => 'ڻ',
+       'ﮢ' => 'ڻ',
+       'ﮣ' => 'ڻ',
+       'ﮤ' => 'ۀ',
+       'ﮥ' => 'ۀ',
+       'ﮦ' => 'ہ',
+       'ﮧ' => 'ہ',
+       'ﮨ' => 'ہ',
+       'ﮩ' => 'ہ',
+       'ﮪ' => 'ھ',
+       'ﮫ' => 'ھ',
+       'ﮬ' => 'ھ',
+       'ﮭ' => 'ھ',
+       'ﮮ' => 'ے',
+       'ﮯ' => 'ے',
+       'ﮰ' => 'ۓ',
+       'ﮱ' => 'ۓ',
+       'ﯓ' => 'ڭ',
+       'ﯔ' => 'ڭ',
+       'ﯕ' => 'ڭ',
+       'ﯖ' => 'ڭ',
+       'ﯗ' => 'ۇ',
+       'ﯘ' => 'ۇ',
+       'ﯙ' => 'ۆ',
+       'ﯚ' => 'ۆ',
+       'ﯛ' => 'ۈ',
+       'ﯜ' => 'ۈ',
+       'ﯝ' => 'ٷ',
+       'ﯞ' => 'ۋ',
+       'ﯟ' => 'ۋ',
+       'ﯠ' => 'ۅ',
+       'ﯡ' => 'ۅ',
+       'ﯢ' => 'ۉ',
+       'ﯣ' => 'ۉ',
+       'ﯤ' => 'ې',
+       'ﯥ' => 'ې',
+       'ﯦ' => 'ې',
+       'ﯧ' => 'ې',
+       'ﯨ' => 'ى',
+       'ﯩ' => 'ى',
+       'ﯪ' => 'ئا',
+       'ﯫ' => 'ئا',
+       'ﯬ' => 'ئە',
+       'ﯭ' => 'ئە',
+       'ﯮ' => 'ئو',
+       'ﯯ' => 'ئو',
+       'ﯰ' => 'ئۇ',
+       'ﯱ' => 'ئۇ',
+       'ﯲ' => 'ئۆ',
+       'ﯳ' => 'ئۆ',
+       'ﯴ' => 'ئۈ',
+       'ﯵ' => 'ئۈ',
+       'ﯶ' => 'ئې',
+       'ﯷ' => 'ئې',
+       'ﯸ' => 'ئې',
+       'ﯹ' => 'ئى',
+       'ﯺ' => 'ئى',
+       'ﯻ' => 'ئى',
+       'ﯼ' => 'ی',
+       'ﯽ' => 'ی',
+       'ﯾ' => 'ی',
+       'ﯿ' => 'ی',
+       'ﰀ' => 'ئج',
+       'ﰁ' => 'ئح',
+       'ﰂ' => 'ئم',
+       'ﰃ' => 'ئى',
+       'ﰄ' => 'ئي',
+       'ﰅ' => 'بج',
+       'ﰆ' => 'بح',
+       'ﰇ' => 'بخ',
+       'ﰈ' => 'بم',
+       'ﰉ' => 'بى',
+       'ﰊ' => 'بي',
+       'ﰋ' => 'تج',
+       'ﰌ' => 'تح',
+       'ﰍ' => 'تخ',
+       'ﰎ' => 'تم',
+       'ﰏ' => 'تى',
+       'ﰐ' => 'تي',
+       'ﰑ' => 'ثج',
+       'ﰒ' => 'ثم',
+       'ﰓ' => 'ثى',
+       'ﰔ' => 'ثي',
+       'ﰕ' => 'جح',
+       'ﰖ' => 'جم',
+       'ﰗ' => 'حج',
+       'ﰘ' => 'حم',
+       'ﰙ' => 'خج',
+       'ﰚ' => 'خح',
+       'ﰛ' => 'خم',
+       'ﰜ' => 'سج',
+       'ﰝ' => 'سح',
+       'ﰞ' => 'سخ',
+       'ﰟ' => 'سم',
+       'ﰠ' => 'صح',
+       'ﰡ' => 'صم',
+       'ﰢ' => 'ضج',
+       'ﰣ' => 'ضح',
+       'ﰤ' => 'ضخ',
+       'ﰥ' => 'ضم',
+       'ﰦ' => 'طح',
+       'ﰧ' => 'طم',
+       'ﰨ' => 'ظم',
+       'ﰩ' => 'عج',
+       'ﰪ' => 'عم',
+       'ﰫ' => 'غج',
+       'ﰬ' => 'غم',
+       'ﰭ' => 'فج',
+       'ﰮ' => 'فح',
+       'ﰯ' => 'فخ',
+       'ﰰ' => 'فم',
+       'ﰱ' => 'فى',
+       'ﰲ' => 'في',
+       'ﰳ' => 'قح',
+       'ﰴ' => 'قم',
+       'ﰵ' => 'قى',
+       'ﰶ' => 'قي',
+       'ﰷ' => 'كا',
+       'ﰸ' => 'كج',
+       'ﰹ' => 'كح',
+       'ﰺ' => 'كخ',
+       'ﰻ' => 'كل',
+       'ﰼ' => 'كم',
+       'ﰽ' => 'كى',
+       'ﰾ' => 'كي',
+       'ﰿ' => 'لج',
+       'ﱀ' => 'لح',
+       'ﱁ' => 'لخ',
+       'ﱂ' => 'لم',
+       'ﱃ' => 'لى',
+       'ﱄ' => 'لي',
+       'ﱅ' => 'مج',
+       'ﱆ' => 'مح',
+       'ﱇ' => 'مخ',
+       'ﱈ' => 'مم',
+       'ﱉ' => 'مى',
+       'ﱊ' => 'مي',
+       'ﱋ' => 'نج',
+       'ﱌ' => 'نح',
+       'ﱍ' => 'نخ',
+       'ﱎ' => 'نم',
+       'ﱏ' => 'نى',
+       'ﱐ' => 'ني',
+       'ﱑ' => 'هج',
+       'ﱒ' => 'هم',
+       'ﱓ' => 'هى',
+       'ﱔ' => 'هي',
+       'ﱕ' => 'يج',
+       'ﱖ' => 'يح',
+       'ﱗ' => 'يخ',
+       'ﱘ' => 'يم',
+       'ﱙ' => 'يى',
+       'ﱚ' => 'يي',
+       'ﱛ' => 'ذٰ',
+       'ﱜ' => 'رٰ',
+       'ﱝ' => 'ىٰ',
+       'ﱞ' => ' ٌّ',
+       'ﱟ' => ' ٍّ',
+       'ﱠ' => ' َّ',
+       'ﱡ' => ' ُّ',
+       'ﱢ' => ' ِّ',
+       'ﱣ' => ' ّٰ',
+       'ﱤ' => 'ئر',
+       'ﱥ' => 'ئز',
+       'ﱦ' => 'ئم',
+       'ﱧ' => 'ئن',
+       'ﱨ' => 'ئى',
+       'ﱩ' => 'ئي',
+       'ﱪ' => 'بر',
+       'ﱫ' => 'بز',
+       'ﱬ' => 'بم',
+       'ﱭ' => 'بن',
+       'ﱮ' => 'بى',
+       'ﱯ' => 'بي',
+       'ﱰ' => 'تر',
+       'ﱱ' => 'تز',
+       'ﱲ' => 'تم',
+       'ﱳ' => 'تن',
+       'ﱴ' => 'تى',
+       'ﱵ' => 'تي',
+       'ﱶ' => 'ثر',
+       'ﱷ' => 'ثز',
+       'ﱸ' => 'ثم',
+       'ﱹ' => 'ثن',
+       'ﱺ' => 'ثى',
+       'ﱻ' => 'ثي',
+       'ﱼ' => 'فى',
+       'ﱽ' => 'في',
+       'ﱾ' => 'قى',
+       'ﱿ' => 'قي',
+       'ﲀ' => 'كا',
+       'ﲁ' => 'كل',
+       'ﲂ' => 'كم',
+       'ﲃ' => 'كى',
+       'ﲄ' => 'كي',
+       'ﲅ' => 'لم',
+       'ﲆ' => 'لى',
+       'ﲇ' => 'لي',
+       'ﲈ' => 'ما',
+       'ﲉ' => 'مم',
+       'ﲊ' => 'نر',
+       'ﲋ' => 'نز',
+       'ﲌ' => 'نم',
+       'ﲍ' => 'نن',
+       'ﲎ' => 'نى',
+       'ﲏ' => 'ني',
+       'ﲐ' => 'ىٰ',
+       'ﲑ' => 'ير',
+       'ﲒ' => 'يز',
+       'ﲓ' => 'يم',
+       'ﲔ' => 'ين',
+       'ﲕ' => 'يى',
+       'ﲖ' => 'يي',
+       'ﲗ' => 'ئج',
+       'ﲘ' => 'ئح',
+       'ﲙ' => 'ئخ',
+       'ﲚ' => 'ئم',
+       'ﲛ' => 'ئه',
+       'ﲜ' => 'بج',
+       'ﲝ' => 'بح',
+       'ﲞ' => 'بخ',
+       'ﲟ' => 'بم',
+       'ﲠ' => 'به',
+       'ﲡ' => 'تج',
+       'ﲢ' => 'تح',
+       'ﲣ' => 'تخ',
+       'ﲤ' => 'تم',
+       'ﲥ' => 'ته',
+       'ﲦ' => 'ثم',
+       'ﲧ' => 'جح',
+       'ﲨ' => 'جم',
+       'ﲩ' => 'حج',
+       'ﲪ' => 'حم',
+       'ﲫ' => 'خج',
+       'ﲬ' => 'خم',
+       'ﲭ' => 'سج',
+       'ﲮ' => 'سح',
+       'ﲯ' => 'سخ',
+       'ﲰ' => 'سم',
+       'ﲱ' => 'صح',
+       'ﲲ' => 'صخ',
+       'ﲳ' => 'صم',
+       'ﲴ' => 'ضج',
+       'ﲵ' => 'ضح',
+       'ﲶ' => 'ضخ',
+       'ﲷ' => 'ضم',
+       'ﲸ' => 'طح',
+       'ﲹ' => 'ظم',
+       'ﲺ' => 'عج',
+       'ﲻ' => 'عم',
+       'ﲼ' => 'غج',
+       'ﲽ' => 'غم',
+       'ﲾ' => 'فج',
+       'ﲿ' => 'فح',
+       'ﳀ' => 'فخ',
+       'ﳁ' => 'فم',
+       'ﳂ' => 'قح',
+       'ﳃ' => 'قم',
+       'ﳄ' => 'كج',
+       'ﳅ' => 'كح',
+       'ﳆ' => 'كخ',
+       'ﳇ' => 'كل',
+       'ﳈ' => 'كم',
+       'ﳉ' => 'لج',
+       'ﳊ' => 'لح',
+       'ﳋ' => 'لخ',
+       'ﳌ' => 'لم',
+       'ﳍ' => 'له',
+       'ﳎ' => 'مج',
+       'ﳏ' => 'مح',
+       'ﳐ' => 'مخ',
+       'ﳑ' => 'مم',
+       'ﳒ' => 'نج',
+       'ﳓ' => 'نح',
+       'ﳔ' => 'نخ',
+       'ﳕ' => 'نم',
+       'ﳖ' => 'نه',
+       'ﳗ' => 'هج',
+       'ﳘ' => 'هم',
+       'ﳙ' => 'هٰ',
+       'ﳚ' => 'يج',
+       'ﳛ' => 'يح',
+       'ﳜ' => 'يخ',
+       'ﳝ' => 'يم',
+       'ﳞ' => 'يه',
+       'ﳟ' => 'ئم',
+       'ﳠ' => 'ئه',
+       'ﳡ' => 'بم',
+       'ﳢ' => 'به',
+       'ﳣ' => 'تم',
+       'ﳤ' => 'ته',
+       'ﳥ' => 'ثم',
+       'ﳦ' => 'ثه',
+       'ﳧ' => 'سم',
+       'ﳨ' => 'سه',
+       'ﳩ' => 'شم',
+       'ﳪ' => 'شه',
+       'ﳫ' => 'كل',
+       'ﳬ' => 'كم',
+       'ﳭ' => 'لم',
+       'ﳮ' => 'نم',
+       'ﳯ' => 'نه',
+       'ﳰ' => 'يم',
+       'ﳱ' => 'يه',
+       'ﳲ' => 'ـَّ',
+       'ﳳ' => 'ـُّ',
+       'ﳴ' => 'ـِّ',
+       'ﳵ' => 'طى',
+       'ﳶ' => 'طي',
+       'ﳷ' => 'عى',
+       'ﳸ' => 'عي',
+       'ﳹ' => 'غى',
+       'ﳺ' => 'غي',
+       'ﳻ' => 'سى',
+       'ﳼ' => 'سي',
+       'ﳽ' => 'شى',
+       'ﳾ' => 'شي',
+       'ﳿ' => 'حى',
+       'ﴀ' => 'حي',
+       'ﴁ' => 'جى',
+       'ﴂ' => 'جي',
+       'ﴃ' => 'خى',
+       'ﴄ' => 'خي',
+       'ﴅ' => 'صى',
+       'ﴆ' => 'صي',
+       'ﴇ' => 'ضى',
+       'ﴈ' => 'ضي',
+       'ﴉ' => 'شج',
+       'ﴊ' => 'شح',
+       'ﴋ' => 'شخ',
+       'ﴌ' => 'شم',
+       'ﴍ' => 'شر',
+       'ﴎ' => 'سر',
+       'ﴏ' => 'صر',
+       'ﴐ' => 'ضر',
+       'ﴑ' => 'طى',
+       'ﴒ' => 'طي',
+       'ﴓ' => 'عى',
+       'ﴔ' => 'عي',
+       'ﴕ' => 'غى',
+       'ﴖ' => 'غي',
+       'ﴗ' => 'سى',
+       'ﴘ' => 'سي',
+       'ﴙ' => 'شى',
+       'ﴚ' => 'شي',
+       'ﴛ' => 'حى',
+       'ﴜ' => 'حي',
+       'ﴝ' => 'جى',
+       'ﴞ' => 'جي',
+       'ﴟ' => 'خى',
+       'ﴠ' => 'خي',
+       'ﴡ' => 'صى',
+       'ﴢ' => 'صي',
+       'ﴣ' => 'ضى',
+       'ﴤ' => 'ضي',
+       'ﴥ' => 'شج',
+       'ﴦ' => 'شح',
+       'ﴧ' => 'شخ',
+       'ﴨ' => 'شم',
+       'ﴩ' => 'شر',
+       'ﴪ' => 'سر',
+       'ﴫ' => 'صر',
+       'ﴬ' => 'ضر',
+       'ﴭ' => 'شج',
+       'ﴮ' => 'شح',
+       'ﴯ' => 'شخ',
+       'ﴰ' => 'شم',
+       'ﴱ' => 'سه',
+       'ﴲ' => 'شه',
+       'ﴳ' => 'طم',
+       'ﴴ' => 'سج',
+       'ﴵ' => 'سح',
+       'ﴶ' => 'سخ',
+       'ﴷ' => 'شج',
+       'ﴸ' => 'شح',
+       'ﴹ' => 'شخ',
+       'ﴺ' => 'طم',
+       'ﴻ' => 'ظم',
+       'ﴼ' => 'اً',
+       'ﴽ' => 'اً',
+       'ﵐ' => 'تجم',
+       'ﵑ' => 'تحج',
+       'ﵒ' => 'تحج',
+       'ﵓ' => 'تحم',
+       'ﵔ' => 'تخم',
+       'ﵕ' => 'تمج',
+       'ﵖ' => 'تمح',
+       'ﵗ' => 'تمخ',
+       'ﵘ' => 'جمح',
+       'ﵙ' => 'جمح',
+       'ﵚ' => 'حمي',
+       'ﵛ' => 'حمى',
+       'ﵜ' => 'سحج',
+       'ﵝ' => 'سجح',
+       'ﵞ' => 'سجى',
+       'ﵟ' => 'سمح',
+       'ﵠ' => 'سمح',
+       'ﵡ' => 'سمج',
+       'ﵢ' => 'سمم',
+       'ﵣ' => 'سمم',
+       'ﵤ' => 'صحح',
+       'ﵥ' => 'صحح',
+       'ﵦ' => 'صمم',
+       'ﵧ' => 'شحم',
+       'ﵨ' => 'شحم',
+       'ﵩ' => 'شجي',
+       'ﵪ' => 'شمخ',
+       'ﵫ' => 'شمخ',
+       'ﵬ' => 'شمم',
+       'ﵭ' => 'شمم',
+       'ﵮ' => 'ضحى',
+       'ﵯ' => 'ضخم',
+       'ﵰ' => 'ضخم',
+       'ﵱ' => 'طمح',
+       'ﵲ' => 'طمح',
+       'ﵳ' => 'طمم',
+       'ﵴ' => 'طمي',
+       'ﵵ' => 'عجم',
+       'ﵶ' => 'عمم',
+       'ﵷ' => 'عمم',
+       'ﵸ' => 'عمى',
+       'ﵹ' => 'غمم',
+       'ﵺ' => 'غمي',
+       'ﵻ' => 'غمى',
+       'ﵼ' => 'فخم',
+       'ﵽ' => 'فخم',
+       'ﵾ' => 'قمح',
+       'ﵿ' => 'قمم',
+       'ﶀ' => 'لحم',
+       'ﶁ' => 'لحي',
+       'ﶂ' => 'لحى',
+       'ﶃ' => 'لجج',
+       'ﶄ' => 'لجج',
+       'ﶅ' => 'لخم',
+       'ﶆ' => 'لخم',
+       'ﶇ' => 'لمح',
+       'ﶈ' => 'لمح',
+       'ﶉ' => 'محج',
+       'ﶊ' => 'محم',
+       'ﶋ' => 'محي',
+       'ﶌ' => 'مجح',
+       'ﶍ' => 'مجم',
+       'ﶎ' => 'مخج',
+       'ﶏ' => 'مخم',
+       'ﶒ' => 'مجخ',
+       'ﶓ' => 'همج',
+       'ﶔ' => 'همم',
+       'ﶕ' => 'نحم',
+       'ﶖ' => 'نحى',
+       'ﶗ' => 'نجم',
+       'ﶘ' => 'نجم',
+       'ﶙ' => 'نجى',
+       'ﶚ' => 'نمي',
+       'ﶛ' => 'نمى',
+       'ﶜ' => 'يمم',
+       'ﶝ' => 'يمم',
+       'ﶞ' => 'بخي',
+       'ﶟ' => 'تجي',
+       'ﶠ' => 'تجى',
+       'ﶡ' => 'تخي',
+       'ﶢ' => 'تخى',
+       'ﶣ' => 'تمي',
+       'ﶤ' => 'تمى',
+       'ﶥ' => 'جمي',
+       'ﶦ' => 'جحى',
+       'ﶧ' => 'جمى',
+       'ﶨ' => 'سخى',
+       'ﶩ' => 'صحي',
+       'ﶪ' => 'شحي',
+       'ﶫ' => 'ضحي',
+       'ﶬ' => 'لجي',
+       'ﶭ' => 'لمي',
+       'ﶮ' => 'يحي',
+       'ﶯ' => 'يجي',
+       'ﶰ' => 'يمي',
+       'ﶱ' => 'ممي',
+       'ﶲ' => 'قمي',
+       'ﶳ' => 'نحي',
+       'ﶴ' => 'قمح',
+       'ﶵ' => 'لحم',
+       'ﶶ' => 'عمي',
+       'ﶷ' => 'كمي',
+       'ﶸ' => 'نجح',
+       'ﶹ' => 'مخي',
+       'ﶺ' => 'لجم',
+       'ﶻ' => 'كمم',
+       'ﶼ' => 'لجم',
+       'ﶽ' => 'نجح',
+       'ﶾ' => 'جحي',
+       'ﶿ' => 'حجي',
+       'ﷀ' => 'مجي',
+       'ﷁ' => 'فمي',
+       'ﷂ' => 'بحي',
+       'ﷃ' => 'كمم',
+       'ﷄ' => 'عجم',
+       'ﷅ' => 'صمم',
+       'ﷆ' => 'سخي',
+       'ﷇ' => 'نجي',
+       'ﷰ' => 'صلے',
+       'ﷱ' => 'قلے',
+       'ﷲ' => 'الله',
+       'ﷳ' => 'اكبر',
+       'ﷴ' => 'محمد',
+       'ﷵ' => 'صلعم',
+       'ﷶ' => 'رسول',
+       'ﷷ' => 'عليه',
+       'ﷸ' => 'وسلم',
+       'ﷹ' => 'صلى',
+       'ﷺ' => 'صلى الله عليه وسلم',
+       'ﷻ' => 'جل جلاله',
+       '﷼' => 'ریال',
+       'ﹰ' => ' ً',
+       'ﹱ' => 'ـً',
+       'ﹲ' => ' ٌ',
+       'ﹴ' => ' ٍ',
+       'ﹶ' => ' َ',
+       'ﹷ' => 'ـَ',
+       'ﹸ' => ' ُ',
+       'ﹹ' => 'ـُ',
+       'ﹺ' => ' ِ',
+       'ﹻ' => 'ـِ',
+       'ﹼ' => ' ّ',
+       'ﹽ' => 'ـّ',
+       'ﹾ' => ' ْ',
+       'ﹿ' => 'ـْ',
+       'ﺀ' => 'ء',
+       'ﺁ' => 'آ',
+       'ﺂ' => 'آ',
+       'ﺃ' => 'أ',
+       'ﺄ' => 'أ',
+       'ﺅ' => 'ؤ',
+       'ﺆ' => 'ؤ',
+       'ﺇ' => 'إ',
+       'ﺈ' => 'إ',
+       'ﺉ' => 'ئ',
+       'ﺊ' => 'ئ',
+       'ﺋ' => 'ئ',
+       'ﺌ' => 'ئ',
+       'ﺍ' => 'ا',
+       'ﺎ' => 'ا',
+       'ﺏ' => 'ب',
+       'ﺐ' => 'ب',
+       'ﺑ' => 'ب',
+       'ﺒ' => 'ب',
+       'ﺓ' => 'ة',
+       'ﺔ' => 'ة',
+       'ﺕ' => 'ت',
+       'ﺖ' => 'ت',
+       'ﺗ' => 'ت',
+       'ﺘ' => 'ت',
+       'ﺙ' => 'ث',
+       'ﺚ' => 'ث',
+       'ﺛ' => 'ث',
+       'ﺜ' => 'ث',
+       'ﺝ' => 'ج',
+       'ﺞ' => 'ج',
+       'ﺟ' => 'ج',
+       'ﺠ' => 'ج',
+       'ﺡ' => 'ح',
+       'ﺢ' => 'ح',
+       'ﺣ' => 'ح',
+       'ﺤ' => 'ح',
+       'ﺥ' => 'خ',
+       'ﺦ' => 'خ',
+       'ﺧ' => 'خ',
+       'ﺨ' => 'خ',
+       'ﺩ' => 'د',
+       'ﺪ' => 'د',
+       'ﺫ' => 'ذ',
+       'ﺬ' => 'ذ',
+       'ﺭ' => 'ر',
+       'ﺮ' => 'ر',
+       'ﺯ' => 'ز',
+       'ﺰ' => 'ز',
+       'ﺱ' => 'س',
+       'ﺲ' => 'س',
+       'ﺳ' => 'س',
+       'ﺴ' => 'س',
+       'ﺵ' => 'ش',
+       'ﺶ' => 'ش',
+       'ﺷ' => 'ش',
+       'ﺸ' => 'ش',
+       'ﺹ' => 'ص',
+       'ﺺ' => 'ص',
+       'ﺻ' => 'ص',
+       'ﺼ' => 'ص',
+       'ﺽ' => 'ض',
+       'ﺾ' => 'ض',
+       'ﺿ' => 'ض',
+       'ﻀ' => 'ض',
+       'ﻁ' => 'ط',
+       'ﻂ' => 'ط',
+       'ﻃ' => 'ط',
+       'ﻄ' => 'ط',
+       'ﻅ' => 'ظ',
+       'ﻆ' => 'ظ',
+       'ﻇ' => 'ظ',
+       'ﻈ' => 'ظ',
+       'ﻉ' => 'ع',
+       'ﻊ' => 'ع',
+       'ﻋ' => 'ع',
+       'ﻌ' => 'ع',
+       'ﻍ' => 'غ',
+       'ﻎ' => 'غ',
+       'ﻏ' => 'غ',
+       'ﻐ' => 'غ',
+       'ﻑ' => 'ف',
+       'ﻒ' => 'ف',
+       'ﻓ' => 'ف',
+       'ﻔ' => 'ف',
+       'ﻕ' => 'ق',
+       'ﻖ' => 'ق',
+       'ﻗ' => 'ق',
+       'ﻘ' => 'ق',
+       'ﻙ' => 'ك',
+       'ﻚ' => 'ك',
+       'ﻛ' => 'ك',
+       'ﻜ' => 'ك',
+       'ﻝ' => 'ل',
+       'ﻞ' => 'ل',
+       'ﻟ' => 'ل',
+       'ﻠ' => 'ل',
+       'ﻡ' => 'م',
+       'ﻢ' => 'م',
+       'ﻣ' => 'م',
+       'ﻤ' => 'م',
+       'ﻥ' => 'ن',
+       'ﻦ' => 'ن',
+       'ﻧ' => 'ن',
+       'ﻨ' => 'ن',
+       'ﻩ' => 'ه',
+       'ﻪ' => 'ه',
+       'ﻫ' => 'ه',
+       'ﻬ' => 'ه',
+       'ﻭ' => 'و',
+       'ﻮ' => 'و',
+       'ﻯ' => 'ى',
+       'ﻰ' => 'ى',
+       'ﻱ' => 'ي',
+       'ﻲ' => 'ي',
+       'ﻳ' => 'ي',
+       'ﻴ' => 'ي',
+       'ﻵ' => 'لآ',
+       'ﻶ' => 'لآ',
+       'ﻷ' => 'لأ',
+       'ﻸ' => 'لأ',
+       'ﻹ' => 'لإ',
+       'ﻺ' => 'لإ',
+       'ﻻ' => 'لا',
+       'ﻼ' => 'لا',
+];
diff --git a/languages/data/normalize-ml.php b/languages/data/normalize-ml.php
new file mode 100644 (file)
index 0000000..ca89a5a
--- /dev/null
@@ -0,0 +1,10 @@
+<?php
+// File created by maintenance/generateNormalizerDataMl.php
+return [
+       'ണ്‍' => 'ൺ',
+       'ന്‍' => 'ൻ',
+       'ര്‍' => 'ർ',
+       'ല്‍' => 'ൽ',
+       'ള്‍' => 'ൾ',
+       'ക്‍' => 'ൿ',
+];
index e364f1b..78bfa83 100644 (file)
@@ -2,8 +2,8 @@
 <!DOCTYPE supplementalData SYSTEM "../../common/dtd/ldmlSupplemental.dtd">
 <!--
 Copyright © 1991-2013 Unicode, Inc.
-CLDR data files are interpreted according to the LDML specification (http://unicode.org/reports/tr35/)
-For terms of use, see http://www.unicode.org/copyright.html
+CLDR data files are interpreted according to the LDML specification (https://unicode.org/reports/tr35/)
+For terms of use, see https://www.unicode.org/copyright.html
 -->
 <supplementalData>
     <version number="$Revision: 10807 $"/>
index f3ff0f8..eb17346 100644 (file)
        "sp-contributions-submit": "Cari",
        "whatlinkshere-title": "Kintal yang ada pranala ka \"$1\"",
        "whatlinkshere-page": "Kintal",
-       "nolinkshere": "Seng ada halaman yang taika par <strong>[[:$1]]</strong>.",
+       "nolinkshere-2": "Seng ada halaman yang taika par <strong>$1</strong>.",
        "isredirect": "kintal voor pengalihan",
        "istemplate": "tranklusi",
        "whatlinkshere-prev": "{{PLURAL:$1|sabalong $1}}",
index b08ae3a..4bbbe6f 100644 (file)
        "actionthrottled": "Buet geupeubataih",
        "actionthrottledtext": "Sibagoe saboh seunipat lawan-spam, droeneuh geupeubataih nibak neupeulaku buet nyoe le that gö lam watèë paneuk, ngön droeneuh ka leubèh nibak bataih.\nNeuci lom lam padum minèt.",
        "protectedpagetext": "Laman nyoe ka geupeulindông mangat bèk jeuet geuandam",
-       "viewsourcetext": "Droëneuh  jeuët neu’eu",
+       "viewsourcetext": "Droeneuh jeuet neueu ngön neusalén nè nibak mieng nyoe.",
        "viewyourtext": "Droëneuh meuidzin kalön ngön neucok nè andam droëneuh u laman nyoë",
        "protectedinterface": "Halaman nyoe na tèks muka keu muka keu peukakaih leumiëk ngön geupeulindông mangat bek jeuet jipeureuloh.\nKeu neuk tamah atawa ubah teujeumah keu ban dum wiki, neungui [https://translatewiki.net/ translatewiki.net], proyek lokalisasi MediaWiki.",
        "mycustomcssprotected": "Droëneuh hana hak neuandam halaman CSS nyoe.",
        "missingcommenttext": "Neupasoë beunalah di yup.",
        "summary-preview": "Eu neuringkaih neuandam:",
        "blockedtitle": "Ureueng ngui geutheun",
-       "blockedtext": "'''Nan ureuëng nguy atawa alamat IP Droëneuh  ka geutheun.'''\n\nGeutheun lé $1. Dalèh jih nakeuh ''$2''.\n\n* Geutheun yôh: $8\n* Neutheun maté tanggay bak: $6\n* Nyang geutheun: $7\n\nDroëneuh   jeuët neutanyong bak $1 atawa [[{{MediaWiki:Grouppage-sysop}}|nyang urôh nyang la’én]] keu peugah haba bhah nyoë.\n\nDroëneuh   h’an jeuët neunguy alat 'Kirém surat-e ureuëng nguy nyoë' keucuali ka neupasoë alamat surat-e nyang sah di [[Special:Preferences|Geunalak]] Droëneuh ngön Droëneuh ka geutheun keu nguy nyan.\n\nAlamat IP Droëneuh nakeuh $3, ngön ID neutheun nakeuh $5. Tulông peuseureuta salah saboh atawa ban duwa beurita nyoë bak tiëp teunanyöng nyang neupeugöt.",
+       "blockedtext": "<strong>Nan ureueng ngui atawa alamat IP Droeneuh ka geutheun.</strong>\n\nTeuneuheuen geupeugöt lé $1. \nAlasan nyang geubri nakeuh <em>$2</em>.\n\n* Phôn mula geutheun: $8\n* Maté tanggai teuneuheun: $6\n* Ureueng nyang geutheun: $7\n\nDroeneuh jeuet neutanyöng bak $1 atawa [[{{MediaWiki:Grouppage-sysop}}|ureueng urôih]] nyang la’én bhaih teuneuheun nyoe.\nDroeneuh h`an jeuet neungui alat \"{{int:emailuser}}\" keucuali meunyo alamat surat-e nyang sah na neupasoe bak [[Special:Preferences|Neuatô akun]] ngön Droeneuh hana geutheun keu neungui atra nyan.\nAlamat IP Droeneuh jinoe nakeuh $3, ngön ID teuneuheun nakeuh $5.\nNeutulông pasoe ban dum keutrangan di ateueh lam tiep teunanyöng nyang neupeugöt.",
        "autoblockedtext": "'''Nan ureuëng nguy atawa alamat IP Droëneuh  ka geutheun.'''\n\nGeutheun lé $1. Dalèh jih nakeuh ''$2''.\n\n* Geutheun yôh: $8\n* Neutheun maté tanggay bak: $6\n* Nyang geutheun: $7\n\nDroëneuh   jeuët neutanyong bak $1 atawa [[{{MediaWiki:Grouppage-sysop}}|nyang urôh nyang la’én]] keu peugah haba bhah nyoë.\n\nDroëneuh   h’an jeuët neunguy alat 'Kirém surat-e ureuëng nguy nyoë' keucuali ka neupasoë alamat surat-e nyang sah di [[Special:Preferences|Geunalak]] Droëneuh ngön Droëneuh ka geutheun keu nguy nyan.\n\nAlamat IP Droëneuh nakeuh $3, ngön ID neutheun nakeuh $5. Tulông peuseureuta salah saboh atawa ban duwa beurita nyoë bak tiëp teunanyöng nyang neupeugöt.",
        "blockednoreason": "hana dalèh nyang geubri",
        "whitelistedittext": "Droeneuh suwah $1 keu neuandam ôn.",
        "search-result-category-size": "{{PLURAL:$1|1 anggeeta|$1 anggeeta}} ({{PLURAL:$2|1 aneuk kawan|$2 aneuk kawan}}, {{PLURAL:$3|1 beureukaih|$3 beureukaih}})",
        "search-redirect": "(geupupinah nibak $1)",
        "search-section": "(bideuëng $1)",
+       "search-file-match": "(reumbang ngön asoe beureukaih)",
        "search-suggest": "Kadang meukeusud Droëneuh nakeuh: $1",
        "search-interwiki-caption": "Buët la’én",
        "search-interwiki-default": "Hasé nibak $1:",
        "recentchanges-label-plusminus": "Seunipat miëng geugantoë lé jeumeulah bita nyoë",
        "recentchanges-legend-heading": "<strong>Hareutoë:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (eu cit [[Special:NewPages|dapeuta laman barô]])",
-       "rcnotefrom": "Di yup nyoë nakeuh neuubah yôh <strong>$2</strong> (geupeudeuh trôh ‘an <strong>$1</strong> neuubah).",
+       "rcnotefrom": "Di yup nyoe nakeuh {{PLURAL:$5|neuubah}} yôh <strong>$3, $4</strong> (trôk 'an <strong>$1</strong> geupeudeuih).",
        "rclistfrom": "Peudeuih neuubah barô yôh $3 $2 kön",
        "rcshowhideminor": "$1 andam bacut",
        "rcshowhideminor-show": "Peuleumah",
        "rcshowhidebots-show": "Peuleumah",
        "rcshowhidebots-hide": "Peusom",
        "rcshowhideliu": "$1 ureuëng ngui tamöng",
+       "rcshowhideliu-show": "Peudeuih",
        "rcshowhideliu-hide": "Peusom",
        "rcshowhideanons": "$1 ureuëng ngui hana nan",
        "rcshowhideanons-show": "Peuleumah",
        "recentchangeslinked-feed": "Neuubah meuhubông",
        "recentchangeslinked-toolbox": "Neuubah teukaw'èt",
        "recentchangeslinked-title": "Neuubah nyang meukaw'èt ngön $1",
-       "recentchangeslinked-summary": "Neupasoe saboh nan mieng keu neueu neuubah bak mieng nyang mupawôt u atawa nibak mieng nyan. (Keu neueu anggèeta nibak saboh kawan, neupasoe Kawan:Nan kawan). Neuubah bak mieng bak [[Special:Watchlist|dapeuta keunalön]] teutuléh <strong>teubai</strong>.",
+       "recentchangeslinked-summary": "Neupasoe saboh nan mieng keu neueu neuubah bak mieng nyang mupawôt u atawa nibak mieng nyan. (Keu neueu anggèeta nibak saboh kawan, neupasoe {{ns:category}}:Nan kawan). Neuubah bak mieng nyang na bak [[Special:Watchlist|dapeuta keunalön]] teutuléh <strong>teubai</strong>.",
        "recentchangeslinked-page": "Nan miëng:",
        "recentchangeslinked-to": "Peuleumah neuubah nibak laman-laman nyang mupawôt ngön laman nyang geubri",
        "upload": "Peutamöng beureukaih",
        "sp-contributions-search": "Mita soë nyang tuléh",
        "sp-contributions-username": "Alamat IP atawa nan ureuëng ngui:",
        "sp-contributions-toponly": "Peuleumah geunantoe nyang baro mantong",
+       "sp-contributions-newonly": "Peudeuih pumeugöt mieng mantöng",
        "sp-contributions-submit": "Mita",
        "whatlinkshere": "Peunawôt balék",
        "whatlinkshere-title": "Laman nyang mupawôt u $1",
        "whatlinkshere-page": "Miëng:",
-       "linkshere": "Laman-laman nyoë meupawôt u '''[[:$1]]''':",
-       "nolinkshere": "Hana halaman nyang teukaw'et u '''[[:$1]]'''.",
+       "linkshere-2": "Laman-laman nyoë meupawôt u '''$1''':",
+       "nolinkshere-2": "Hana halaman nyang teukaw'et u '''$1'''.",
        "isredirect": "laman peuninah",
        "istemplate": "ngön seunaleuëk",
        "isimage": "peunawôt beureukaih",
        "tooltip-summary": "Pasoë éhtisa paneuk",
        "interlanguage-link-title": "$1 – $2",
        "simpleantispam-label": "Paréksa anti-spam.\n<strong>BÈK</strong> neupasoë!",
+       "pageinfo-title": "Keutrangan keu \"$1\"",
+       "pageinfo-watchers": "Jumeulah ureueng kalön mieng",
        "pageinfo-toolboxlink": "Keutrangan miëng",
        "previousdiff": "← Bida awai",
        "nextdiff": "Geunantoë lheuëh nyan →",
        "file-info-size": "$1 × $2 piksel, rayek beureukaih: $3, MIME jeunèh: $4",
+       "file-info-size-pages": "$1 × $2 piksel, seunipat beureukaih: $3, jeunèh MIME: $4, $5 {{PLURAL:$5|mieng}}",
        "file-nohires": "Hana resolusi nyang leubèh manyang.",
        "svg-long-desc": "Beureukah SVG, nominal $1 x $2 piksel, rayek beureukah: $3",
        "show-big-image": "Beureukaih aseuli",
        "confirm-unwatch-button": "Ka göt",
        "confirm-unwatch-top": "Sampôh laman nyoë nibak dapeuta keunalön droëneuh?",
        "imgmultipageprev": "← laman sigohlomjih",
+       "imgmultigo": "Jak!",
+       "imgmultigoto": "Jak u mieng $1",
        "autosumm-new": "Geupeugöt laman ngön asoë '$1'",
        "watchlisttools-view": "Peudeuh neuubah meukaw'èt",
        "watchlisttools-edit": "Peudeuh ngön andam dapeuta keunalön",
        "redirect-file": "Nan beureukaih",
        "fileduplicatesearch-submit": "Mita",
        "specialpages": "Miëng kusuih",
+       "specialpages-note-restricted": "* Laman kusuih biasa.\n* <span class=\"mw-specialpagerestricted\">Laman kusuih geutheun.</span>",
        "specialpages-group-maintenance": "Beuneuri thèë plara",
        "specialpages-group-other": "La'én-la'én",
        "specialpages-group-login": "Tamöng / dapeuta",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag}}]]: $2)",
        "logentry-delete-delete": "$1 {{GENDER:$2|geusampôh}} miëng $3",
        "logentry-move-move": "$1 {{GENDER:$2|geupinah}} mieng $3 u $4",
+       "logentry-move-move-noredirect": "$1 {{GENDER:$2|geupinah}} mieng $3 u $4 hana geubôh peuninah",
        "logentry-newusers-create": "$1 {{GENDER:$2|geupeugöt}} akun ureuëng ngui",
        "logentry-upload-upload": "$1 {{GENDER:$2|geupasoe}} $3",
        "searchsuggest-search": "Mita {{SITENAME}}",
index 264a16d..0cd04d9 100644 (file)
        "whatlinkshere": "Мы нэкӀубгъом къэзыщэрэ зэпыщэхэр",
        "whatlinkshere-title": "\"$1\"-м къэзыщэрэ нэкӀубгъохэр",
        "whatlinkshere-page": "НэкӀубгъо:",
-       "linkshere": "Мы нэкӀубгъомэ зэпыщэр мыщ къащэ <strong>[[:$1]]</strong>:",
+       "linkshere-2": "Мы нэкӀубгъомэ зэпыщэр мыщ къащэ <strong>$1</strong>:",
        "isredirect": "езгъэкӀокӀырэ нэкӀубгъо",
        "istemplate": "хэлъхьаныгъэ",
        "isimage": "файл зэпыщэ",
index ece84d8..2ab8104 100644 (file)
        "sp-contributions-toponly": "أظهر أعلى المراجعات فقط",
        "whatlinkshere-title": "الصفحات التي تصل إلى \"$1\"",
        "whatlinkshere-page": "الپاج:",
-       "linkshere": "الصفحات التالية تصل إلى '''[[:$1]]''':",
-       "nolinkshere": "لا توجد صفحات تصل إلى '''[[:$1]]'''.",
+       "linkshere-2": "الصفحات التالية تصل إلى '''$1''':",
+       "nolinkshere-2": "لا توجد صفحات تصل إلى '''$1'''.",
        "isredirect": "صفحة تحويل",
        "istemplate": "مضمن",
        "isimage": "وصلة ملف",
index 43c9a62..0c3c6a7 100644 (file)
        "whatlinkshere": "Skakels hierheen",
        "whatlinkshere-title": "Bladsye wat na \"$1\" skakel",
        "whatlinkshere-page": "Bladsy:",
-       "linkshere": "Die volgende bladsye skakel na '''[[:$1]]''':",
-       "nolinkshere": "Geen bladsye skakel na '''[[:$1]]'''.",
-       "nolinkshere-ns": "Geen bladsye skakel na '''[[:$1]]''' in die verkose naamruimte nie.",
+       "linkshere-2": "Die volgende bladsye skakel na '''$1''':",
+       "nolinkshere-2": "Geen bladsye skakel na '''$1'''.",
+       "nolinkshere-ns-2": "Geen bladsye skakel na '''$1''' in die verkose naamruimte nie.",
        "isredirect": "aanstuurblad",
        "istemplate": "insluiting",
        "isimage": "lêerskakel",
        "fileduplicatesearch-noresults": "Daar is nie 'n lêer met die naam \"$1\" nie.",
        "specialpages": "Spesiale bladsye",
        "specialpages-note-top": "Sleutel",
+       "specialpages-note-restricted": "* Normale spesiale bladsye.\n* <span class=\"mw-specialpagerestricted\">Spesiale bladsye met beperkte toegang.</span>\n* <span class=\"mw-specialpagecached\">Spesiale bladsye met gegewens uit die kas (kan verouderd wees).</span>",
        "specialpages-group-maintenance": "Onderhoud verslae",
        "specialpages-group-other": "Ander spesiale bladsye",
        "specialpages-group-login": "Meld aan / registreer",
index e008069..57fd482 100644 (file)
        "whatlinkshere": "masasiket katukuh uyniyay a kasabelih",
        "whatlinkshere-title": "masasiket tayza \"$1\" a kasabelih",
        "whatlinkshere-page": "Kasabelih:",
-       "linkshere": "isasaay a kasabelih masasiket tazuma tu <strong>[[:$1]]</strong>:",
-       "nolinkshere": "No pages link to <strong>[[:$1]]</strong>.",
-       "nolinkshere-ns": "mapili’ay a pangangananay a salaedan inayi’ kasabelih  masasiket tu [[:$1]].",
+       "linkshere-2": "isasaay a kasabelih masasiket tazuma tu <strong>$1</strong>:",
+       "nolinkshere-2": "No pages link to <strong>$1</strong>.",
+       "nolinkshere-ns-2": "mapili’ay a pangangananay a salaedan inayi’ kasabelih  masasiket tu $1.",
        "isredirect": "miliyaw patatuzu’",
        "istemplate": "palaculen tu kasabelih",
        "isimage": "tangan-tangan misiket",
index 9b570e5..4989c5d 100644 (file)
        "whatlinkshere": "Vegzat me këtu",
        "whatlinkshere-title": "Faqe që lidhen me \"$1\"",
        "whatlinkshere-page": "Faqja:",
-       "linkshere": "Faqet e mâposhtme lidhen në '''[[:$1]]''':",
+       "linkshere-2": "Faqet e mâposhtme lidhen në '''$1''':",
        "isredirect": "faqe përcjellëse",
        "istemplate": "përfshirë",
        "isimage": "vegëz në figurë",
index 65159b8..f9f475d 100644 (file)
        "whatlinkshere": "ወዲህ የሚያያዝ",
        "whatlinkshere-title": "ከ «$1» ጋር የሚያያዙ ገጾች",
        "whatlinkshere-page": "ለገጽ (አርዕስት)፦",
-       "linkshere": "የሚከተሉት ገጾች ወደ '''[[:$1]]''' ተያይዘዋል።",
-       "nolinkshere": "ወደ '''[[:$1]]''' የተያያዘ ገጽ የለም።",
-       "nolinkshere-ns": "ባመለከቱት ክፍለ-ዊኪ ወደ '''[[:$1]]''' የተያያዘ ገጽ የለም።",
+       "linkshere-2": "የሚከተሉት ገጾች ወደ '''$1''' ተያይዘዋል።",
+       "nolinkshere-2": "ወደ '''$1''' የተያያዘ ገጽ የለም።",
+       "nolinkshere-ns-2": "ባመለከቱት ክፍለ-ዊኪ ወደ '''$1''' የተያያዘ ገጽ የለም።",
        "isredirect": "መምሪያ መንገድ",
        "istemplate": "የተሰካ",
        "isimage": "የምስል ማያያዣ",
index 88ab47a..3e54a4a 100644 (file)
        "whatlinkshere": "Pachinas que enlazan con ista",
        "whatlinkshere-title": "Pachinas que tienen vinclos ta $1",
        "whatlinkshere-page": "Pachina:",
-       "linkshere": "As siguients pachinas tienen vinclos enta '''[[:$1]]''':",
-       "nolinkshere": "Garra pachina tiene vinclos ta '''[[:$1]]'''.",
-       "nolinkshere-ns": "Garra pachina d'o espacio de nombres trigato tiene vinclos ta '''[[:$1]]'''.",
+       "linkshere-2": "As siguients pachinas tienen vinclos enta '''$1''':",
+       "nolinkshere-2": "Garra pachina tiene vinclos ta '''$1'''.",
+       "nolinkshere-ns-2": "Garra pachina d'o espacio de nombres trigato tiene vinclos ta '''$1'''.",
        "isredirect": "pachina reendrezata",
        "istemplate": "incluyida",
        "isimage": "Vinclo ta un fichero",
        "fileduplicatesearch-result-n": "O fichero \"$1\" tiene {{PLURAL:$2|1 duplicau identico|$2 duplicaus identicos}}.",
        "fileduplicatesearch-noresults": "No s'ha trobau garra fichero con o nombre «$1».",
        "specialpages": "Pachinas especials",
+       "specialpages-note-restricted": "* Pachinas especials normals.\n* <strong class=\"mw-specialpagerestricted\">Pachinas especials restrinchitas.</strong>",
        "specialpages-group-maintenance": "Informes de mantenimiento",
        "specialpages-group-other": "Atras pachinas especials",
        "specialpages-group-login": "Inicio de sesión / rechistro",
index 84eaa79..e833c1b 100644 (file)
        "whatlinkshere": "Hwæt hæfþ hlencan hider",
        "whatlinkshere-title": "Trametas þā habbaþ hlencan tō \"$1\"",
        "whatlinkshere-page": "Tramet:",
-       "linkshere": "Þā folgiendan trametas habbaþ hlencan tō: '''[[:$1]]'''",
-       "nolinkshere": "Nǣnge trametas habbaþ hlencan tō '''[[:$1]]'''.",
+       "linkshere-2": "Þā folgiendan trametas habbaþ hlencan tō: '''$1'''",
+       "nolinkshere-2": "Nǣnge trametas habbaþ hlencan tō '''$1'''.",
        "isredirect": "edlǣdunge tramet",
        "istemplate": "bysene nytt",
        "isimage": "ymelan hlenca",
index 2958327..8382f17 100644 (file)
        "whatlinkshere": "एन्जां की जुड़तै",
        "whatlinkshere-title": "$1 सं॑ जुड़लऽ पन्ना",
        "whatlinkshere-page": "पन्ना:",
-       "linkshere": "नीचे के सब पन्ना '''[[:$1]]''' स॑ जुड़लऽ:",
-       "nolinkshere": "<strong>[[:$1]]</strong> स॑ कोय भी पन्ना नै जुड़लऽ छै।",
+       "linkshere-2": "नीचे के सब पन्ना '''$1''' स॑ जुड़लऽ:",
+       "nolinkshere-2": "<strong>$1</strong> स॑ कोय भी पन्ना नै जुड़लऽ छै।",
        "isredirect": "पुन: निर्दिष्ट पन्ना",
        "istemplate": "मिलाबऽ",
        "isimage": "फाइल लिंक",
index bb4c258..97b37ff 100644 (file)
        "botpasswords-existing": "كلمات مرور البوت الموجودة",
        "botpasswords-createnew": "إنشاء كلمة مرور جديدة للبوت",
        "botpasswords-editexisting": "تعديل كلمة مرور موجودة للبوت",
+       "botpasswords-label-needsreset": "(تحتاج كلمة المرور إلى إعادة الضبط)",
        "botpasswords-label-appid": "اسم البوت:",
        "botpasswords-label-create": "أنشأ",
        "botpasswords-label-update": "حدث",
        "botpasswords-restriction-failed": "قيود كلمة مرور البوت تمنع هذا الولوج.",
        "botpasswords-invalid-name": "اسم المستخدم الموفر لا يحتوي على فاصل كلمة سر البوت (\"$1\").",
        "botpasswords-not-exist": "المستخدم \"$1\" لا يمتلك كلمة سر بوت بالاسم \"$2\".",
+       "botpasswords-needs-reset": "يجب إعادة تعيين كلمة مرور البوت لاسم بوت \"$2\" {{GENDER:$1|المستخدم|المستخدم}}\".",
        "resetpass_forbidden": "كلمات السر لا يمكن تغييرها",
        "resetpass_forbidden-reason": "لا يمكن تغيير كلمة المرور: $1",
        "resetpass-no-info": "يجب أن تكون مسجل الدخول للوصول إلى هذه الصفحة مباشرة.",
        "subject-preview": "معاينة الموضوع:",
        "previewerrortext": "حدث خطأ أثناء محاولة معاينة تغييراتك.",
        "blockedtitle": "المستخدم ممنوع",
-       "blockedtext": "'''اسم المستخدم أو عنوان الأيبي الخاص بك تم منعه.'''\n\nقام بالمنع $1.\nسبب المنع هو: ''$2''.\n\n* بداية المنع: $8\n* انتهاء المنع: $6\n* الممنوع المقصود: $7\n\nيمكنك الاتصال ب$1 أو مع أحد [[{{MediaWiki:Grouppage-sysop}}|الإداريين]] للنقاش حول المنع.\nلا يمكنك استخدام خاصية 'مراسلة هذا المستخدم' إلا إذا كنت قد وضعت عنوان بريدي صحيح في [[Special:Preferences|تفضيلات حسابك]] ولم يتم منعك من استخدامها.\nعنوان الأيبي الخاص بك حاليا هو $3، ورقم المنع هو #$5.\nمن فضلك اذكر كل التفاصيل بالأعلى في أي استعلامات تقوم بها.",
-       "autoblockedtext": "مُنِع عنوان آيبيك تلقائيا لأن مستخدما آخرا منعه $1 استخدمه.\nالسبب المعطى هو التالي:\n\n:''$2''\n\n* بداية المنع: $8\n* انتهاء المنع: $6\n* الممنوع المقصود: $7\n\nيمكنك أن تتصل ب $1 أو أحد [[{{MediaWiki:Grouppage-sysop}}|الإداريين]] الآخرين لمناقشة المنع.\n\nلاحظ أنه لا يمكنك استخدام خاصية \"إرسال رسالة لهذا المستخدم\" إلا لو كان لديك عنوان بريد إلكتروني صحيح مسجل في [[Special:Preferences|تفضيلاتك]] ولم يتم منعك من استخدامه.\n\nعنوان آيبيك الحالي $3، ورقم المنع #$5.\nمن فضلك اذكر كل التفاصيل بالأعلى في أي استعلامات تقوم بها.",
+       "blockedtext": "'''اسم المستخدم أو عنوان الأيبي الخاص بك تم منعه.'''\n\nقام بالمنع $1.\nسبب المنع هو: ''$2''.\n\n* بداية المنع: $8\n* انتهاء المنع: $6\n* الممنوع المقصود: $7\n\nيمكنك الاتصال ب$1 أو أحد [[{{MediaWiki:Grouppage-sysop}}|الإداريين]] للنقاش حول المنع.\nلا يمكنك استخدام خاصية \"{{int:emailuser}}\" إلا إذا كنت قد وضعت عنوان بريدي صحيح في [[Special:Preferences|تفضيلات حسابك]] ولم يتم منعك من استخدامها.\nعنوان الأيبي الخاص بك حاليا هو $3، ورقم المنع هو #$5.\nمن فضلك اذكر كل التفاصيل بالأعلى في أي استعلامات تقوم بها.",
+       "autoblockedtext": "مُنِع عنوان آيبيك تلقائيا لأن مستخدما آخرا منعه $1 استخدمه.\nالسبب المعطى هو التالي:\n\n:<em>$2</em>\n\n* بداية المنع: $8\n* انتهاء المنع: $6\n* الممنوع المقصود: $7\n\nيمكنك أن تتصل ب $1 أو أحد [[{{MediaWiki:Grouppage-sysop}}|الإداريين]] الآخرين لمناقشة المنع.\n\nلاحظ أنه لا يمكنك استخدام خاصية \"إرسال رسالة لهذا المستخدم\" إلا لو كان لديك عنوان بريد إلكتروني صحيح مسجل في [[Special:Preferences|تفضيلاتك]] ولم يتم منعك من استخدامه.\n\nعنوان آيبيك الحالي $3، ورقم المنع #$5.\nمن فضلك اذكر كل التفاصيل بالأعلى في أي استعلامات تقوم بها.",
        "systemblockedtext": "اسم المستخدم أو عنوان الأيبي الخاص بك تم منعه تلقائيا بواسطة ميدياويكي.\nالسبب المعطى هو:\n\n:<em>$2</em>\n\n* بداية المنع: $8\n* نهاية المنع: $6\n* المقصود بالمنع: $7\n\nعنوان الأيبي الحالي الخاص بك هو $3.\nمن فضلك ضمن كل التفاصيل بالأعلى في أي استعلام تقوم به.",
        "blockednoreason": "لا سبب معطى",
        "whitelistedittext": "يجب عليك $1 لتتمكن من تعديل الصفحات.",
        "prefs-watchlist-edits": "عدد التعديلات التي تعرض في قائمة المراقبة:",
        "prefs-watchlist-edits-max": "العدد الأقصى: 1000",
        "prefs-watchlist-token": "مفتاح قائمة المراقبة:",
-       "prefs-watchlist-managetokens": "اÙ\84تحÙ\83Ù\85 Ø¨Ø§Ù\84تÙ\88Ù\83Ù\86ات",
+       "prefs-watchlist-managetokens": "إدارة Ø§Ù\84رÙ\85Ù\88ز",
        "prefs-misc": "متفرقات",
        "prefs-resetpass": "غير كلمة السر",
        "prefs-changeemail": "تغيير أو إزالة عنوان البريد الإلكتروني",
        "recentchangescount": "عدد التعديلات للعرض في أحدث التغييرات وتواريخ الصفحات، والسجلات، افتراضيا:",
        "prefs-help-recentchangescount": "العدد الأقصى: 1000",
        "prefs-help-watchlist-token2": "هذا هو المفتاح السري لتغذية الويب لقائمة مراقبتك.\nيمكن لأي شخص يعرفه أن يقرأ قائمة مراقبتك، ولذا لا تتشاركه مع أحد.\nإذا احتجت، [[Special:ResetTokens|يمكنك إعادة ضبطه]].",
-       "prefs-help-tokenmanagement": "أنت يمكنك رؤية وإعادة ضبط المفتاح السري لحسابك الذي يمكنه الوصول لتلقيم الويب لقائمة مراقبتك. أي شخص يعرف المفتاح سيمكنه قراءة قائمة مراقبتك، لذا فلا تشاركه.",
+       "prefs-help-tokenmanagement": "أنت يمكنك رؤية وإعادة ضبط المفتاح السري لحسابك الذي يمكنه الوصول لتلقيم الويب لقائمة مراقبتك، أي شخص يعرف المفتاح سيمكنه قراءة قائمة مراقبتك; لذا فلا تشاركه.",
        "savedprefs": "تم حفظ تفضيلاتك.",
        "savedrights": "حُفظت المجموعات الجديدة {{GENDER:$1|للمستخدم|للمستخدمة}} $1.",
        "timezonelegend": "المنطقة الزمنية:",
        "recentchangeslinked-feed": "تغييرات ذات علاقة",
        "recentchangeslinked-toolbox": "تغييرات ذات علاقة",
        "recentchangeslinked-title": "التغييرات المرتبطة بصفحة «$1»",
-       "recentchangeslinked-summary": "أدخل اسم صفحة لرؤية التغييرات في الصفحات الموصولة من أو إلى تلك الصفحة. (لرؤية أعضاء تصنيف، أدخل تصنيف:الاسم الخاص بالتصنيف). التغييرات في الصفحات في [[Special:Watchlist|قائمة مراقبتك]] <strong>عريضة</strong>.",
+       "recentchangeslinked-summary": "أدخل اسم صفحة لرؤية التغييرات في الصفحات الموصولة من أو إلى تلك الصفحة. (لرؤية أعضاء تصنيف، أدخل {{ns:category}}:الاسم الخاص بالتصنيف). التغييرات في الصفحات في [[Special:Watchlist|قائمة مراقبتك]] <strong>عريضة</strong>.",
        "recentchangeslinked-page": "اسم الصفحة:",
        "recentchangeslinked-to": "أظهر التغييرات للصفحات الموصولة للصفحة المعطاة عوضاً عن ذلك",
        "recentchanges-page-added-to-category": "[[:$1]] أضيفت إلى التصنيف",
        "protectedtitles-submit": "لعرض العناوين",
        "listusers": "قائمة الأعضاء",
        "listusers-editsonly": "اعرض المستخدمين الذين أجروا تعديلات فقط",
+       "listusers-temporarygroupsonly": "عرض المستخدمين في مجموعات المستخدمين المؤقتة فقط",
        "listusers-creationsort": "رتب حسب تاريخ الإنشاء",
        "listusers-desc": "رتب تنازليا",
        "usereditcount": "{{PLURAL:$1|لا تعديلات|تعديل واحد|تعديلان|$1 تعديلات|$1 تعديلًا|$1 تعديل}}",
        "apisandbox-dynamic-parameters-add-label": "أضف مُعاملا:",
        "apisandbox-dynamic-parameters-add-placeholder": "اسم المعامل",
        "apisandbox-dynamic-error-exists": "يوجد بالفعل معامل باسم \"$1\".",
+       "apisandbox-templated-parameter-reason": "يتم تقديم [[Special:ApiHelp/main#main/templatedparams|templated parameter]]  استنادا إلى {{PLURAL:$1|قيمة|قيم}} $2.",
        "apisandbox-deprecated-parameters": "معاملات مهملة",
        "apisandbox-fetch-token": "املأ التوكين تلقائيا",
        "apisandbox-add-multi": "إضافة",
        "whatlinkshere": "ماذا يصل هنا",
        "whatlinkshere-title": "الصفحات التي تصل إلى \"$1\"",
        "whatlinkshere-page": "الصفحة:",
-       "linkshere": "الصفحات التالية تصل إلى '''[[:$1]]''':",
-       "nolinkshere": "لا توجد صفحات تصل إلى '''[[:$1]]'''.",
-       "nolinkshere-ns": "لا تصل أي صفحة إلى '''[[:$1]]''' في النطاق المختار.",
+       "linkshere-2": "الصفحات التالية تصل إلى '''$1''':",
+       "nolinkshere-2": "لا توجد صفحات تصل إلى '''$1'''.",
+       "nolinkshere-ns-2": "لا تصل أي صفحة إلى '''$1''' في النطاق المختار.",
        "isredirect": "صفحة تحويل",
        "istemplate": "مضمن",
        "isimage": "وصلة ملف",
        "authmanager-authn-not-in-progress": "عملية التحقق ليست جارية أو بينات الجلسة تم فقدها. من فضلك ابدأ مرة ثانية من البداية.",
        "authmanager-authn-no-primary": "الاعتماد الموفر لم يمكن التحقق منه.",
        "authmanager-authn-no-local-user": "الاعتماد الموفر غير مرتبط بأي مستخدم على هذه الويكي.",
-       "authmanager-authn-no-local-user-link": "الاعتمادات الموفرة صحيحة لكن غير مرتبطة بأي مستخدم على هذه الويكي. سجل الدخول باستخدام طريقة أخرى، أو أنشيء مستخدما جديدا، وستمتلك الاختيار لوصل اعتماداتك السابقة لذلك الحساب.",
+       "authmanager-authn-no-local-user-link": "الاعتمادات الموفرة صحيحة لكن غير مرتبطة بأي مستخدم على هذه الويكي. سجل الدخول باستخدام طريقة أخرى، أو أنشئ حسابًا جديدًا، وستمتلك الاختيار لوصل اعتماداتك السابقة لذلك الحساب.",
        "authmanager-authn-autocreate-failed": "الإنشاء التلقائي لحساب محلي فشل: $1",
        "authmanager-change-not-supported": "الاعتمادات الموفرة لم يمكن تغييرها، حيث أن لا شيء سيستخدمها.",
        "authmanager-create-disabled": "إنشاء الحسابات معطل.",
        "pagedata-title": "بيانات الصفحة",
        "pagedata-text": "هذه الصفحة توفر واجهة بيانات للصفحات. من فضلك وفر عنوان الصفحة في المسار، باستخدام صيغة الصفحات الفرعية.\n* تفاوض المحتوى يطبق بناء على الAccept header الخاص بعميلك. هذا يعني أن بيانات الصفحة سيتم توفيرها بالصيغة المفضلة لعميلك.",
        "pagedata-not-acceptable": "لم يتم العثور على هيئة مطابقة. أنماط MIME المدعومة: $1",
-       "pagedata-bad-title": "عنوان خاطئ: $1."
+       "pagedata-bad-title": "عنوان خاطئ: $1.",
+       "unregistered-user-config": "لأسباب تتعلق بالأمان; لا يمكن تحميل الصفحات الفرعية JavaScript وCSS وJSON للمستخدمين غير المسجلين.",
+       "passwordpolicies": "سياسات كلمة المرور",
+       "passwordpolicies-summary": "هذه قائمة بسياسات كلمة المرور الفعالة لمجموعات المستخدمين المعرفة في هذا الويكي.",
+       "passwordpolicies-group": "المجموعة",
+       "passwordpolicies-policies": "السياسات",
+       "passwordpolicies-policy-minimalpasswordlength": "يجب أن يكون طول كلمة المرور على الأقل $1 {{PLURAL:$1|حرف|أحرف}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "يجب أن يكون طول كلمة المرور على الأقل $1 {{PLURAL:$1|حرف|أحرف}} لتتمكن من تسجيل الدخول",
+       "passwordpolicies-policy-passwordcannotmatchusername": "لا يمكن أن تكون كلمة المرور هي نفس اسم المستخدم",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "لا يمكن أن تتطابق كلمة المرور مع كلمات المرور المدرجة على القائمة السوداء تحديدا",
+       "passwordpolicies-policy-maximalpasswordlength": "يجب أن يكون طول كلمة المرور أقل من $1 {{PLURAL:$1|حرف|أحرف}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "لا يمكن أن تكون كلمة المرور {{PLURAL:$1|كلمة المرور الشائعة|في قائمة كلمات المرور الشائعة الـ$1}}"
 }
index 1997c9a..15b1e3e 100644 (file)
        "whatlinkshere": "ܡܐ ܐܣܪ ܠܗܪܟܐ",
        "whatlinkshere-title": "ܦܐܬܬ̈ܐ ܕܐܣܝܪܝܢ ܥܡ \"$1\"",
        "whatlinkshere-page": "ܦܐܬܐ:",
-       "linkshere": "ܦܐܬܬ̈ܐ ܗܠܝܢ ܐܣܝܪܝܢ ܥܡ '''[[:$1]]''':",
-       "nolinkshere": "ܠܝܬ ܦܐܬܬ̈ܐ ܐܣܪܝܢ ܥܡ '''[[:$1]]'''.",
-       "nolinkshere-ns": "ܠܝܬ ܦܐܬܬ̈ܐ ܐܣܪܝܢ ܥܡ '''[[:$1]]''' ܒܚܩܠܐ ܓܒܝܐ.",
+       "linkshere-2": "ܦܐܬܬ̈ܐ ܗܠܝܢ ܐܣܝܪܝܢ ܥܡ '''$1''':",
+       "nolinkshere-2": "ܠܝܬ ܦܐܬܬ̈ܐ ܐܣܪܝܢ ܥܡ '''$1'''.",
+       "nolinkshere-ns-2": "ܠܝܬ ܦܐܬܬ̈ܐ ܐܣܪܝܢ ܥܡ '''$1''' ܒܚܩܠܐ ܓܒܝܐ.",
        "isredirect": "ܦܐܬܐ ܕܨܘܝܒܐ",
        "istemplate": "ܚܒܝܫܬܐ",
        "isimage": "ܐܣܘܪܐ ܕܠܦܦܐ",
        "fileduplicatesearch-submit": "ܒܨܝ",
        "fileduplicatesearch-info": "$1 × $2 ܦܩܣܠ<br /> ܥܓܪܐ ܕܠܦܦܐ: $3<br /> ܐܕܫܐ ܕ MIME: $4",
        "specialpages": "ܦܐܬܬ̈ܐ ܕ̈ܝܠܢܝܬܐ",
+       "specialpages-note-restricted": "* ܦܐܬܬ̈ܐ ܕ̈ܝܠܢܝܬܐ ܥܝܕ̈ܝܬܐ.\n* <span class=\"mw-specialpagerestricted\">ܦܐܬܬ̈ܐ ܕ̈ܝܠܢܝܬܐ ܕܩܝܘܡ̈ܐ.</span>",
        "specialpages-group-maintenance": "ܬܫܪܪ̈ܐ ܕܚܕܬܘܬܐ",
        "specialpages-group-other": "ܦܐܬܬ̈ܐ ܕ̈ܝܠܢܝܬܐ ܐܚܪ̈ܢܝܬܐ",
        "specialpages-group-login": "ܥܘܠ / ܒܪܝ ܚܘܫܒܢܐ",
index 41d8dce..1ca78c1 100644 (file)
        "whatlinkshere": "Lasulu faw püle",
        "whatlinkshere-title": "Wülngiñ nülkükawlelu \"$1\"",
        "whatlinkshere-page": "Pakina:",
-       "linkshere": "Tüfachi wülngiñ nülkükawley '''[[:$1]]''':",
-       "nolinkshere": "Chem wülngiñ no rume nülkükawlelu '''[[:$1]]'''.",
+       "linkshere-2": "Tüfachi wülngiñ nülkükawley '''$1''':",
+       "nolinkshere-2": "Chem wülngiñ no rume nülkükawlelu '''$1'''.",
        "isredirect": "wüñongünen wülngiñ",
        "istemplate": "yomtukudungu",
        "isimage": "Adentun lasun",
index df8fa58..0367678 100644 (file)
        "whatlinkshere": "شنوّ يوصّل ل هنا",
        "whatlinkshere-title": "الباجات اللي تقين في \"$1\"",
        "whatlinkshere-page": "الباجه:",
-       "linkshere": "هاذ الباجات يوصلو إلى '''[[:$1]]''':",
-       "nolinkshere": "ما كانش  باجه فيها وصيله ل'''[[:$1]]'''.",
+       "linkshere-2": "هاذ الباجات يوصلو إلى '''$1''':",
+       "nolinkshere-2": "ما كانش  باجه فيها وصيله ل'''$1'''.",
        "isredirect": "باجت تحويل",
        "istemplate": "تضمين",
        "isimage": "وصيلة ملف",
index 6e82115..c412556 100644 (file)
        "hidetoc": "Ḫebbi",
        "collapsible-collapse": "twi",
        "collapsible-expand": "wsseĝ",
+       "confirmable-no": "لا",
        "thisisdeleted": "nĊof onstarjaa $1?",
        "viewdeleted": "nchof $1?",
        "restorelink": "{{PLURAL:$1|wahd taadil tmsh|$1 taadilat tmshat}}",
        "whatlinkshere": "Ṣefḫaṫ mlaqyin",
        "whatlinkshere-title": "Ṣ-Ṣefḫaṫ li mlaqyin mĝa \"$1\"",
        "whatlinkshere-page": "ṣfḫa:",
-       "linkshere": "Had ṣ-ṣefḫaṫ kayddiw le '''[[:$1]]''':",
-       "nolinkshere": "ḫṫa ċi ṣfḫa ma ka-twṣṣel l-'''[[:$1]]'''.",
-       "nolinkshere-ns": "ḫṫṫĝ ṣfḫa ma ka-twṣṣal l-'''[[:$1]]''' f-nnitaq lli ĥṫariṫi",
+       "linkshere-2": "Had ṣ-ṣefḫaṫ kayddiw le '''$1''':",
+       "nolinkshere-2": "ḫṫa ċi ṣfḫa ma ka-twṣṣel l-'''$1'''.",
+       "nolinkshere-ns-2": "ḫṫṫĝ ṣfḫa ma ka-twṣṣal l-'''$1''' f-nnitaq lli ĥṫariṫi",
        "isredirect": "Ṫeḫwil ṣ-ṣefḫa",
        "istemplate": "Daĥel",
        "isimage": "wṣlṫ l-milef",
index 841b6e8..c392c6a 100644 (file)
        "whatlinkshere": "ايه بيوصل هنا",
        "whatlinkshere-title": "الصفحات اللى بتوصل لـ \"$1\"",
        "whatlinkshere-page": "الصفحة:",
-       "linkshere": "الصفحات دى فيها وصله ل '''[[:$1]]''':",
-       "nolinkshere": "مافيش صفحات بتوصل ل '''[[:$1]]'''.",
-       "nolinkshere-ns": "مافيش صفحات بتوصل لـ '''[[:$1]]''' فى النطاق اللى انت اختارته.",
+       "linkshere-2": "الصفحات دى فيها وصله ل '''$1''':",
+       "nolinkshere-2": "مافيش صفحات بتوصل ل '''$1'''.",
+       "nolinkshere-ns-2": "مافيش صفحات بتوصل لـ '''$1''' فى النطاق اللى انت اختارته.",
        "isredirect": "صفحة تحويل",
        "istemplate": "متضمن",
        "isimage": "وصلة ملف",
        "fileduplicatesearch-result-1": "الملف \"$1\" ما لهو ش تكرار متطابق.",
        "fileduplicatesearch-result-n": "الملف \"$1\" فيه {{PLURAL:$2|1 تكرار متطابق|$2 تكرار متطابق}}.",
        "specialpages": "صفح مخصوصه",
+       "specialpages-note-restricted": "* صفحات خاصة عادية.\n* <strong class=\"mw-specialpagerestricted\">صفحات خاصة للناس اللى مسموح لهم.</strong>",
        "specialpages-group-maintenance": "تقارير الصيانة",
        "specialpages-group-other": "صفحات خاصه تا نيه",
        "specialpages-group-login": "ادخل / سجل",
index 81b6d0f..fb329e0 100644 (file)
@@ -25,7 +25,7 @@
                ]
        },
        "tog-underline": "সংযোগসমূহ অধোৰেখিত কৰক:",
-       "tog-hideminor": "সামà§\8dপà§\8dৰতিà¦\95 সাল-সলনিত অগুৰুত্বপূৰ্ণ সম্পাদনা নেদেখুৱাব",
+       "tog-hideminor": "শà§\87হতà§\80য়া সাল-সলনিত অগুৰুত্বপূৰ্ণ সম্পাদনা নেদেখুৱাব",
        "tog-hidepatrolled": "সাম্প্ৰতিক সাল-সলনিত তহলদাৰী সম্পাদনা নেদেখুৱাব",
        "tog-newpageshidepatrolled": "নতুন পৃষ্ঠা তালিকাত তহলদাৰী পৃষ্ঠাসমূহ নেদেখুৱাব",
        "tog-hidecategorization": "পৃষ্ঠাবোৰৰ শ্ৰেণীকৰণ লুকুৱাওক",
        "undo-failure": "এই সম্পাদনা মধ্যৱৰ্তী সম্পাদনাসমূহৰ দ্বন্দৰ কাৰণে পূৰ্ববৎ কৰা নহ'ব ।",
        "undo-norev": "এই সম্পাদনাটো ৰদ কৰিব নোৱাৰি, কাৰণ এইটো আৰু নাই বা ইয়াক বিলোপ কৰা হ'ল।",
        "undo-nochange": "সম্পাদনাটো ইতিমধ্যেই বাতিল কৰা হৈছে।",
-       "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|আলোচনা]]) সম্পাদিত $1 সংশোধনটি বাতিল কৰক",
+       "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|আলোচনা]])-ই কৰা $1 নম্বৰ সম্পাদনাটো বাতিল কৰা হৈছে",
        "undo-summary-username-hidden": "এজন গোপন ব্যৱহাৰকাৰীয়ে কৰা $1 সংশোধন বাতিল কৰক",
        "cantcreateaccount-text": "আই পি ঠিকনা ('''$1''')ৰ পৰা একাউণ্ট সৃষ্টিত [[User:$3|$3]]’য়ে বাধা প্ৰদান কৰিছে ।\n\n$3 য়ে আগবঢ়োৱা ইয়াৰ কাৰণ হৈছে ''$2''",
        "cantcreateaccount-range-text": "[[User:$3|$3]]য়ে <strong>$1</strong> পৰিসীমাৰ আই পি ঠিকনাৰ পৰা একাউণ্ট সৃষ্টি বাৰণ কৰিছে যাৰ ভিতৰত আপোনাৰ আই ই ঠিকনাও (<strong>$4</strong>) আছে।\n\n $3য়ে <em>$2</em> বুলি কাৰণ দৰ্শাইছে",
        "recentchanges-legend-plusminus": "(''±১২৩'')",
        "rcfilters-legend-heading": "<strong>সংক্ষিপ্ত ৰূপৰ তালিকা:</strong>",
        "rcfilters-other-review-tools": "আন পুনৰীক্ষণ সঁজুলি",
+       "rcfilters-quickfilters": "সঞ্চিত পৰিস্ৰাৱক",
+       "rcfilters-quickfilters-placeholder-title": "এতিয়ালৈকে কোনো ছেকনী সাঁচি থোৱা নাই",
+       "rcfilters-quickfilters-placeholder-description": "আপোনাৰ ছেকনীৰ ছেটিংছ সাঁচি থ'বলৈ আৰু পাছত সেয়া ব্যৱহাৰ কৰিবলৈ তলত থকা সক্ৰিয় পৰিস্ৰাৱক ক্ষেত্ৰৰ বুক্‌মাৰ্ক চিহ্নটো ক্লিক কৰক।",
+       "rcfilters-savedqueries-defaultlabel": "সঞ্চিত পৰিস্ৰাৱক",
+       "rcfilters-show-new-changes": "নতুন সালসলনিবোৰ চাওক",
+       "rcfilters-search-placeholder": "পৰিৱৰ্তনসমূহ ছেকক (ছেকনীৰ নামৰ বাবে মেন্যু বা সন্ধান ব্যৱহাৰ কৰক)",
+       "rcfilters-highlightbutton-title": "ফলাফলসমূহ উজ্জ্বল কৰক",
+       "rcfilters-filter-editsbyself-label": "আপুনি কৰা সালসলনিসমূহ",
+       "rcfilters-filter-editsbyself-description": "আপোনাৰ নিজৰ অৱদানসমূহ।",
+       "rcfilters-filter-editsbyother-label": "আনে কৰা সালসলনিসমূহ",
+       "rcfilters-filter-editsbyother-description": "আপুনি কৰাখিনিৰ বাহিৰে আন সকলো সালসলনি।",
+       "rcfilters-filtergroup-userExpLevel": "সদস্য পঞ্জীয়ন আৰু অভিজ্ঞতা",
+       "rcfilters-filter-user-experience-level-registered-label": "পঞ্জীয়নভুক্ত",
+       "rcfilters-filter-user-experience-level-registered-description": "প্ৰৱেশ কৰা সম্পাদকসকল।",
+       "rcfilters-filter-user-experience-level-unregistered-description": "প্ৰৱেশ নকৰা সম্পাদকসকল।",
+       "rcfilters-filter-user-experience-level-newcomer-label": "নবাগতসকল",
+       "rcfilters-filter-user-experience-level-newcomer-description": "১টাতকৈ কম সম্পাদনা কৰা বা ৪ দিনতকৈ কম সময় সক্ৰিয় থকা পঞ্জীয়নভুক্ত সম্পাদকসকল।",
+       "rcfilters-filter-user-experience-level-learner-label": "ন-শিকাৰুসকল",
+       "rcfilters-filter-user-experience-level-learner-description": "পঞ্জীয়নভুক্ত সম্পাদকসকল যাৰ অভিজ্ঞতাৰ স্তৰ \"নবাগত\" আৰু \"অভিজ্ঞ সদস্য\"ৰ মাজত।",
+       "rcfilters-filter-user-experience-level-experienced-label": "অভিজ্ঞ সদস্যসকল",
+       "rcfilters-filter-user-experience-level-experienced-description": "৫০০তকৈ বেছি সম্পাদনা কৰা আৰু ৩০ দিনতকৈ বেছি সময় সক্ৰিয় থকা পঞ্জীয়নভুক্ত সম্পাদকসকল।",
+       "rcfilters-filter-humans-label": "মানুহ (ব'ট নহয়)",
+       "rcfilters-filter-pageedits-label": "পৃষ্ঠা সম্পাদনা",
+       "rcfilters-filter-newpages-label": "পৃষ্ঠা সৃষ্টি",
+       "rcfilters-filter-logactions-label": "নথিভুক্ত কাম",
+       "rcfilters-liveupdates-button": "পোনপটীয়া উন্নীতকৰণ",
        "rcnotefrom": "<strong>$2</strong>ৰ পৰা হোৱা পৰিৱৰ্তনসমূহ (সৰ্বোচ্চ <strong>$1টা</strong> দেখুৱা হৈছে)।",
        "rclistfrom": "$3 $2ৰ পৰা নতুন সালসলনি দেখুৱাওক",
        "rcshowhideminor": "$1 -সংখ্যক নগণ্য সম্পাদনা",
        "recentchangeslinked-feed": "প্ৰাসংগিক সালসলনিসমূহ",
        "recentchangeslinked-toolbox": "প্ৰাসংগিক সালসলনিসমূহ",
        "recentchangeslinked-title": "\"$1\"ৰ লগত জড়িত সাল-সলনি",
-       "recentchangeslinked-summary": "à¦\8fà¦\96ন à¦¨à¦¿à§°à§\8dদিষà§\8dà¦\9f à¦ªà§\83ষà§\8dঠাৰ à¦²à¦\97ত à¦¸à¦\82যà§\81à¦\95à§\8dত à¦ªà§\83ষà§\8dঠাসমà§\82হৰ( à¦¬à¦¾ à¦\8fà¦\9fা à¦¨à¦¿à§°à§\8dদিষà§\8dà¦\9f à¦¶à§\8dৰà§\87ণà§\80ৰ à¦¸à¦¦à¦¸à§\8dযসমà§\82হৰ) à¦¶à§\87হতà§\80য়া à¦¸à¦¾à¦²à¦¸à¦²à¦¨à¦¿à§° à¦¤à¦¾à¦²à¦¿à¦\95া à¦¤à¦²à¦¤ à¦¦à¦¿à¦¯à¦¼à¦¾ à¦¹à§\88à¦\9bà§\87 à¥¤\n[[Special:Watchlist|à¦\86পà§\81নি à¦\9aà¦\95à§\81 à§°à¦\96া à¦ªà§\83ষà§\8dঠাসমà§\82হৰ à¦¤à¦¾à¦²à¦¿à¦\95া]] à¦¤ à¦¥à¦\95া à¦ªà§\83ষà§\8dঠাসমà§\82হ '''à¦\97াঢ়''' à¦¦à§\87à¦\96া à¦ªà¦¾à¦¬ ।",
+       "recentchangeslinked-summary": "à¦\95à§\8bনà§\8b à¦ªà§\83ষà§\8dঠালà§\88 à¦¬à¦¾ à¦\87য়াৰ à¦ªà§°à¦¾ à¦¸à¦\82যà§\81à¦\95à§\8dত à¦ªà§\83ষà§\8dঠাবà§\8bৰৰ à¦¸à¦¾à¦²à¦¸à¦²à¦¨à¦¿ à¦\9aাবলà§\88 à¦ªà§\83ষà§\8dঠাà¦\9fà§\8bৰ à¦¨à¦¾à¦® à¦²à¦¿à¦\96à¦\95। (à¦\95à§\8bনà§\8b à¦¶à§\8dৰà§\87ণà§\80ৰ à¦¨à¦¾à¦®à¦¬à§\8bৰ à¦\9aাবলà§\88 {{ns:category}}:শà§\8dৰà§\87ণà§\80à¦\9fà§\8bৰ à¦¨à¦¾à¦®) à¦²à¦¿à¦\96à¦\95। [[Special:Watchlist|à¦\86পà§\8bনাৰ à¦²à¦\95à§\8dষà§\8dয-তালিà¦\95া]]ৰ à¦ªà§\83ষà§\8dঠাবà§\8bৰৰ à¦ªà§°à¦¿à§±à§°à§\8dতন <strong>à¦\97াঢ়</strong> à¦\86à¦\96ৰত à¦¦à§\87à¦\96া à¦ªà¦¾à¦¬।",
        "recentchangeslinked-page": "পৃষ্ঠাৰ নাম:",
        "recentchangeslinked-to": "অন্যথা নিৰ্দিষ্ট পৃষ্ঠাৰ লগত সংযুক্ত পৃষ্ঠাসমূহৰ সালসলনি দেখুৱাওক",
        "recentchanges-page-added-to-category": "শ্ৰেণীত [[:$1]] যোগ কৰা হৈছে",
        "whatlinkshere": "ইয়ালৈ থকা সংযোগসমূহ",
        "whatlinkshere-title": "\"$1\"লৈ সংযোজিত পৃষ্ঠাসমূহ",
        "whatlinkshere-page": "পৃষ্ঠা:",
-       "linkshere": "এই পৃষ্ঠাটো '''[[:$1]]''' ৰ লগত সংযোজিত:",
-       "nolinkshere": "'''[[:$1]]''' ৰ লগত কোনো পৃষ্ঠা সংযোজিত নহয়।",
-       "nolinkshere-ns": "নিৰ্বাচিত নামস্থানৰ কোনো পৃষ্ঠাৰ পৰা [[:$1]]লৈ সংযোগ নাই ।",
+       "linkshere-2": "এই পৃষ্ঠাটো '''$1''' ৰ লগত সংযোজিত:",
+       "nolinkshere-2": "'''$1''' ৰ লগত কোনো পৃষ্ঠা সংযোজিত নহয়।",
+       "nolinkshere-ns-2": "নিৰ্বাচিত নামস্থানৰ কোনো পৃষ্ঠাৰ পৰা $1লৈ সংযোগ নাই ।",
        "isredirect": "পুনঃনিৰ্দেশনা পৃষ্ঠা",
        "istemplate": "অন্তৰ্ভুক্ত কৰক",
        "isimage": "নথিৰ সংযোগ",
        "fileduplicatesearch-noresults": "কোনো \"$1\" নামৰ নথিৰ সন্ধান পোৱা নগ’ল ।",
        "specialpages": "বিশেষ পৃষ্ঠাসমূহ",
        "specialpages-note-top": "ব্যাখ্যা",
+       "specialpages-note-restricted": "* সাধাৰণ বিশেষ পৃষ্ঠাসমূহ।\n* <span class=\"mw-specialpagerestricted\">সীমাবদ্ধ বিশেষ পৃষ্ঠাসমূহ।</span>",
        "specialpages-group-maintenance": "তত্বাৱধানৰ কাৰ্যবিৱৰণীসমূহ",
        "specialpages-group-other": "অন্যান্য বিশেষ পৃষ্ঠাসমূহ",
        "specialpages-group-login": "প্ৰৱেশ/একাউণ্ট সৃষ্টি কৰক",
index b688b16..1a15227 100644 (file)
        "botpasswords-existing": "Contraseñes de bots esistentes",
        "botpasswords-createnew": "Crear una contraseña nueva de bot",
        "botpasswords-editexisting": "Editar una contraseña de bot esistiente",
+       "botpasswords-label-needsreset": "(la contraseña tien de reaniciase)",
        "botpasswords-label-appid": "Nome del bot:",
        "botpasswords-label-create": "Crear",
        "botpasswords-label-update": "Anovar",
        "botpasswords-restriction-failed": "Hai torgues de contraseña de bot que torgaron esti aniciu de sesión.",
        "botpasswords-invalid-name": "El nome d'usuariu especificáu nun contien el separador de contraseña de bot («$1»).",
        "botpasswords-not-exist": "L'usuariu «$1» nun tien una contraseña de bot llamada «$2».",
+       "botpasswords-needs-reset": "Tien de reniciase la contraseña del robot «$2», propiedá {{GENDER:$1|del usuariu|de la usuaria}} «$1».",
        "resetpass_forbidden": "Nun puen camudase les contraseñes",
        "resetpass_forbidden-reason": "Les contraseñes nun pueden camudase: $1",
        "resetpass-no-info": "Tienes d'aniciar sesión pa entrar direutamente a esta páxina.",
        "subject-preview": "Vista previa del asuntu:",
        "previewerrortext": "Hebo un error al intentar entever los cambios.",
        "blockedtitle": "L'usuariu ta bloquiáu",
-       "blockedtext": "'''El to nome d'usuariu o direición IP ta bloquiáu.'''\n\nEl bloquéu fexolu $1.\nEl motivu conseñáu ye ''$2''.\n\n* Principiu del bloquéu: $8\n* Caducidá del bloquéu: $6\n* Usuariu a bloquiar: $7\n\nPues ponete'n contautu con $1 o con otru [[{{MediaWiki:Grouppage-sysop}}|alministrador]] p'aldericar sobre'l bloquéu.\nNun pues usar la función 'manda-y un corréu electrónicu a esti usuariu' a nun ser que tea especificada una direición de\ncorréu electrónicu válida nes tos [[Special:Preferences|preferencies de cuenta]] y que nun tengas torgao usala.\nLa to direición IP actual ye $3, y la ID del bloquéu ye #$5.\nPor favor, incluye tolos detalles anteriores nes consultes que faigas.",
-       "autoblockedtext": "La to direición IP bloquióse automáticamente porque usóla otru usuariu que foi bloquiáu por $1.\nEl motivu conseñáu ye:\n\n:''$2''\n\n* Principiu del bloquéu: $8\n* Caducidá del bloquéu: $6\n* Usuariu a bloquiar: $7\n\nPues ponete'n contautu con $1 o con otru de los [[{{MediaWiki:Grouppage-sysop}}|alministradores]] p'aldericar sobre'l bloquéu.\n\nTen en cuenta que nun pues usar la función «manda-y un corréu electrónicu a esti usuariu» a nun ser que tengas rexistrada una direición de corréu electrónicu válida nes [[Special:Preferences|preferencies d'usuariu]] y que nun tengas torgao usala.\n\nLa to direición IP actual ye $3, y la ID del bloquéu ye #$5.\nPor favor, incluye tolos detalles anteriores nes consultes que faigas.",
+       "blockedtext": "<strong>El to nome d'usuariu o direición IP ta bloquiáu.</strong>\n\nEl bloquéu fexolu $1.\nEl motivu conseñáu ye <em>$2</em>.\n\n* Principiu del bloquéu: $8\n* Caducidá del bloquéu: $6\n* Usuariu a bloquiar: $7\n\nPuedes comunicate con $1 o con otru [[{{MediaWiki:Grouppage-sysop}}|alministrador]] p'aldericar sobre'l bloquéu.\nNun puedes usar la función «{{int:emailuser}}» a nun ser que tea especificada una direición de corréu electrónicu válida nes tos [[Special:Preferences|preferencies de cuenta]] y que nun tengas torgao usala.\nLa to direición IP actual ye $3, y la ID del bloquéu ye #$5.\nPor favor, incluye tolos detalles anteriores nes consultes que faigas.",
+       "autoblockedtext": "La to direición IP bloquióse automáticamente porque usóla otru usuariu que foi bloquiáu por $1.\nEl motivu conseñáu ye:\n\n:<em>$2</em>\n\n* Principiu del bloquéu: $8\n* Caducidá del bloquéu: $6\n* Usuariu a bloquiar: $7\n\nPues ponete'n contautu con $1 o con otru de los [[{{MediaWiki:Grouppage-sysop}}|alministradores]] p'aldericar sobre'l bloquéu.\n\nTen en cuenta que nun pues usar la función «{{int:emailuser}}» a nun ser que tengas rexistrada una direición de corréu electrónicu válida nes [[Special:Preferences|preferencies d'usuariu]] y que nun tengas torgao usala.\n\nLa to direición IP actual ye $3, y la ID del bloquéu ye #$5.\nPor favor, incluye tolos detalles anteriores nes consultes que faigas.",
        "systemblockedtext": "El to nome d'usuariu o dirección IP bloquióse automáticamente pol software MediaWiki.\nEl motivu dau ye:\n\n:<em>$2</em>\n\n* Entamu del bloquéu: $8\n* Caducidá de bloquéu: $6\n* Destinatariu del bloquéu: $7\n\nLa to dirección IP actual ye $3.\nPor favor, incluye tolos anteriores en cualquier consulta que faigas.",
        "blockednoreason": "nun se dio nengún motivu",
        "whitelistedittext": "Tienes d'$1 pa editar páxines.",
        "recentchangeslinked-feed": "Cambios rellacionaos",
        "recentchangeslinked-toolbox": "Cambios rellacionaos",
        "recentchangeslinked-title": "Cambios rellacionaos con \"$1\"",
-       "recentchangeslinked-summary": "Esscribe'l nome d'una páxina pa ver los cambios nes páxines enllazaes a o dende esa páxina. (Pa ver los miembros d'una categoría, escribe Categoría:Nome de la categoría). Los cambios nes páxines de [[Special:Watchlist|la to llista de siguimientu]] tán en <strong>negrina</strong>.",
+       "recentchangeslinked-summary": "Esscribe'l nome d'una páxina pa ver los cambios nes páxines enllazaes a o dende esa páxina. (Pa ver los miembros d'una categoría, escribe {{ns:category}}:Nome de la categoría). Los cambios nes páxines de [[Special:Watchlist|la to llista de siguimientu]] tán en <strong>negrina</strong>.",
        "recentchangeslinked-page": "Nome de la páxina:",
        "recentchangeslinked-to": "Amosar los cambios de les páxines qu'enllacen en cuenta de los de la páxina dada",
        "recentchanges-page-added-to-category": "[[:$1]] amestóse a la categoría",
        "apisandbox-dynamic-parameters-add-label": "Amestar parámetru:",
        "apisandbox-dynamic-parameters-add-placeholder": "Nome del parámetru",
        "apisandbox-dynamic-error-exists": "Yá existe un parámetru llamáu «$1».",
+       "apisandbox-templated-parameter-reason": "Esti [[Special:ApiHelp/main#main/templatedparams|parámetru dende plantía]] úfrese basándose {{PLURAL:$1|nel valor|nos valores}} de $2.",
        "apisandbox-deprecated-parameters": "Parámetros anticuaos",
        "apisandbox-fetch-token": "Rellenu automáticu del pase",
        "apisandbox-add-multi": "Amestar",
        "whatlinkshere": "Lo qu'enllaza equí",
        "whatlinkshere-title": "Páxines qu’enllacien a «$1»",
        "whatlinkshere-page": "Páxina:",
-       "linkshere": "Les páxines siguientes enllacien a '''[[:$1]]''':",
-       "nolinkshere": "Nenguna páxina enllaza a '''[[:$1]]'''.",
-       "nolinkshere-ns": "Nenguna páxina enllaza con <strong>[[:$1]]</strong> nel espaciu de nomes escoyíu.",
+       "linkshere-2": "Les páxines siguientes enllacien a '''$1''':",
+       "nolinkshere-2": "Nenguna páxina enllaza a '''$1'''.",
+       "nolinkshere-ns-2": "Nenguna páxina enllaza con <strong>$1</strong> nel espaciu de nomes escoyíu.",
        "isredirect": "páxina de redireición",
        "istemplate": "tresclusión",
        "isimage": "enllaz al ficheru",
        "pagedata-title": "Datos de la páxina",
        "pagedata-text": "Esta páxina ufre una interfaz de datos pa les páxines. Escribe'l títulu de la páxina na URL, usando la sintaxis de subpáxina.\n* Aplícase la negociación de conteníu en base a la testera Accept del to cliente. Esto significa que los datos de la páxina van dase nel formatu que prefiera'l to cliente.",
        "pagedata-not-acceptable": "Nun s'alcontró nengún formatu que coincidiera. Tipos MIME soportaos: $1",
-       "pagedata-bad-title": "Títulu inválidu: $1."
+       "pagedata-bad-title": "Títulu inválidu: $1.",
+       "unregistered-user-config": "Por motivos de seguridá, les subpáxines d'usuariu JavaScript, CSS y JSON nun pueden cargase pa usuarios ensin rexistrar."
 }
index 578221c..185574b 100644 (file)
        "whatlinkshere": "Kaskina ickwemakina ka witci acteki",
        "whatlinkshere-title": "Masinahikan nte mia ka ici tapitik \"$1\"",
        "whatlinkshere-page": "Masinahikan:",
-       "linkshere": "Masinhikan ka ici tapitik <strong>[[:$1]]</strong>:",
+       "linkshere-2": "Masinhikan ka ici tapitik <strong>$1</strong>:",
        "isredirect": "masinhikan ke kweskiticohemikok",
        "istemplate": "ka ki acotcipitcikatek",
        "isimage": "e ici tapitik masinahikaniwoc",
index 39b2b30..92939aa 100644 (file)
        "whatlinkshere": "Gluyarakiraf bueem",
        "whatlinkshere-title": "Bu gluyasu va \"$1\"",
        "whatlinkshere-page": "Bu :",
-       "linkshere": "Van batu bu vlevef bueem va gluyasiki ruldar : '''[[:$1]]'''",
-       "nolinkshere": "Van batu bu nedoyu bu va gluyasiki ruldar : '''[[:$1]]'''",
-       "nolinkshere-ns": "Koe kiblayano yoltxo meku bu gluyasikikirafu gu '''[[:$1]]'''.",
+       "linkshere-2": "Van batu bu vlevef bueem va gluyasiki ruldar : '''$1'''",
+       "nolinkshere-2": "Van batu bu nedoyu bu va gluyasiki ruldar : '''$1'''",
+       "nolinkshere-ns-2": "Koe kiblayano yoltxo meku bu gluyasikikirafu gu '''$1'''.",
        "isredirect": "graskarabu",
        "istemplate": "kodoplekura",
        "isimage": "skedasiki va ewava",
index ddcfbc4..db933ef 100644 (file)
        "whatlinkshere": "हिँया का जोडान अहै",
        "whatlinkshere-title": "$1 से जोडान पन्ना",
        "whatlinkshere-page": "पन्ना:",
-       "linkshere": "नीचे दिहा पन्ना '''[[:$1]]''' से जोडान है:",
-       "nolinkshere": "'''[[:$1]]''' से कुछ नाइ जोडान् है।",
-       "nolinkshere-ns": "चुनल नामस्थानसे '''[[:$1]]''' से कवनो पन्ना नाइ जोडान् है।",
+       "linkshere-2": "नीचे दिहा पन्ना '''$1''' से जोडान है:",
+       "nolinkshere-2": "'''$1''' से कुछ नाइ जोडान् है।",
+       "nolinkshere-ns-2": "चुनल नामस्थानसे '''$1''' से कवनो पन्ना नाइ जोडान् है।",
        "isredirect": "पुनर्निर्देशन पन्ना",
        "istemplate": "मिलावा जाय",
        "isimage": "फ़ाइल कय कड़ी",
        "fileduplicatesearch-noresults": "कवनो \"$1\" फाइल नाइ मिला।",
        "specialpages": "खाश पन्ना",
        "specialpages-note-top": "कुंजी",
+       "specialpages-note-restricted": "* साधारण विशेष पन्ना।\n* <span class=\"mw-specialpagerestricted\">प्रतिबंधित विशेष पन्ना।</span>",
        "specialpages-group-maintenance": "अनुरक्षण रिपोर्ट",
        "specialpages-group-other": "अउर खाश पन्ना",
        "specialpages-group-login": "लाग इन / खाता खोला जाय",
index 1b15090..c7afe94 100644 (file)
        "whatlinkshere": "Bu səhifəyə bağlantılar",
        "whatlinkshere-title": "\"$1\" məqaləsinə keçid verən səhifələr",
        "whatlinkshere-page": "Səhifə:",
-       "linkshere": "'''[[:$1]]''' səhifəsinə keçid verən səhifələr:",
-       "nolinkshere": "<strong>[[:$1]]</strong> səhifəsinə keçid verən səhifə yoxdur.",
-       "nolinkshere-ns": "Seçilmiş ad aralığında heç bir səhifə '''[[:$1]]''' səhifəsinə keçid vermir.",
+       "linkshere-2": "'''$1''' səhifəsinə keçid verən səhifələr:",
+       "nolinkshere-2": "<strong>$1</strong> səhifəsinə keçid verən səhifə yoxdur.",
+       "nolinkshere-ns-2": "Seçilmiş ad aralığında heç bir səhifə '''$1''' səhifəsinə keçid vermir.",
        "isredirect": "İstiqamətləndirmə səhifəsi",
        "istemplate": "daxil olmuş",
        "isimage": "şəkil üçün keçid",
index f7e2265..4ec9935 100644 (file)
        "recentchangeslinked-feed": "باغلی دَییشیکلیک‌لر",
        "recentchangeslinked-toolbox": "باغلی دَییشیکلیک‌لر",
        "recentchangeslinked-title": "''$1'' ایله باغلی دییشیکلر",
-       "recentchangeslinked-summary": "آشاغیداکی سیياهی، قئيد اوْلونان صحیفه‌‌يه (و يا قئيد اوْلونان کاتئقوْرياداکی صحیفه‌‌لره) داخیلی کئچید وئرن صحیفه‌‌لرده ائدیلمیش سوْن ديَیشیکلیکلرین سیياهیسیدیر. \n[[Special:Watchlist|ایزله‌مه سیياهینیزداکی]] صحیفه‌‌لر '''قالین''' شریفتله گؤستریلمیشدیر.",
+       "recentchangeslinked-summary": "آشاغیداکی ژورنال، قئيد اوْلونان صفحه‌‌يه (و يا قئيد اوْلونان بؤلمه‌ده‌کی صفحه‌‌لره) داخیلی کئچید وئرن صفحه‌‌لرده ائدیلمیش سوْن ديَیشیکلیکلرین لیستیدیر. \n[[Special:Watchlist|ایزله‌مه لیستینیزده]]‌کی صفحه‌‌لر '''قالین''' شریفتله گؤستریلمیشدیر.",
        "recentchangeslinked-page": "صفحه آدی:",
        "recentchangeslinked-to": "قئيد اوْلونان صحیفه‌‌ده‌کی دئيیل، اوْنا داخیلی کئچید وئرن صحیفه‌‌لرده‌کی ديَیشیکلیکلری گؤستر",
        "upload": "فایل یوکله‌",
        "whatlinkshere": "بۇ صفحه‌‌يه باغلانتیلار",
        "whatlinkshere-title": "«$1»-ه باغلانان صفحه‌لر",
        "whatlinkshere-page": "صفحه:",
-       "linkshere": "آشاغیداکی صفحه‌لر '''[[:$1]]'''-ه باغلانیب:",
-       "nolinkshere": "<strong>[[:$1]]</strong>-ه هئچ بیر صفحه باغلانماییب‌دیر.",
-       "nolinkshere-ns": "سئچیلمیش آدفضاسیندا، هئچ صحیفه '''[[:$1]]'''-ه باغلانتی‌سی یوخدور.",
+       "linkshere-2": "آشاغیداکی صفحه‌لر '''$1'''-ه باغلانیب:",
+       "nolinkshere-2": "<strong>$1</strong>-ه هئچ بیر صفحه باغلانماییب‌دیر.",
+       "nolinkshere-ns-2": "سئچیلمیش آدفضاسیندا، هئچ صحیفه '''$1'''-ه باغلانتی‌سی یوخدور.",
        "isredirect": "یوللاندیرما صفحه‌سی",
        "istemplate": "داخیل اولموش",
        "isimage": "فایلا باغلانتی",
        "fileduplicatesearch-result-n": "«$1» فایلینین، {{PLURAL:$2|بیر|$2}} عینی کوپیسی واردیر.",
        "fileduplicatesearch-noresults": "\"$1\" آدیندا فایل تاپیلمادی.",
        "specialpages": "اؤزل صفحه‌لر",
+       "specialpages-note-restricted": "* نورمال اؤزل صفحه‌لر.\n* <span class=\"mw-specialpagerestricted\">محدودلاشدیریلمیش اؤزل صفحه‌لر.</span>",
        "specialpages-group-maintenance": "ساخلانیش گوزاریشلری",
        "specialpages-group-other": "آیری اؤزل صفحه‌لر",
        "specialpages-group-login": "گیریش / حساب یارات",
index 00540ea..033c601 100644 (file)
        "whatlinkshere": "Бында һылтанмалар",
        "whatlinkshere-title": "«$1» битенә һылтанған биттәр",
        "whatlinkshere-page": "Бит:",
-       "linkshere": "'''[[:$1]]''' битенә киләһе биттәр һылтана:",
-       "nolinkshere": "'''[[:$1]]''' битенә бер бит тә һылтанмай.",
-       "nolinkshere-ns": "'''[[:$1]]''' битенә һайланған исемдәр арауығынан бер бит тә һылтанмай.",
+       "linkshere-2": "'''$1''' битенә киләһе биттәр һылтана:",
+       "nolinkshere-2": "'''$1''' битенә бер бит тә һылтанмай.",
+       "nolinkshere-ns-2": "'''$1''' битенә һайланған исемдәр арауығынан бер бит тә һылтанмай.",
        "isredirect": "йүнәлтеү бите",
        "istemplate": "ҡушылған",
        "isimage": "файл һылтанмаһы",
index 143531c..4ca49b6 100644 (file)
        "whatlinkshere": "Links af de Seitn",
        "whatlinkshere-title": "Seitn, wo af „$1“ valinka",
        "whatlinkshere-page": "Seitn:",
-       "linkshere": "De foigandn Seitn valinka af '''„[[:$1]]“''':",
-       "nolinkshere": "Koa Seitn valinkt af '''„[[:$1]]“'''.",
+       "linkshere-2": "De foigandn Seitn valinka af '''„$1“''':",
+       "nolinkshere-2": "Koa Seitn valinkt af '''„$1“'''.",
        "isredirect": "Weidaloatungsseitn",
        "istemplate": "Vorlogneinbindung",
        "isimage": "Dateilink",
        "fileduplicatesearch-info": "$1 × $2 Pixel<br />Daateigress: $3<br />MIME-Typ: $4",
        "fileduplicatesearch-result-1": "Dé Daatei „$1“ hod koane identischen Duplikaate.",
        "specialpages": "Spezialseitn",
+       "specialpages-note-restricted": "* Reguläre Speziaalseiten\n* <span class=\"mw-specialpagerestricted\">Zuagrifsbschränkde Speziaalseiten</span>\n* <span class=\"mw-specialpagecached\">Cachegenerrirde Speziaalseiten (Da Inhoid is méglicherweis vaoiterd)</span>",
        "specialpages-group-maintenance": "Wartungslisten",
        "specialpages-group-other": "Åndre Speziaalseiten",
        "specialpages-group-login": "Åmöden",
index e1037ac..a15010d 100644 (file)
        "whatlinkshere": "ای لینکی که ادا هست",
        "whatlinkshere-title": "صفحاتی که لینگ بوتگنت په \"$1\"",
        "whatlinkshere-page": "صفحه:",
-       "linkshere": "جهلیگی صفحات لینک بوت '''[[:$1]]''':",
-       "nolinkshere": "هچ لینک صفحه ای په '''[[:$1]]'''.",
-       "nolinkshere-ns": "هج صفحه ای لینک نهنت په '''[[:$1]]''' ته ای انتخابی نام فضا",
+       "linkshere-2": "جهلیگی صفحات لینک بوت '''$1''':",
+       "nolinkshere-2": "هچ لینک صفحه ای په '''$1'''.",
+       "nolinkshere-ns-2": "هج صفحه ای لینک نهنت په '''$1''' ته ای انتخابی نام فضا",
        "isredirect": "صفحه غیر مستقیم",
        "istemplate": "همراهی",
        "isimage": "لینک عکس",
        "fileduplicatesearch-result-1": " \"$1\" فایل هچ مشحصین دوبلی نیست.",
        "fileduplicatesearch-result-n": "فایل \"$1\" has {{PLURAL:$2|1 identical duplication|$2 مشخصین کپی بوتن}}.",
        "specialpages": "حاصین صفحات",
+       "specialpages-note-restricted": "* نرمال صفحات حاص.\n*  <strong class=\"mw-specialpagerestricted\">محدودین صفحات حاص.</strong>",
        "specialpages-group-maintenance": "گزارشات دارگ",
        "specialpages-group-other": "دگر حاصین صفحات",
        "specialpages-group-login": "ورود/ثبت نام",
index 427ccdb..a839c35 100644 (file)
        "whatlinkshere": "Ano an mga makasugpon digde",
        "whatlinkshere-title": "Mga pahina na nakasugpon sa \"$1\"",
        "whatlinkshere-page": "Pahina:",
-       "linkshere": "An mga minasunod na pahina isinusugpon sa '''[[:$1]]''':",
-       "nolinkshere": "Mayong mga pahinang kasugpon sa '''[[:$1]]'''.",
-       "nolinkshere-ns": "Mayong pahina na nakatakod sa '''[[:$1]]''' sa piniling ngaran-espacio.",
+       "linkshere-2": "An mga minasunod na pahina isinusugpon sa '''$1''':",
+       "nolinkshere-2": "Mayong mga pahinang kasugpon sa '''$1'''.",
+       "nolinkshere-ns-2": "Mayong pahina na nakatakod sa '''$1''' sa piniling ngaran-espacio.",
        "isredirect": "palikwaton an pahina",
        "istemplate": "pinagkabalihan",
        "isimage": "kasugpon nin sagunson",
        "fileduplicatesearch-noresults": "Mayong sagunson na pinagngaranan na \"$1\" an nanagboan.",
        "specialpages": "Mga espesyal na pahina",
        "specialpages-note-top": "Balaynan",
+       "specialpages-note-restricted": "* Normal sa espesyal na mga pahina.\n* <span class=\"mw-specialpagerestricted\"> Restriktadong espesyal na mga pahina.</span>",
        "specialpages-group-maintenance": "Mga talaan nin pagpangataman",
        "specialpages-group-other": "Iba pang mga espesyal na pahina",
        "specialpages-group-login": "Maglaog / magmukna nin panindog",
index df3cd07..eb9533f 100644 (file)
        "botpasswords-restriction-failed": "Уваход ня выкананы праз абмежаваньні на пароль робата",
        "botpasswords-invalid-name": "Пададзенае імя ўдзельніка ня ўтрымлівае падзяляльнік для паролю робата («$1»).",
        "botpasswords-not-exist": "Удзельнік «$1» ня мае паролю для робата з назвай «$2».",
+       "botpasswords-needs-reset": "Пароль для робата зь імем «$2» {{GENDER:$1|удзельніка|удзельніцы}} «$1» мусіць быць скінуты.",
        "resetpass_forbidden": "Пароль ня можа быць зьменены",
        "resetpass_forbidden-reason": "Паролі ня могуць быць зьмененыя: $1",
        "resetpass-no-info": "Для непасрэднага доступу да гэтай старонкі Вам неабходна ўвайсьці ў сыстэму.",
        "subject-preview": "Папярэдні прагляд загалоўку:",
        "previewerrortext": "Адбылася памылка пры спробе папярэдняга прагляду вашых зьменаў.",
        "blockedtitle": "Удзельнік заблякаваны",
-       "blockedtext": "<strong>Ð\92аÑ\88 Ñ\80аÑ\85Ñ\83нак Ñ\83дзелÑ\8cнÑ\96ка Ñ\86Ñ\96 IP-адÑ\80аÑ\81 Ð±Ñ\8bÑ\9e Ð·Ð°Ð±Ð»Ñ\8fкаванÑ\8b.</strong>\n\nÐ\91лÑ\8fкаванÑ\8cне Ð²Ñ\8bканаÑ\9e $1.\nÐ\9fÑ\80Ñ\8bÑ\87Ñ\8bна Ð³Ñ\8dÑ\82ага: <em>$2</em>.\n\n* Ð\9fаÑ\87аÑ\82ак Ð±Ð»Ñ\8fкаванÑ\8cнÑ\8f: $8\n* Ð¡ÐºÐ°Ð½Ñ\87Ñ\8dнÑ\8cне Ð±Ð»Ñ\8fкаванÑ\8cнÑ\8f: $6\n* Ð\91Ñ\8bÑ\9e Ð·Ð°Ð±Ð»Ñ\8fкаванÑ\8b: $7\n\nÐ\92Ñ\8b Ð¼Ð¾Ð¶Ð°Ñ\86е Ñ\81канÑ\82акÑ\82аваÑ\86Ñ\86а Ð· $1 Ñ\86Ñ\96 Ð°Ð´Ð½Ñ\8bм Ð·Ñ\8c Ñ\96нÑ\88Ñ\8bÑ\85 [[{{MediaWiki:Grouppage-sysop}}|адмÑ\96нÑ\96Ñ\81Ñ\82Ñ\80аÑ\82аÑ\80аÑ\9e]], ÐºÐ°Ð± Ð°Ð±Ð¼ÐµÑ\80каваÑ\86Ñ\8c Ð±Ð»Ñ\8fкаванÑ\8cне. Ð\97аÑ\9eважÑ\86е, Ñ\88Ñ\82о Ð\92Ñ\8b Ð½Ñ\8f Ð·Ð¼Ð¾Ð¶Ð°Ñ\86е Ñ\9eжÑ\8bÑ\86Ñ\8c Ð¼Ð°Ð³Ñ\87Ñ\8bмаÑ\81Ñ\8cÑ\86Ñ\8c Â«Ð´Ð°Ñ\81лаÑ\86Ñ\8c Ð»Ñ\96Ñ\81Ñ\82 Ð¿Ð° Ñ\8dлекÑ\82Ñ\80оннай Ð¿Ð¾Ñ\88Ñ\86е», Ð¿Ð°ÐºÑ\83лÑ\8c Ð½Ðµ Ð¿Ð°Ð·Ð½Ð°Ñ\87Ñ\8bÑ\86е Ñ\81апÑ\80аÑ\9eднÑ\8b Ð°Ð´Ñ\80аÑ\81 Ñ\8dлекÑ\82Ñ\80оннай Ð¿Ð¾Ñ\88Ñ\82Ñ\8b Ñ\9e Ð\92аÑ\88Ñ\8bÑ\85 [[Special:Preferences|наладаÑ\85]], Ñ\96 ÐºÐ°Ð»Ñ\96 Ð³Ñ\8dÑ\82а Ð\92ам Ð½Ðµ Ð±Ñ\8bло Ð·Ð°Ð±Ð°Ñ\80онена.\nÐ\92аÑ\88 IP-адÑ\80аÑ\81 â\80\94 $3, Ñ\96дÑ\8dнÑ\82Ñ\8bÑ\84Ñ\96каÑ\82аÑ\80 Ð±Ð»Ñ\8fкаванÑ\8cнÑ\8f â\80\94 #$5.\nÐ\9aалÑ\96 Ð»Ð°Ñ\81ка, Ñ\83лÑ\83Ñ\87айÑ\86е Ñ\9eÑ\81Ñ\8e Ð²Ñ\8bÑ\88Ñ\8dйпададзенÑ\83Ñ\8e Ñ\96нÑ\84аÑ\80маÑ\86Ñ\8bÑ\8e Ð²Ð° Ñ\9eÑ\81е Ð·Ð°Ð¿Ñ\8bÑ\82Ñ\8b, Ñ\88Ñ\82о Ð\92ы будзеце рабіць.",
-       "autoblockedtext": "Ð\92аÑ\88 IP-адÑ\80аÑ\81 Ð±Ñ\8bÑ\9e Ð°Ñ\9eÑ\82амаÑ\82Ñ\8bÑ\87на Ð·Ð°Ð±Ð»Ñ\8fкаванÑ\8b, Ñ\82амÑ\83 Ñ\88Ñ\82о Ñ\91н Ñ\83жÑ\8bваÑ\9eÑ\81Ñ\8f Ñ\96нÑ\88Ñ\8bм Ñ\83дзелÑ\8cнÑ\96кам, Ñ\8fкÑ\96 Ð±Ñ\8bÑ\9e Ð·Ð°Ð±Ð»Ñ\8fкаванÑ\8b $1.\nÐ\9fÑ\80Ñ\8bÑ\87Ñ\8bна Ð³Ñ\8dÑ\82ага:\n\n:<em>$2</em>\n\n* Ð\91лÑ\8fкаванÑ\8cне Ð¿Ð°Ñ\87алоÑ\81Ñ\8f: $8\n* Ð\91лÑ\8fкаванÑ\8cне Ñ\81конÑ\87Ñ\8bÑ\86Ñ\86а: $6\n* Ð\91Ñ\8bÑ\9e Ð·Ð°Ð±Ð»Ñ\8fкаванÑ\8b: $7\n\nÐ\92Ñ\8b Ð¼Ð¾Ð¶Ð°Ñ\86е Ñ\81канÑ\82акÑ\82аваÑ\86Ñ\86а Ð· $1 Ñ\86Ñ\96 Ð· Ð°Ð´Ð½Ñ\8bм Ð·Ñ\8c Ñ\96нÑ\88Ñ\8bÑ\85 [[{{MediaWiki:Grouppage-sysop}}|адмÑ\96нÑ\96Ñ\81Ñ\82Ñ\80аÑ\82аÑ\80аÑ\9e]], ÐºÐ°Ð± Ð°Ð±Ð¼ÐµÑ\80каваÑ\86Ñ\8c Ð±Ð»Ñ\8fкаванÑ\8cне.\n\nÐ\97аÑ\9eважÑ\86е, Ñ\88Ñ\82о Ð\92Ñ\8b Ð½Ñ\8f Ð·Ð¼Ð¾Ð¶Ð°Ñ\86е Ñ\9eжÑ\8bваÑ\86Ñ\8c Ð¼Ð°Ð³Ñ\87Ñ\8bмаÑ\81Ñ\8cÑ\86Ñ\8c Â«Ð´Ð°Ñ\81лаÑ\86Ñ\8c Ð»Ñ\96Ñ\81Ñ\82 Ð¿Ñ\80аз Ñ\8dлекÑ\82Ñ\80оннÑ\83Ñ\8e Ð¿Ð¾Ñ\88Ñ\82Ñ\83», Ð¿Ð°ÐºÑ\83лÑ\8c Ð½Ñ\8f Ð±Ñ\83дзе Ð¿Ð°Ð·Ð½Ð°Ñ\87анÑ\8b Ð´Ð·ÐµÐ¹Ð½Ñ\8b Ð°Ð´Ñ\80аÑ\81 Ñ\8dлекÑ\82Ñ\80оннай Ð¿Ð¾Ñ\88Ñ\82Ñ\8b Ñ\9e Ð\92аÑ\88Ñ\8bÑ\85 [[Special:Preferences|наладаÑ\85 Ñ\83дзелÑ\8cнÑ\96ка]], Ñ\96 ÐºÐ°Ð»Ñ\96 Ð³Ñ\8dÑ\82а Ð\92ам Ð½Ðµ Ð±Ñ\8bло Ð·Ð°Ð±Ð°Ñ\80онена.\n\nÐ\92аÑ\88 Ñ\86Ñ\8fпеÑ\80аÑ\88нÑ\96 IP-адÑ\80аÑ\81 â\80\94 $3, Ñ\96дÑ\8dнÑ\82Ñ\8bÑ\84Ñ\96каÑ\82аÑ\80 Ð±Ð»Ñ\8fкаванÑ\8cнÑ\8f â\80\94 #$5.\nÐ\9aалÑ\96 Ð»Ð°Ñ\81ка, Ñ\83лÑ\83Ñ\87айÑ\86е Ñ\9eÑ\81Ñ\8e Ð²Ñ\8bÑ\88Ñ\8dйпададзенÑ\83Ñ\8e Ñ\96нÑ\84аÑ\80маÑ\86Ñ\8bÑ\8e Ð²Ð° Ñ\9eÑ\81е Ð·Ð°Ð¿Ñ\8bÑ\82Ñ\8b, Ñ\88Ñ\82о Ð\92ы будзеце рабіць.",
+       "blockedtext": "<strong>Ð\92аÑ\88 Ñ\80аÑ\85Ñ\83нак Ñ\83дзелÑ\8cнÑ\96ка Ñ\86Ñ\96 IP-адÑ\80аÑ\81 Ð±Ñ\8bÑ\9e Ð·Ð°Ð±Ð»Ñ\8fкаванÑ\8b.</strong>\n\nÐ\91лÑ\8fкаванÑ\8cне Ð²Ñ\8bканаÑ\9e $1.\nÐ\9fÑ\80Ñ\8bÑ\87Ñ\8bна Ð³Ñ\8dÑ\82ага: <em>$2</em>.\n\n* Ð\9fаÑ\87аÑ\82ак Ð±Ð»Ñ\8fкаванÑ\8cнÑ\8f: $8\n* Ð¡ÐºÐ°Ð½Ñ\87Ñ\8dнÑ\8cне Ð±Ð»Ñ\8fкаванÑ\8cнÑ\8f: $6\n* Ð\91Ñ\8bÑ\9e Ð·Ð°Ð±Ð»Ñ\8fкаванÑ\8b: $7\n\nÐ\92Ñ\8b Ð¼Ð¾Ð¶Ð°Ñ\86е Ñ\81канÑ\82акÑ\82аваÑ\86Ñ\86а Ð· $1 Ñ\86Ñ\96 Ð°Ð´Ð½Ñ\8bм Ð·Ñ\8c Ñ\96нÑ\88Ñ\8bÑ\85 [[{{MediaWiki:Grouppage-sysop}}|адмÑ\96нÑ\96Ñ\81Ñ\82Ñ\80аÑ\82аÑ\80аÑ\9e]], ÐºÐ°Ð± Ð°Ð±Ð¼ÐµÑ\80каваÑ\86Ñ\8c Ð±Ð»Ñ\8fкаванÑ\8cне. Ð\97аÑ\9eважÑ\86е, Ñ\88Ñ\82о Ð²Ñ\8b Ð½Ñ\8f Ð·Ð¼Ð¾Ð¶Ð°Ñ\86е Ñ\9eжÑ\8bÑ\86Ñ\8c Ð¼Ð°Ð³Ñ\87Ñ\8bмаÑ\81Ñ\8cÑ\86Ñ\8c Â«{{int:emailuser}}», Ð¿Ð°ÐºÑ\83лÑ\8c Ð½Ðµ Ð¿Ð°Ð·Ð½Ð°Ñ\87Ñ\8bÑ\86е Ñ\81апÑ\80аÑ\9eднÑ\8b Ð°Ð´Ñ\80аÑ\81 Ñ\8dлекÑ\82Ñ\80оннай Ð¿Ð¾Ñ\88Ñ\82Ñ\8b Ñ\9e Ð²Ð°Ñ\88Ñ\8bÑ\85 [[Special:Preferences|наладаÑ\85]], Ñ\96 ÐºÐ°Ð»Ñ\96 Ð³Ñ\8dÑ\82а Ð²Ð°Ð¼ Ð½Ðµ Ð±Ñ\8bло Ð·Ð°Ð±Ð°Ñ\80онена.\nÐ\92аÑ\88 IP-адÑ\80аÑ\81 â\80\94 $3, Ñ\96дÑ\8dнÑ\82Ñ\8bÑ\84Ñ\96каÑ\82аÑ\80 Ð±Ð»Ñ\8fкаванÑ\8cнÑ\8f â\80\94 #$5.\nÐ\9aалÑ\96 Ð»Ð°Ñ\81ка, Ñ\83лÑ\83Ñ\87айÑ\86е Ñ\9eÑ\81Ñ\8e Ð²Ñ\8bÑ\88Ñ\8dйпададзенÑ\83Ñ\8e Ñ\96нÑ\84аÑ\80маÑ\86Ñ\8bÑ\8e Ð²Ð° Ñ\9eÑ\81е Ð·Ð°Ð¿Ñ\8bÑ\82Ñ\8b, Ñ\88Ñ\82о Ð²ы будзеце рабіць.",
+       "autoblockedtext": "Ð\92аÑ\88 IP-адÑ\80аÑ\81 Ð±Ñ\8bÑ\9e Ð°Ñ\9eÑ\82амаÑ\82Ñ\8bÑ\87на Ð·Ð°Ð±Ð»Ñ\8fкаванÑ\8b, Ñ\82амÑ\83 Ñ\88Ñ\82о Ñ\91н Ñ\83жÑ\8bваÑ\9eÑ\81Ñ\8f Ñ\96нÑ\88Ñ\8bм Ñ\83дзелÑ\8cнÑ\96кам, Ñ\8fкÑ\96 Ð±Ñ\8bÑ\9e Ð·Ð°Ð±Ð»Ñ\8fкаванÑ\8b $1.\nÐ\9fÑ\80Ñ\8bÑ\87Ñ\8bна Ð³Ñ\8dÑ\82ага:\n\n:<em>$2</em>\n\n* Ð\91лÑ\8fкаванÑ\8cне Ð¿Ð°Ñ\87алоÑ\81Ñ\8f: $8\n* Ð\91лÑ\8fкаванÑ\8cне Ñ\81конÑ\87Ñ\8bÑ\86Ñ\86а: $6\n* Ð\91Ñ\8bÑ\9e Ð·Ð°Ð±Ð»Ñ\8fкаванÑ\8b: $7\n\nÐ\92Ñ\8b Ð¼Ð¾Ð¶Ð°Ñ\86е Ñ\81канÑ\82акÑ\82аваÑ\86Ñ\86а Ð· $1 Ñ\86Ñ\96 Ð· Ð°Ð´Ð½Ñ\8bм Ð·Ñ\8c Ñ\96нÑ\88Ñ\8bÑ\85 [[{{MediaWiki:Grouppage-sysop}}|адмÑ\96нÑ\96Ñ\81Ñ\82Ñ\80аÑ\82аÑ\80аÑ\9e]], ÐºÐ°Ð± Ð°Ð±Ð¼ÐµÑ\80каваÑ\86Ñ\8c Ð±Ð»Ñ\8fкаванÑ\8cне.\n\nÐ\97аÑ\9eважÑ\86е, Ñ\88Ñ\82о Ð²Ñ\8b Ð½Ñ\8f Ð·Ð¼Ð¾Ð¶Ð°Ñ\86е Ñ\9eжÑ\8bваÑ\86Ñ\8c Ð¼Ð°Ð³Ñ\87Ñ\8bмаÑ\81Ñ\8cÑ\86Ñ\8c Â«{{int:emailuser}}», Ð¿Ð°ÐºÑ\83лÑ\8c Ð½Ñ\8f Ð±Ñ\83дзе Ð¿Ð°Ð·Ð½Ð°Ñ\87анÑ\8b Ð´Ð·ÐµÐ¹Ð½Ñ\8b Ð°Ð´Ñ\80аÑ\81 Ñ\8dлекÑ\82Ñ\80оннай Ð¿Ð¾Ñ\88Ñ\82Ñ\8b Ñ\9e Ð²Ð°Ñ\88Ñ\8bÑ\85 [[Special:Preferences|наладаÑ\85 Ñ\83дзелÑ\8cнÑ\96ка]], Ñ\96 ÐºÐ°Ð»Ñ\96 Ð³Ñ\8dÑ\82а Ð²Ð°Ð¼ Ð½Ðµ Ð±Ñ\8bло Ð·Ð°Ð±Ð°Ñ\80онена.\n\nÐ\92аÑ\88 Ñ\86Ñ\8fпеÑ\80аÑ\88нÑ\96 IP-адÑ\80аÑ\81 â\80\94 $3, Ñ\96дÑ\8dнÑ\82Ñ\8bÑ\84Ñ\96каÑ\82аÑ\80 Ð±Ð»Ñ\8fкаванÑ\8cнÑ\8f â\80\94 #$5.\nÐ\9aалÑ\96 Ð»Ð°Ñ\81ка, Ñ\83лÑ\83Ñ\87айÑ\86е Ñ\9eÑ\81Ñ\8e Ð²Ñ\8bÑ\88Ñ\8dйпададзенÑ\83Ñ\8e Ñ\96нÑ\84аÑ\80маÑ\86Ñ\8bÑ\8e Ð²Ð° Ñ\9eÑ\81е Ð·Ð°Ð¿Ñ\8bÑ\82Ñ\8b, Ñ\88Ñ\82о Ð²ы будзеце рабіць.",
        "systemblockedtext": "Вашае імя ўдзельніка ці IP-адрас былі аўтаматычна заблякаваныя MediaWiki.\nЗ наступнай прычыны:\n\n:<em>$2</em>\n\n* Пачатак блякаваньня: $8\n* Сканчэньне блякаваньня: $6\n* Мэта блякаваньня: $7\n\nВаш цяперашні IP-адрас — $3.\nКалі ласка, уключайце ўсе пададзеныя вышэй дэталі ва ўсе запыты, што вы робіце.",
        "blockednoreason": "прычына не пазначана",
        "whitelistedittext": "Вам трэба $1, каб рэдагаваць старонкі.",
        "upload": "Загрузіць файл",
        "uploadbtn": "Загрузіць файл",
        "reuploaddesc": "Скасаваць загрузку і вярнуцца да формы загрузкі",
-       "upload-tryagain": "Даслаць зьмененае апісаньне файла",
+       "upload-tryagain": "Даслаць зьмененае апісаньне файлу",
        "upload-tryagain-nostash": "Даслаць паўторна загружаны файл і зьмененае апісаньне",
        "uploadnologin": "Вы не ўвайшлі ў сыстэму",
        "uploadnologintext": "Вам трэба $1, каб загружаць файлы.",
        "upload_directory_missing": "Загрузачная дырэкторыя ($1) адсутнічае і ня можа быць створаная сэрвэрам.",
        "upload_directory_read_only": "Сэрвэр ня мае правоў на запіс у дырэкторыю загружаных файлаў ($1).",
        "uploaderror": "Памылка загрузкі",
-       "upload-recreate-warning": "'''Увага: файл з такой назвай быў выдалены альбо перанесены.'''\n\nЖурнал выдаленьняў і пераносаў гэтай старонкі для зручнасьці пададзены тут:",
+       "upload-recreate-warning": "<strong>Увага: файл з такой назвай быў выдалены альбо перанесены.</strong>\n\nЖурнал выдаленьняў і пераносаў гэтай старонкі для зручнасьці пададзены тут:",
        "uploadtext": "Ужывайце форму ніжэй для загрузкі файлаў.\nКаб паглядзець ці адшукаць раней загружаныя файлы, глядзіце [[Special:FileList|сьпіс загружаных файлаў]], загрузкі таксама запісваюцца ў [[Special:Log/upload|журнал загрузак]], а выдаленьні — у [[Special:Log/delete|журнал выдаленьняў]].\n\nКаб улучыць файл у старонку, ужывайце адзін з наступных варыянтаў:\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' для поўнай вэрсіі файла\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|Подпіс да выявы]]</nowiki></code>''' для выявы шырынёй 200 піксэляў у рамцы і тэкстам «Подпіс да выявы» ў якасьці подпісу\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' для простай спасылкі на файл безь яго адлюстраваньня.",
        "upload-permitted": "{{PLURAL:$2|Дазволены тып|Дазволеныя тыпы}} файлаў: $1.",
        "upload-preferred": "{{PLURAL:$2|Пажаданы тып|Пажаданыя тыпы}} файлаў: $1.",
        "upload-prohibited": "{{PLURAL:$2|Забаронены тып|Забароненыя тыпы}} файлаў: $1.",
        "uploadlogpage": "Журнал загрузак",
-       "uploadlogpagetext": "СÑ\8cпÑ\96Ñ\81 Ð°Ð¿Ð¾Ñ\88нÑ\96Ñ\85 Ð·Ð°Ð³Ñ\80Ñ\83жанÑ\8bÑ\85 Ñ\84айлаÑ\9e.",
-       "filename": "Назва файла",
+       "uploadlogpagetext": "Ð\9dÑ\96жÑ\8dй Ð·Ð½Ð°Ñ\85одзÑ\96Ñ\86Ñ\86а Ñ\81Ñ\8cпÑ\96Ñ\81 Ð°Ð¿Ð¾Ñ\88нÑ\96Ñ\85 Ð·Ð°Ð³Ñ\80Ñ\83жанÑ\8bÑ\85 Ñ\84айлаÑ\9e.\nÐ\93лÑ\8fдзÑ\96Ñ\86е [[Special:NewFiles|галеÑ\80Ñ\8dÑ\8e Ð½Ð¾Ð²Ñ\8bÑ\85 Ñ\84айлаÑ\9e]] Ð´Ð»Ñ\8f Ð±Ð¾Ð»Ñ\8cÑ\88 Ð²Ñ\96зÑ\83алÑ\8cнага Ð°Ð³Ð»Ñ\8fдÑ\83.",
+       "filename": "Назва файлу",
        "filedesc": "Апісаньне",
        "fileuploadsummary": "Апісаньне:",
        "filereuploadsummary": "Зьмены ў файле:",
        "filesource": "Крыніца:",
        "ignorewarning": "Праігнараваць папярэджаньне і захаваць файл",
        "ignorewarnings": "Ігнараваць усе папярэджаньні",
-       "minlength1": "Назва файла павінна ўтрымліваць хаця б адзін сымбаль.",
-       "illegalfilename": "Назва файла «$1» зьмяшчае сымбалі, якія нельга выкарыстоўваць у назвах старонак. Калі ласка, зьмяніце назву файла і паспрабуйце загрузіць яго зноў.",
+       "minlength1": "Назва файлу павінна ўтрымліваць хаця б адну літару.",
+       "illegalfilename": "Назва файлу «$1» зьмяшчае сымбалі, якія нельга выкарыстоўваць у назвах старонак. Калі ласка, зьмяніце назву файлу і паспрабуйце загрузіць яго зноў.",
        "filename-toolong": "Назвы файлаў ня могуць быць даўжэй 240 байтаў.",
        "badfilename": "Назва файла была зьмененая на «$1».",
        "filetype-mime-mismatch": "Пашырэньне файла «.$1» не адпавядае выяўленаму MIME-тыпу файла ($2).",
        "protectedtitles-submit": "Паказаць загалоўкі",
        "listusers": "Сьпіс удзельнікаў і ўдзельніц",
        "listusers-editsonly": "Паказаць толькі ўдзельнікаў, якія маюць рэдагаваньні",
+       "listusers-temporarygroupsonly": "Паказваць толькі ўдзельнікаў у часовых групах удзельнікаў",
        "listusers-creationsort": "Адсартаваць па даце стварэньня",
        "listusers-desc": "Сартаваць па зьмяншэньні",
        "usereditcount": "$1 {{PLURAL:$1|рэдагаваньне|рэдагаваньні|рэдагаваньняў}}",
        "apisandbox-dynamic-parameters-add-label": "Дадаць парамэтар:",
        "apisandbox-dynamic-parameters-add-placeholder": "Назва парамэтру",
        "apisandbox-dynamic-error-exists": "Парамэтар з назвай «$1» ужо існуе.",
+       "apisandbox-templated-parameter-reason": "Гэты [[Special:ApiHelp/main#main/templatedparams|шаблённы парамэтар]] прапануецца паводле {{PLURAL:$1|1=значэньня|значэньняў}} $2.",
        "apisandbox-deprecated-parameters": "Састарэлыя парамэтры",
        "apisandbox-fetch-token": "Аўтазапаўненьне токену",
        "apisandbox-add-multi": "Дадаць",
        "whatlinkshere": "Спасылкі на старонку",
        "whatlinkshere-title": "Старонкі, якія спасылаюцца на $1",
        "whatlinkshere-page": "Старонка:",
-       "linkshere": "Наступныя старонкі спасылаюцца на <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Ніводная старонка не спасылаецца на <strong>[[:$1]]</strong>.",
-       "nolinkshere-ns": "Ніводная старонка не спасылаецца на '''[[:$1]]''' з выбранай прасторы назваў.",
+       "linkshere-2": "Наступныя старонкі спасылаюцца на <strong>$1</strong>:",
+       "nolinkshere-2": "Ніводная старонка не спасылаецца на <strong>$1</strong>.",
+       "nolinkshere-ns-2": "Ніводная старонка не спасылаецца на '''$1''' з выбранай прасторы назваў.",
        "isredirect": "старонка-перанакіраваньне",
        "istemplate": "уключэньне",
        "isimage": "спасылка на файл",
        "pagedata-title": "Зьвесткі старонкі",
        "pagedata-text": "Гэтая старонка забясьпечвае інтэрфэйс зьвестак для старонак. Калі ласка, увядзіце назву старонкі ў URL-адрас з дапамогай сынтаксысу падстаронак.\n* Узгадненьне зьместу засноўваецца на загалоўку Accept вашага кліенту. Гэта значыць, што зьвесткі старонкі будуць пададзеныя ў фармаце, найлепшым для вашага кліенту.",
        "pagedata-not-acceptable": "Ня знойдзены адпаведны фармат. Падтрымліваюцца MIME-тыпы: $1",
-       "pagedata-bad-title": "Няслушная назва: $1."
+       "pagedata-bad-title": "Няслушная назва: $1.",
+       "unregistered-user-config": "З прычынаў бясьпекі JavaScript, CSS і JSON-падстаронкі ўдзельніка ня могуць быць загружаныя для незарэгістраваных удзельнікаў.",
+       "passwordpolicies": "Палітыка пароляў",
+       "passwordpolicies-summary": "Гэта сьпіс дзейных палітыкаў пароляў для групаў удзельнікаў, вызначаных у гэтай вікі.",
+       "passwordpolicies-group": "Група",
+       "passwordpolicies-policies": "Палітыкі",
+       "passwordpolicies-policy-minimalpasswordlength": "Пароль мусіць мець даўжыню найменей $1 {{PLURAL:$1|сымбаль|сымбалі|сымбаляў}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Пароль мусіць мець даўжыню найменш $1 {{PLURAL:$1|сымбаль|сымбалі|сымбаляў}}, каб уваходзіць у сыстэму",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Пароль ня можа супадаць зь імем ўдзельніка",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Пароль ня можа супадаць з паролямі з чорнага сьпісу"
 }
index 0333b61..71c2d94 100644 (file)
        "recentchangesdays-max": "(найбольш $1 {{PLURAL:$1|дзень|дзён}})",
        "recentchangescount": "Перадвызначаная колькасць правак для паказу:",
        "prefs-help-recentchangescount": "Максімальная колькасць: 1000",
-       "prefs-help-watchlist-token2": "Гэта сакрэтны ключ да сеціўнай стужкі з Вашага спіса назірання.\nКожны, хто ведае гэты ключ, будзе мець магчымасць чытаць Ваш спіс назірання, таму не дзяліцеся ім.\nКалі трэба, можна [[Special:ResetTokens|скінуць яго]].",
+       "prefs-help-watchlist-token2": "Гэта сакрэтны ключ да сеціўнай стужкі з Вашага спісу назірання.\nКожны, хто ведае гэты ключ, будзе мець магчымасць чытаць Ваш спіс назірання, таму не дзяліцеся ім.\nКалі трэба, можна [[Special:ResetTokens|скінуць яго]].",
        "savedprefs": "Настройкі замацаваныя.",
        "savedrights": "Групы {{GENDER:$1|ўдзельніка|ўдзельніцы}} $1 захаваныя.",
        "timezonelegend": "Часавы пояс:",
        "uploaded-event-handler-on-svg": "Устаноўка атрыбутаў апрацоўшчыка падзей <code>$1=\"$2\"</code> у SVG файле не дазваляецца.",
        "uploaded-href-attribute-svg": "у SVG файлах атрыбутам href дазволены толькі мэты віду http:// або https://, знойдзена <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-href-unsafe-target-svg": "У ўкладзеным SVG файле знойдзена спасылка на небяспечныя звесткі: URI мэты <code>&lt;$1 $2=\"$3\"&gt;</code>.",
-       "uploaded-animate-svg": "У ўкладзеным SVG файле знойдзены тэг \"animate\", здольны змяніць спасылку з дапамогай атрыбута \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-animate-svg": "Ð\92а ўкладзеным SVG файле знойдзены тэг \"animate\", здольны змяніць спасылку з дапамогай атрыбута \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-setting-event-handler-svg": "Устаноўка атрыбутаў апрацоўкі падзей заблакавана, у ўкладзеным SVG-файле знойдзены код <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-setting-href-svg": "Выкарыстанне тэга \"set\" для дадання атрыбута \"href\" у бацькоўскі элемент заблакавана.",
        "uploaded-wrong-setting-svg": "Ужыванне тэга \"set\" для задання ў якасці мэты аддаленага адраса/звестак/сцэнарыя для любога атрыбута заблакавана. У ўкладзеным SVG-файле знойдзены <code>&lt;set to=\"$1\"&gt;</code>.",
        "whatlinkshere": "Сюды спасылаюцца",
        "whatlinkshere-title": "Старонкі, якія спасылаюцца на \"$1\"",
        "whatlinkshere-page": "Старонка:",
-       "linkshere": "Наступныя старонкі спасылаюцца на <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Няма старонак, якія б спасылаліся на '''[[:$1]]'''.",
-       "nolinkshere-ns": "Няма старонак, якія б спасылаліся на '''[[:$1]]''' у гэтай прасторы назваў.",
+       "linkshere-2": "Наступныя старонкі спасылаюцца на <strong>$1</strong>:",
+       "nolinkshere-2": "Няма старонак, якія б спасылаліся на '''$1'''.",
+       "nolinkshere-ns-2": "Няма старонак, якія б спасылаліся на '''$1''' у гэтай прасторы назваў.",
        "isredirect": "старонка-перасылка",
        "istemplate": "уключэнне",
        "isimage": "Спасылка на выяву",
        "tooltip-ca-undelete": "Аднавіць праўкі, зробленыя на гэтай старонцы перад тым, як яна была сцёрта",
        "tooltip-ca-move": "Перанесці гэтую старонку пад іншую назву",
        "tooltip-ca-watch": "Дадаць гэтую старонку да свайго спісу назіраных старонак",
-       "tooltip-ca-unwatch": "Выняць гэту старонку з вашага спіса назірання",
+       "tooltip-ca-unwatch": "Выняць гэтую старонку з Вашага спісу назірання",
        "tooltip-search": "Знайсці ў {{SITENAME}}",
        "tooltip-search-go": "Перайсці да старонкі з дакладна такой назвай, калі такая наогул існуе",
        "tooltip-search-fulltext": "Знайсці гэты тэкст у тэкстах старонак",
        "confirm-watch-button": "ОК",
        "confirm-watch-top": "Дабавіць старонку ў спіс назірання",
        "confirm-unwatch-button": "ОК",
-       "confirm-unwatch-top": "Ð\92Ñ\8bнÑ\8fÑ\86Ñ\8c Ð³Ñ\8dÑ\82Ñ\83 Ñ\81Ñ\82аÑ\80онкÑ\83 Ð· Ð²Ð°Ñ\88ага Ñ\81пÑ\96Ñ\81а назірання?",
+       "confirm-unwatch-top": "Ð\92Ñ\8bнÑ\8fÑ\86Ñ\8c Ð³Ñ\8dÑ\82Ñ\83 Ñ\81Ñ\82аÑ\80онкÑ\83 Ð· Ð\92аÑ\88ага Ñ\81пÑ\96Ñ\81Ñ\83 назірання?",
        "confirm-rollback-button": "Добра",
        "confirm-rollback-top": "Адкаціць праўкі гэтай старонкі?",
        "quotation-marks": "«$1»",
        "autosumm-replace": "Замена старонкі на '$1'",
        "autoredircomment": "Перасылае да [[$1]]",
        "autosumm-removed-redirect": "Выдаленае перенаправление на [[$1]]",
+       "autosumm-changed-redirect-target": "Мэта перасылкі зменена з [[$1]] на [[$2]]",
        "autosumm-new": "Новая старонка: '$1'",
        "autosumm-newblank": "Створана пустая старонка",
        "size-bytes": "$1 {{PLURAL:$1|байт|байты|байтаў}}",
        "watchlistedit-normal-legend": "Выдаленне складнікаў са спісу назірання",
        "watchlistedit-normal-explain": "Назвы старонак з ліку назіраных паказаныя ніжэй. Каб нешта выдаліць, адзначце клетку побач з адпаведным радком, пасля чаго націсніце \"Выняць складнікі\". Таксама можна правіць гэты спіс непасрэдна, [[Special:EditWatchlist/raw|без афармлення]].",
        "watchlistedit-normal-submit": "Выняць складнікі",
-       "watchlistedit-normal-done": "Ð\97 Ð²Ð°Ñ\88ага Ñ\81пÑ\96Ñ\81а назірання {{PLURAL:$1|быў выдалены|былі выдалены|было выдалена}} $1 {{PLURAL:$1|складнік|складнікі|складнікаў}}:",
+       "watchlistedit-normal-done": "Ð\97 Ð\92аÑ\88ага Ñ\81пÑ\96Ñ\81Ñ\83 назірання {{PLURAL:$1|быў выдалены|былі выдалены|было выдалена}} $1 {{PLURAL:$1|складнік|складнікі|складнікаў}}:",
        "watchlistedit-raw-title": "Нефарматаваны спіс назірання",
        "watchlistedit-raw-legend": "Правіць нефарматаваны спіс назірання",
        "watchlistedit-raw-explain": "Назвы старонак з ліку назіраных паказаныя ніжэй, без афармлення, адна назва на адзін радок; такім чынам, спіс можна правіць як звычайны тэкст. Па сканчэнні націсніце \"{{int:Watchlistedit-raw-submit}}\". Таксама гэта можна зрабіць праз [[Special:EditWatchlist|стандартны інтэрфейс]].",
        "fileduplicatesearch-noresults": "Не знойдзены файл з іменем «$1».",
        "specialpages": "Адмысловыя старонкі",
        "specialpages-note-top": "Легенда",
+       "specialpages-note-restricted": "* Звычайныя адмысловыя старонкі.\n* <span class=\"mw-specialpagerestricted\">Адмысловыя старонкі з абмежаваным доступам.</span>\n* <span class=\"mw-specialpagecached\">Закэшаваныя адмысловыя старонкі (могуць быць састарэлымі).</span>",
        "specialpages-group-maintenance": "Звесткі аб працы",
        "specialpages-group-other": "Іншыя адмысловыя старонкі",
        "specialpages-group-login": "Прадстаўленне / рэгістрацыя",
        "logentry-delete-delete": "$1 {{GENDER:$2|выдаліў|выдаліла}} старонку $3",
        "logentry-delete-delete_redir": "$1 {{GENDER:$2|выдаліў|выдаліла}} перанакіраванне $3 шляхам перазапісу",
        "logentry-delete-restore": "$1 {{GENDER:$2|аднавіў|аднавіла}} старонку $3 ($4)",
+       "restore-count-revisions": "{{PLURAL:$1|1 версія|$1 версіі|$1 версій}}",
        "logentry-delete-event": "$1 {{GENDER:$2|змяніў|змяніла}} бачнасць {{PLURAL:$5|запісу журнала|$5 запісаў журнала}} $3: $4",
        "logentry-delete-revision": "$1 {{GENDER:$2|змяніў|змяніла}} бачнасць {{PLURAL:$5|версіі|$5 версій|$5 версій}} старонкі $3: $4",
        "logentry-delete-event-legacy": "$1 {{GENDER:$2|змяніў|змяніла}} бачнасць запісаў журнала $3",
index b4b31f2..40b3be4 100644 (file)
        "savechanges": "Съхраняване на промените",
        "publishpage": "Публикуване на страницата",
        "publishchanges": "Публикуване на промените",
+       "savearticle-start": "Съхраняване на страницата...",
+       "savechanges-start": "Съхраняване на промените...",
+       "publishpage-start": "Публикуване на страницата...",
        "publishchanges-start": "Публикуване на промените...",
        "preview": "Предварителен преглед",
        "showpreview": "Предварителен преглед",
        "anoneditwarning": "<strong>Внимание:</strong> Не сте влезли в системата. Ако направите редакция IP-адресът Ви ще бъде публично видим. Ако <strong>[$1 влезете]</strong> или си <strong>[$2 създадете акаунт]</strong>, редакциите Ви ще бъдат свързани с потребителското Ви име, заедно с други преимущества.",
        "anonpreviewwarning": "<em>Не сте влезли в системата. Ако съхраните редакцията си, тя ще бъде записана в историята на страницата с вашия IP-адрес.</em>",
        "missingsummary": "<strong>Напомняне:</strong> Не е въведено кратко описание на промените.\nПри повторно натискане на бутона „$1“, редакцията ще бъде съхранена без резюме.",
+       "selfredirect": "<strong>Внимание:</strong> Пренасочвате страница към самата нея.\nМоже би сте посочили грешна цел за пренасочването или може би сте редактирали грешната страница.\nАко натиснете „$1“ отново, пренасочването ще бъде създадено.",
        "missingcommenttext": "Моля, въведете коментар.",
        "missingcommentheader": "<strong>Напомняне:</strong> Не е въведено заглавие на коментара.\nПри повторно натискане на „$1“, редакцията ще бъде записана без коментар.",
        "summary-preview": "Предварителен преглед на резюмето:",
        "blockedtitle": "Потребителят е блокиран",
        "blockedtext": "'''Вашето потребителско име (или IP-адрес) беше блокирано.'''\n\nБлокирането е извършено от $1. Посочената причина е: ''$2''\n\n*Начало на блокирането: $8\n*Край на блокирането: $6\n*Блокирането се отнася за: $7\n\nМожете да се свържете с $1 или с някой от останалите [[{{MediaWiki:Grouppage-sysop}}|администратори]], за да обсъдите блокирането.\n\nМожете да използвате услугата „Пращане писмо на потребител“ само ако не ви е забранена употребата ѝ и ако сте посочили валидна електронна поща в [[Special:Preferences|настройките]] си.\n\nВашият IP адрес е $3, а номерът на блокирането е $5. Включвайте едно от двете или и двете във всяко запитване, което правите.",
        "autoblockedtext": "IP-адресът ви беше блокиран автоматично, защото е бил използван от друг потребител, който е бил блокиран от $1.\nПосочената причина е:\n\n:''$2''\n\n* Начало на блокирането: $8\n* Край на блокирането: $6\n* Блокирането се отнася за: $7\n\nМожете да се свържете с $1 или с някой от останалите [[{{MediaWiki:Grouppage-sysop}}|администратори]], за да обсъдите блокирането.\n\nМожете да използвате услугата „Пращане писмо на потребител“ само ако не ви е забранена употребата ѝ и ако сте посочили валидна електронна поща в [[Special:Preferences|настройките]] си.\n\nТекущият ви IP-адрес е $3, а номерът на блокирането ви е $5. Включвайте ги във всяко питане, което правите.",
+       "systemblockedtext": "Вашето потребителско име или IP адрес беше автоматично блокирано от Медия Уики.\nПосочената причина е:\n\n:<em>$2</em>\n\n* Начало на блокирането: $8\n* Край на блокирането: $6\n* Блокирането се отнася за: $7\n\nВашият текущ IP адрес е $3.\nМоля, включете всичките детайли по-горе, ако правите каквито и да е запитвания.",
        "blockednoreason": "не е указана причина",
        "whitelistedittext": "Редактирането на страници изисква $1 в системата.",
        "confirmedittext": "Необходимо е да потвърдите електронната си поща, преди да редактирате страници.\nВъведете и потвърдете адреса си на [[Special:Preferences|страницата с настройките]].",
        "prefs-dateformat": "Формат на датата",
        "prefs-timeoffset": "Часово отместване",
        "prefs-advancedediting": "Общи настройки",
+       "prefs-developertools": "Инструменти за разработчици",
        "prefs-editor": "Редактор",
        "prefs-preview": "Преглед",
        "prefs-advancedrc": "Разширени настройки",
        "rcfilters-filter-humans-description": "Редакции, направени от редактори.",
        "rcfilters-filtergroup-reviewstatus": "Проверка на статуса",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Непатрулирано",
+       "rcfilters-filter-reviewstatus-manual-label": "Ръчно патрулирани",
+       "rcfilters-filter-reviewstatus-auto-label": "Автоматично патрулирани",
        "rcfilters-filtergroup-significance": "Значимост",
        "rcfilters-filter-minor-label": "Малки промени",
        "rcfilters-filter-minor-description": "Редакции, които не са отбелязани като малки промени.",
        "filedelete-intro-old": "Изтривате версията на <strong>[[Media:$1|$1]]</strong> към [$4 $3, $2].",
        "filedelete-comment": "Причина:",
        "filedelete-submit": "Изтриване",
-       "filedelete-success": "Файлът '''$1''' беше изтрит.",
+       "filedelete-success": "Файлът <strong>$1</strong> беше изтрит.",
        "filedelete-success-old": "Версията на <strong>[[Media:$1|$1]]</strong> към $3, $2 е била изтрита.",
        "filedelete-nofile": "Файлът <strong>$1</strong> не съществува.",
-       "filedelete-nofile-old": "Не съществува архивна версия на '''$1''' с указаните параметри.",
+       "filedelete-nofile-old": "Не съществува архивна версия на <strong>$1</strong> с указаните параметри.",
        "filedelete-otherreason": "Друга/допълнителна причина:",
        "filedelete-reason-otherlist": "Друга причина",
        "filedelete-reason-dropdown": "*Общи причини за изтриване\n** Нарушение на авторските права\n** Файлът се повтаря",
        "protect-othertime": "Друг срок:",
        "protect-othertime-op": "друг срок",
        "protect-existing-expiry": "Оставащо време: $2, $3",
-       "protect-existing-expiry-infinity": "Existing expiration time: безсрочно",
+       "protect-existing-expiry-infinity": "Оставащо време: безсрочно",
        "protect-otherreason": "Друга/допълнителна причина:",
        "protect-otherreason-op": "Друга причина",
        "protect-dropdown": "* Стандартни причини за защита на страници\n** Чест обект на вандализъм\n** Чест обект на спам\n** Редакторска война\n** Страница, изискваща много сървърни ресурси",
        "restriction-level-all": "всички",
        "undelete": "Преглед на изтрити страници",
        "undeletepage": "Преглед и възстановяване на изтрити страници",
-       "undeletepagetitle": "'''По-долу е показан списък на изтритите версии на [[:$1|$1]]'''.",
+       "undeletepagetitle": "<strong>По-долу е показан списък на изтритите версии на [[:$1|$1]]</strong>.",
        "viewdeletedpage": "Преглед на изтрити страници",
        "undeletepagetext": "{{PLURAL:$1|Следната страница беше изтрита, но все още се намира в архива и може да бъде възстановена|Следните $1 страници бяха изтрити, но все още се намират в архива и могат да бъдат възстановени}}. Архивът може да се почиства от време на време.",
        "undelete-fieldset-title": "Възстановяване на версии",
        "whatlinkshere": "Какво сочи насам",
        "whatlinkshere-title": "Страници, които сочат към „$1“",
        "whatlinkshere-page": "Страница:",
-       "linkshere": "Следните страници сочат към <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Няма страници, сочещи към <strong>[[:$1]]</strong>.",
-       "nolinkshere-ns": "Няма страници, сочещи към [[:$1]] в избраното именно пространство.",
+       "linkshere-2": "Следните страници сочат към <strong>$1</strong>:",
+       "nolinkshere-2": "Няма страници, сочещи към <strong>$1</strong>.",
+       "nolinkshere-ns-2": "Няма страници, сочещи към $1 в избраното именно пространство.",
        "isredirect": "пренасочваща страница",
        "istemplate": "включване",
        "isimage": "препратка към файла",
index 6c17aac..bbf7078 100644 (file)
        "whatlinkshere": "لینک په ای تاکدیما",
        "whatlinkshere-title": "تاکدیمان که گو  «$1» لینک دارنت",
        "whatlinkshere-page": "تاکدیم:",
-       "linkshere": "جهلگین دیم بئ  '''[[:$1]]''' ئا لینک داریت:",
-       "nolinkshere": "هیچ دیمی بئ  '''[[:$1]]''' ئا لینک نه داریت.",
-       "nolinkshere-ns": "هیچ دیمی شه انتخاب بوته ئین نامی فضائان بئ  '''[[:$1]]''' ئا لینک نداریت.",
+       "linkshere-2": "جهلگین دیم بئ  '''$1''' ئا لینک داریت:",
+       "nolinkshere-2": "هیچ دیمی بئ  '''$1''' ئا لینک نه داریت.",
+       "nolinkshere-ns-2": "هیچ دیمی شه انتخاب بوته ئین نامی فضائان بئ  '''$1''' ئا لینک نداریت.",
        "isredirect": "تاکدیمی تغییرمسیر داتین",
        "istemplate": "تراگنجانش‌هان",
        "isimage": "فایل لینک",
        "fileduplicatesearch-noresults": "فایلئ گو «$1» ئی ناما ودئ نه بوت.",
        "specialpages": "خاصین تاکدیمان",
        "specialpages-note-top": "شرح علائم",
+       "specialpages-note-restricted": "* عادی ئین خاصین تاکدیمان.\n* <span class=\"mw-specialpagerestricted\">خاصین تاکدیمان محدود بوته انت.</span>",
        "specialpages-group-maintenance": "ساتیتینئ راپور",
        "specialpages-group-other": "دیگه خاصین تاکدیمان",
        "specialpages-group-login": "داخل بوتین  / حسابي جوڑ کورتین",
index 5f90062..0468272 100644 (file)
        "whatlinkshere": "इहाँ का जुड़ल बा",
        "whatlinkshere-title": "पन्ना जेवन \"$1\" से जुड़ल बा",
        "whatlinkshere-page": "पन्ना:",
-       "linkshere": "<strong>[[:$1]]</strong> से नीचे दिहल पन्ना जुड़ल बाने:",
-       "nolinkshere": "'''[[:$1]]''' से कौनो पन्ना नइखे जुड़ल।",
-       "nolinkshere-ns": "चुनल गईल सन्दर्भ में '''[[:$1]]''' से कौनो पन्ना ना जुड़ेला।",
+       "linkshere-2": "<strong>$1</strong> से नीचे दिहल पन्ना जुड़ल बाने:",
+       "nolinkshere-2": "'''$1''' से कौनो पन्ना नइखे जुड़ल।",
+       "nolinkshere-ns-2": "चुनल गईल सन्दर्भ में '''$1''' से कौनो पन्ना ना जुड़ेला।",
        "isredirect": "अनुप्रेषित पन्ना",
        "istemplate": "ट्रांस्क्लूजन",
        "isimage": "फाइल कड़ी",
index 2615119..1e3d606 100644 (file)
        "whatlinkshere": "Tautan apa di sia",
        "whatlinkshere-title": "Tungkaran-tungkaran nang batautan ka ''$1''",
        "whatlinkshere-page": "Tungkaran:",
-       "linkshere": "Tungkaran-tungkaran barikut batautan ka '''[[:$1]]''':",
-       "nolinkshere": "Kadada tutungkaran tataut ka '''[[:$1]]'''.",
-       "nolinkshere-ns": "Kadada tutungkaran tataut ka '''[[:$1]]''' dalam ruang-ngaran nang dipilih.",
+       "linkshere-2": "Tungkaran-tungkaran barikut batautan ka '''$1''':",
+       "nolinkshere-2": "Kadada tutungkaran tataut ka '''$1'''.",
+       "nolinkshere-ns-2": "Kadada tutungkaran tataut ka '''$1''' dalam ruang-ngaran nang dipilih.",
        "isredirect": "tungkaran paugahan",
        "istemplate": "transklusi",
        "isimage": "tautan barakas",
        "fileduplicatesearch-result-n": "Barakas ''$1'' baisi {{PLURAL:$2|1 panggandaan parsis|$2 papanggandaan parsis}}.",
        "fileduplicatesearch-noresults": "Kadada barakas bangaran ''$1'' taugai.",
        "specialpages": "Tungkaran istimiwa",
+       "specialpages-note-restricted": "* Tutungkaran istimiwa normal\n* <span class=\"mw-specialpagerestricted\">Tutungkaran istimiwa tabatas.</span>\n* <span class=\"mw-specialpagecached\">Tutungkaran istimiwa timbuluk (pinanya bakulat).</span>",
        "specialpages-group-maintenance": "Lapuran pamaliharaan",
        "specialpages-group-other": "Tungkaran istimiwa lainnya",
        "specialpages-group-login": "Babuat log / mandaptar",
index 574950e..d92ed63 100644 (file)
        "subject-preview": "বিষয়ের প্রাকদর্শন:",
        "previewerrortext": "আপনার পরিবর্তনগুলি প্রাকদর্শন করার চেষ্টা করার সময় একটি ত্রুটি ঘটেছে।",
        "blockedtitle": "ব্যবহারকারীকে বাধা দেয়া হয়েছে",
-       "blockedtext": "<strong>আপনার ব্যবহারকারী নাম বা আইপি ঠিকানাটিকে সম্পাদনায় বাধাদান করা হয়েছে।</strong>\n\n$1 এই বাধাটি প্রদান করেছেন। বাধার কারণ হিসেবে বলা হয়েছে:<em>$2</em>।\n\n* বাধা শুরুর সময়: $8\n* বাধা উঠিয়ে নেয়ার সময়: $6\n* যাকে বাধাদান করা হয়েছে: $7\n\nআপনি $1 অথবা অন্য [[{{MediaWiki:Grouppage-sysop}}|প্রশাসকদের]] সাথে এই বাধা সংক্রান্ত বিষয়ে আলোচনা করতে পারেন।\n\nআপনি \"ইমেইল করুন\" বৈশিষ্ট্যটি ব্যবহার করতে পারবেন না যদি না আপনার [[Special:Preferences|অ্যাকাউন্টের পছন্দসমূহে]] একটি বৈধ ইমেইল ঠিকানা নির্দিষ্ট না করা হয়ে থাকে এবং আপনাকে এটি ব্যবহার করা থেকে অবরুদ্ধ না করা হয়ে থাকে।\n\nআপনার বর্তমান আইপি ঠিকানা হল $3, এবং আপনার বাধা নং হল #$5।\nদয়া করে আপনার যেকোন জিজ্ঞাসাতে উপরের সমস্ত বিবরণ অন্তর্ভুক্ত করুন।",
-       "autoblockedtext": "আপনার আইপি ঠিকানাটিকে স্বয়ংক্রিয়ভাবে সম্পাদনায় বাধাদান করা হয়েছে কারণ এমন আরেকজন ব্যবহারকারী এটি ব্যবহার করেছেন, যাকে $1 বাধা দিয়েছেন।\nযে কারণে বাধা দেওয়া হয়েছে সেটি হল:\n\n:<em>$2</em>\n\n* বাধা শুরুর সময়: $8\n* বাধা শেষের সময়: $6\n* যাকে বাধাদান করা হয়েছে: $7\n\nআপনি $1-এর সাথে কিংবা অন্য যেকোন [[{{MediaWiki:Grouppage-sysop}}|প্রশাসকের]] সাথে যোগাযোগ করে এই বাধা সংক্রান্ত বিষয়ে আলোচনা করতে পারেন।\n\nলক্ষ্য করুন, আপনি \"এই ব্যবহারকারীকে ই-মেইল করুন\" বৈশিষ্ট্যটি ব্যবহার করতে পারবেন না যদি না আপনার [[Special:Preferences|অ্যাকাউন্টের পছন্দসমূহে]] একটি বৈধ ইমেইল ঠিকানা নিবন্ধিত না থাকে এবং আপনাকে এটি ব্যবহার করা থেকে অবরুদ্ধ না করা হয়ে থাকে।\n\nআপনার বর্তমান আইপি ঠিকানা হচ্ছে $3, এবং বাধা নং হল #$5।\nদয়া করে আপনার যেকোন জিজ্ঞাসাতে উপরের সমস্ত বিবরণ অন্তর্ভুক্ত করুন।",
+       "blockedtext": "<strong>আপনার ব্যবহারকারী নাম বা আইপি ঠিকানাটিকে সম্পাদনায় বাধাদান করা হয়েছে।</strong>\n\n$1 এই বাধাটি প্রদান করেছেন। বাধার কারণ হিসেবে বলা হয়েছে:<em>$2</em>।\n\n* বাধা শুরুর সময়: $8\n* বাধা উঠিয়ে নেয়ার সময়: $6\n* যাকে বাধাদান করা হয়েছে: $7\n\nআপনি $1 অথবা অন্য [[{{MediaWiki:Grouppage-sysop}}|প্রশাসকদের]] সাথে এই বাধা সংক্রান্ত বিষয়ে আলোচনা করতে পারেন।\n\nআপনি \"{{int:emailuser}}\" বৈশিষ্ট্যটি ব্যবহার করতে পারবেন না যদি না আপনার [[Special:Preferences|অ্যাকাউন্টের পছন্দসমূহে]] একটি বৈধ ইমেইল ঠিকানা নির্দিষ্ট না করা হয়ে থাকে এবং আপনাকে এটি ব্যবহার করা থেকে অবরুদ্ধ না করা হয়ে থাকে।\n\nআপনার বর্তমান আইপি ঠিকানা হল $3, এবং আপনার বাধা নং হল #$5।\nদয়া করে আপনার যেকোন জিজ্ঞাসাতে উপরের সমস্ত বিবরণ অন্তর্ভুক্ত করুন।",
+       "autoblockedtext": "আপনার আইপি ঠিকানাটিকে স্বয়ংক্রিয়ভাবে সম্পাদনায় বাধাদান করা হয়েছে কারণ এমন আরেকজন ব্যবহারকারী এটি ব্যবহার করেছেন, যাকে $1 বাধা দিয়েছেন।\nযে কারণে বাধা দেওয়া হয়েছে সেটি হল:\n\n:<em>$2</em>\n\n* বাধা শুরুর সময়: $8\n* বাধা শেষের সময়: $6\n* যাকে বাধাদান করা হয়েছে: $7\n\nআপনি $1-এর সাথে কিংবা অন্য যেকোন [[{{MediaWiki:Grouppage-sysop}}|প্রশাসকের]] সাথে যোগাযোগ করে এই বাধা সংক্রান্ত বিষয়ে আলোচনা করতে পারেন।\n\nলক্ষ্য করুন, আপনি \"{{int:emailuser}}\" বৈশিষ্ট্যটি ব্যবহার করতে পারবেন না যদি না আপনার [[Special:Preferences|অ্যাকাউন্টের পছন্দসমূহে]] একটি বৈধ ইমেইল ঠিকানা নিবন্ধিত না থাকে এবং আপনাকে এটি ব্যবহার করা থেকে অবরুদ্ধ না করা হয়ে থাকে।\n\nআপনার বর্তমান আইপি ঠিকানা হচ্ছে $3, এবং বাধা নং হল #$5।\nদয়া করে আপনার যেকোন জিজ্ঞাসাতে উপরের সমস্ত বিবরণ অন্তর্ভুক্ত করুন।",
        "systemblockedtext": "আপনার ব্যবহারকারী নাম অথবা আইপি ঠিকানাটিকে স্বয়ংক্রিয়ভাবে মিডিয়াউইকি দ্বারা বাধাদান করা হয়েছে। যে কারণটি দেওয়া হয়েছে, সেটি হল:\n\n:<em>$2</em>\n\n* বাধা শুরুর সময়: $8\n* বাধা উঠিয়ে নেয়ার সময়: $6\n* যাকে বাধাদান করা হয়েছে: $7\n\nআপনার বর্তমান আইপি ঠিকানাটি হল $3।\nদয়া করে আপনার যেকোন জিজ্ঞাসাতে উপরের সমস্ত বিবরণ অন্তর্ভুক্ত করুন।",
        "blockednoreason": "কোন কারণ দেওয়া হয়নি",
        "whitelistedittext": "পাতায় সম্পাদনা করতে অনুগ্রহ করে $1 করুন।",
        "prefs-watchlist-edits": "নজরতালিকাতে দেখানোর জন্য সর্বাধিক পরিবর্তনের সংখ্যা:",
        "prefs-watchlist-edits-max": "সর্বোচ্চ সংখ্যা: ১০০০",
        "prefs-watchlist-token": "নজরতালিকা টোকেন:",
-       "prefs-watchlist-managetokens": "টোকেন পরিচালনা করুন",
+       "prefs-watchlist-managetokens": "টোকেনসমূহ পরিচালনা করুন",
        "prefs-misc": "বিবিধ",
        "prefs-resetpass": "পাসওয়ার্ড পরিবর্তন",
        "prefs-changeemail": "ইমেইল ঠিকানা পরিবর্তন বা বাতিল করুন",
        "prefs-dateformat": "তারিখ বিন্যাস",
        "prefs-timeoffset": "সময় অফসেট",
        "prefs-advancedediting": "সাধারণ পছন্দগুলি",
+       "prefs-developertools": "উন্নয়নকারীর সরঞ্জাম",
        "prefs-editor": "সম্পাদক",
        "prefs-preview": "প্রাকদর্শন",
        "prefs-advancedrc": "উচ্চতর পছন্দগুলি",
        "prefs-opt-out": "উন্নতি অনির্বাচন",
-       "prefs-advancedrendering": "à¦\89à¦\9aà§\8dà¦\9aতর à¦\85পশন",
+       "prefs-advancedrendering": "à¦\89à¦\9aà§\8dà¦\9aতর à¦¬à¦¿à¦\95লà§\8dপà¦\97à§\81লি",
        "prefs-advancedsearchoptions": "উচ্চতর পছন্দগুলি",
-       "prefs-advancedwatchlist": "à¦\89à¦\9aà§\8dà¦\9aতর à¦\85পশন",
+       "prefs-advancedwatchlist": "à¦\89à¦\9aà§\8dà¦\9aতর à¦¬à¦¿à¦\95লà§\8dপà¦\97à§\81লি",
        "prefs-displayrc": "প্রদর্শনীর পছন্দগুলি",
        "prefs-displaywatchlist": "প্রদর্শনী অপশন",
        "prefs-tokenwatchlist": "টোকেন",
        "userrights-cannot-shorten-expiry": "\"$1\" দলটির সদস্যতার মেয়াদোত্তীর্ণ হবার সময় ও তারিখ আপনি পূর্ববর্তী কোন সময়ে এগিয়ে নিয়ে আসতে পারবেন না। যেসব ব্যবহারকারীর এই দলটি যোগ বা অপসারণ করার অনুমতি আছে, কেবল তারাই মেয়াদোত্তীর্ণ হবার সময় ও তারিখ এগিয়ে নিয়ে আসতে পারবেন।",
        "userrights-conflict": "ব্যবহারকারী অধিকার দ্বন্দ্ব! অনুগ্রহ করে নিশ্চিত হোন এবং পুনরায় চেষ্টা করুন।",
        "group": "দল:",
-       "group-user": "ব্যবহারকারীগণ",
+       "group-user": "ব্যবহারকারী",
        "group-autoconfirmed": "স্বয়ংনিশ্চিতকৃত ব্যবহারকারী",
        "group-bot": "বট",
        "group-sysop": "প্রশাসক",
        "right-editcontentmodel": "পাতার তথ্যের ধরন সম্পাদনা করুন",
        "right-editinterface": "ব্যবহারকারী ইন্টারফেস সম্পাদনা",
        "right-editusercss": "অন্য ব্যবহারকারীগণের CSS ফাইল সম্পাদনা",
+       "right-edituserjson": "অন্য ব্যবহারকারীগণের JSON ফাইল সম্পাদনা",
        "right-edituserjs": "অন্য ব্যবহারকারীগণের JS ফাইল সম্পাদনা",
        "right-editmyusercss": "আপনার নিজস্ব ব্যবহারকারী সিএসএস ফাইল সম্পাদনা করুন",
+       "right-editmyuserjson": "আপনার নিজস্ব ব্যবহারকারী JSON ফাইল সম্পাদনা করা",
        "right-editmyuserjs": "আপনার নিজস্ব ব্যবহারকারী জাভাস্ক্রিপ্ট ফাইল সম্পাদনা করুন",
        "right-viewmywatchlist": "আপনার নজরতালিকা দেখুন",
        "right-editmywatchlist": "আপনার নজরতালিকা সম্পাদনা করুন। মনে রাখবেন, এই পরিবর্তনের পরও বিভিন্ন পাতা তালিকায় যুক্ত হয়ে থেতে পারে।",
        "recentchangeslinked-feed": "সম্পর্কিত পরিবর্তন",
        "recentchangeslinked-toolbox": "সম্পর্কিত পরিবর্তন",
        "recentchangeslinked-title": "\"$1\"-এর সাথে সম্পর্কিত পরিবর্তনসমূহ",
-       "recentchangeslinked-summary": "একটি পাতায় বা পাতা থেকে সংযুক্ত পাতাগুলির পরিবর্তন দেখতে একটি পাতার নাম লিখুন। (একটি বিষয়শ্রেণীর সদস্যদের দেখতে, বিষয়শ্রেণী:বিষয়শ্রেণীর নাম লিখুন)। আপনার [[Special:Watchlist|আপনার নজরতালিকায়]] রাখা পাতাগুলি <strong>গাঢ়</strong> করে দেখানো হয়েছে।",
+       "recentchangeslinked-summary": "একটি পাতায় বা পাতা থেকে সংযুক্ত পাতাগুলির পরিবর্তন দেখতে একটি পাতার নাম লিখুন। (একটি বিষয়শ্রেণীর সদস্যদের দেখতে, {{ns:category}}:বিষয়শ্রেণীর নাম লিখুন)। আপনার [[Special:Watchlist|আপনার নজরতালিকায়]] রাখা পাতাগুলি <strong>গাঢ়</strong> করে দেখানো হয়েছে।",
        "recentchangeslinked-page": "পাতার নাম:",
        "recentchangeslinked-to": "প্রদত্ত পাতায় সংযুক্ত আছে এমন পাতাগুলোর পরিবর্তন দেখাও",
        "recentchanges-page-added-to-category": "বিষয়শ্রেণীতে [[:$1]] যোগ করা হয়েছে",
        "protect-level-autoconfirmed": "শুধুমাত্র স্বয়ং পরীক্ষিত ব্যবহারকারীদের জন্য",
        "protect-level-sysop": "কেবল প্রশাসকদের জন্য অনুমতি",
        "protect-summary-cascade": "প্রপাতাকার",
-       "protect-expiring": "$1 (ইউটিসি) সময়ে মেয়াদোত্তীর্ণ",
+       "protect-expiring": "মেয়াদোত্তীর্ণ হবার তারিখ $1 (ইউটিসি)",
        "protect-expiring-local": "মেয়াদ উত্তীর্ণের সময় $1",
        "protect-expiry-indefinite": "অসীম",
        "protect-cascade": "এই পাতায় অন্তর্ভুক্ত পাতাগুলিও সুরক্ষিত করা হোক (প্রপাতাকার সুরক্ষা)",
        "whatlinkshere": "সংযোগকারী পাতাসমূহ",
        "whatlinkshere-title": "যে পাতাগুলি থেকে \"$1\"-এর প্রতি সংযোগ আছে",
        "whatlinkshere-page": "পাতা:",
-       "linkshere": "নিচের পাতাসমূহ '''[[:$1]]''' পাতায় সংযুক্ত আছে:",
-       "nolinkshere": "কোনো পাতা থেকে '''[[:$1]]''' পাতায় সংযোগ নেই।",
-       "nolinkshere-ns": "নির্বাচিত নামস্থানে '''[[:$1]]'''-এর প্রতি কোন পাতা থেকে সংযোগ নেই।",
+       "linkshere-2": "নিচের পাতাসমূহ '''$1''' পাতায় সংযুক্ত আছে:",
+       "nolinkshere-2": "কোনো পাতা থেকে '''$1''' পাতায় সংযোগ নেই।",
+       "nolinkshere-ns-2": "নির্বাচিত নামস্থানে '''$1'''-এর প্রতি কোন পাতা থেকে সংযোগ নেই।",
        "isredirect": "পুনর্নির্দেশ",
        "istemplate": "অন্তর্ভুক্তি",
        "isimage": "ফাইল সংযোগ",
        "undelete-cantcreate": "আপনি এই পাতাটি ফিরিয়ে আনতে পারবেন না কারণ এই নামে কোন পাতা বিদ্যমান নেই ও আপনার এই পাতাটি তৈরি করার অনুমতি নেই।",
        "pagedata-title": "পাতার উপাত্ত",
        "pagedata-not-acceptable": "কোন মিলে যাওয়া বিন্যাস পাওয়া যায় নি। সমর্থিত MIME ধরনগুলি হল: $1",
-       "pagedata-bad-title": "অপ্রযোজ্য শিরোনাম: \"$1\""
+       "pagedata-bad-title": "অপ্রযোজ্য শিরোনাম: \"$1\"",
+       "passwordpolicies-group": "দল",
+       "passwordpolicies-policies": "নীতিসমূহ",
+       "passwordpolicies-policy-minimalpasswordlength": "পাসওয়ার্ড অবশ্যই {{PLURAL:$1|১ অক্ষরের|$1 অক্ষরের}} হতে হবে"
 }
index 33a3f39..97cbed7 100644 (file)
        "whatlinkshere": "གང་དང་སྦྲེལ་བ།",
        "whatlinkshere-title": "\"$1\" ལ སྦྲེལ་ཡོད་པའི་ཤོག་ངོས།",
        "whatlinkshere-page": "ཤོག་ངོས།",
-       "linkshere": "གཤམ་གྱི་ཤོག་ངོས་རྣམས་ '''[[:$1]]''': ལ་སྦྲེལ་ཡོད།",
-       "nolinkshere": "<strong>[[:$1]]</strong> ཤོག་ངོས་གཅིག་ཀྱང་སྦྲེལ་མཐུད་མི་འདུག།",
+       "linkshere-2": "གཤམ་གྱི་ཤོག་ངོས་རྣམས་ '''$1''': ལ་སྦྲེལ་ཡོད།",
+       "nolinkshere-2": "<strong>$1</strong> ཤོག་ངོས་གཅིག་ཀྱང་སྦྲེལ་མཐུད་མི་འདུག།",
        "isimage": "ཡིག་རིས་སྦྲེལ་མཐུད།",
        "whatlinkshere-links": "← སྦྲེལ་མཐུད།",
        "whatlinkshere-hideredirs": "$1 ཁ་ཕྱོགས་བསྐྱར་སྟོན།",
index 476c3a2..f048f56 100644 (file)
        "whatlinkshere": "যে পাতাহানিত্ত এহানাত মিলাপ আসে",
        "whatlinkshere-title": "পাতাহানি $1 -ত মিলাপ আসে",
        "whatlinkshere-page": "পাতা:",
-       "linkshere": "থাঙনার পাতাহানি '''[[:$1]]'''র লগে মিলাপ আসে:",
-       "nolinkshere": "পাতা '''[[:$1]]'''হানাত কোন মিলাপ নেই।",
+       "linkshere-2": "থাঙনার পাতাহানি '''$1'''র লগে মিলাপ আসে:",
+       "nolinkshere-2": "পাতা '''$1'''হানাত কোন মিলাপ নেই।",
        "isredirect": "বুলনদের পাতা",
        "istemplate": "বরানি",
        "isimage": "ফাইল মিলাপ",
index 9fcfa2f..c59dffa 100644 (file)
        "whatlinkshere": "لینک های ای صفحه",
        "whatlinkshere-title": "صفحات آن لینک به \"$1\"",
        "whatlinkshere-page": "بألگە",
-       "linkshere": "لینک صفحات ذیل الذکر به '''[[:$1]]''':",
-       "nolinkshere": "هیچ صفحه ای پیوند نداردبه '''[[:$1]]'''.",
+       "linkshere-2": "لینک صفحات ذیل الذکر به '''$1''':",
+       "nolinkshere-2": "هیچ صفحه ای پیوند نداردبه '''$1'''.",
        "isredirect": "صفحه تغییر مسیر",
        "istemplate": "استفاده‌ وابیده داخل صفحه",
        "isimage": "جانیا هوم پیوند",
index a935884..48547d4 100644 (file)
        "whatlinkshere": "Pajennoù liammet",
        "whatlinkshere-title": "Pajennoù liammet ouzh \"$1\"",
        "whatlinkshere-page": "Pajenn :",
-       "linkshere": "Ar pajennoù a-is zo enno ul liamm a gas war-du '''[[:$1]]''':",
-       "nolinkshere": "N'eus pajenn ebet enni ul liamm war-du '''[[:$1]]'''.",
-       "nolinkshere-ns": "Pajenn ebet n'eo liammet ouzh '''[[:$1]]''' en esaouenn anv dibabet.",
+       "linkshere-2": "Ar pajennoù a-is zo enno ul liamm a gas war-du '''$1''':",
+       "nolinkshere-2": "N'eus pajenn ebet enni ul liamm war-du '''$1'''.",
+       "nolinkshere-ns-2": "Pajenn ebet n'eo liammet ouzh '''$1''' en esaouenn anv dibabet.",
        "isredirect": "pajenn adkas",
        "istemplate": "enframmet",
        "isimage": "Liamm war-zu ar restr",
        "fileduplicatesearch-noresults": "N'eus bet kavet restr ebet anvet \"$1\".",
        "specialpages": "Pajennoù dibar",
        "specialpages-note-top": "Alc'hwez",
+       "specialpages-note-restricted": "* Pajennoù dibar ordinal.\n* <span class=\"mw-specialpagerestricted\">Pajennoù dibar miret strizh.</span>",
        "specialpages-group-maintenance": "Rentaoù-kont trezalc'h",
        "specialpages-group-other": "Pajennoù dibar all",
        "specialpages-group-login": "Kevreañ / krouiñ ur gont",
index 125e3cb..f97f35a 100644 (file)
        "whatlinkshere": "Šta vodi ovamo",
        "whatlinkshere-title": "Stranice koje vode na \"$1\"",
        "whatlinkshere-page": "Stranica:",
-       "linkshere": "Sljedeće stranice vode na <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Nijedna stranica nije povezana sa <strong>[[:$1]]</strong>.",
-       "nolinkshere-ns": "Nijedna stranica nije povezana sa <strong>[[:$1]]</strong> u izabranom imenskom prostoru.",
+       "linkshere-2": "Sljedeće stranice vode na <strong>$1</strong>:",
+       "nolinkshere-2": "Nijedna stranica nije povezana sa <strong>$1</strong>.",
+       "nolinkshere-ns-2": "Nijedna stranica nije povezana sa <strong>$1</strong> u izabranom imenskom prostoru.",
        "isredirect": "preusmjerenje",
        "istemplate": "uključivanje",
        "isimage": "veza na datoteku",
        "fileduplicatesearch-noresults": "Nije pronađena datoteka s imenom \"$1\".",
        "specialpages": "Posebne stranice",
        "specialpages-note-top": "Legenda",
+       "specialpages-note-restricted": "* Normalne posebne stranice.\n* <strong class=\"mw-specialpagerestricted\">Zaštićene posebne stranice.</strong>",
        "specialpages-group-maintenance": "Izvještaji za održavanje",
        "specialpages-group-other": "Ostale posebne stranice",
        "specialpages-group-login": "Prijava / otvaranje računa",
diff --git a/languages/i18n/btm.json b/languages/i18n/btm.json
new file mode 100644 (file)
index 0000000..073808f
--- /dev/null
@@ -0,0 +1,579 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Simartampua"
+               ]
+       },
+       "sunday": "Akad",
+       "monday": "Sinayan",
+       "tuesday": "Salasa",
+       "wednesday": "Rabu",
+       "thursday": "Kamis",
+       "friday": "Jumahat",
+       "saturday": "Sabtu",
+       "sun": "Aka",
+       "mon": "Sin",
+       "tue": "Sal",
+       "wed": "Rab",
+       "thu": "Kam",
+       "fri": "Jum",
+       "sat": "Sab",
+       "january": "Januari",
+       "february": "Februari",
+       "march": "Maret",
+       "april": "April",
+       "may_long": "Mei",
+       "june": "Juni",
+       "july": "Juli",
+       "august": "Agustus",
+       "september": "September",
+       "october": "Oktober",
+       "november": "November",
+       "december": "Desember",
+       "january-gen": "Januari",
+       "february-gen": "Februari",
+       "march-gen": "Maret",
+       "april-gen": "April",
+       "may-gen": "Mei",
+       "june-gen": "Juni",
+       "july-gen": "Juli",
+       "august-gen": "Agustus",
+       "september-gen": "September",
+       "october-gen": "Oktober",
+       "november-gen": "November",
+       "december-gen": "Desember",
+       "jan": "Jan",
+       "feb": "Feb",
+       "mar": "Mar",
+       "apr": "Apr",
+       "may": "Mei",
+       "jun": "Jun",
+       "jul": "Jul",
+       "aug": "Agu",
+       "sep": "Sep",
+       "oct": "Okt",
+       "nov": "Nov",
+       "dec": "Des",
+       "pagecategories": "{{PLURAL:$1|Category|Kategori}}",
+       "category_header": "Alaman i kategori \"$1\"",
+       "subcategories": "Subkategori",
+       "category-media-header": "Media in jategori \"$1\"",
+       "category-empty": "<em>Kategori on sonnari indadong alaman dot media.</em>",
+       "hidden-categories": "{{PLURAL:$1|Hidden category|Kategori monjap}}",
+       "category-subcat-count": "{{PLURAL:$2|Kategori on umna puna subkategori ima.|Kategori on puna ima {{PLURAL:$1|subkategori|$1 subkategori}}, tingon bahat $2.}}",
+       "category-article-count": "{{PLURAL:$2|Kategori on umna marisi alaman ima.|Onma{{PLURAL:$1|alaman ima|$1 alaman}} i kategori on, tingon bahat $2.}}",
+       "category-file-count": "{{PLURAL:$2|Kategori on umna marisi alaman ima.|Onma{{PLURAL:$1|alaman ima|$1 alaman}} i kategori on, tingon bahat $2.}}",
+       "listingcontinuesabbrev": "Sat",
+       "broken-file-category": "Alaman dot link berkas sega",
+       "about": "Satontang",
+       "newwindow": "(bukak i tingkap nabaru)",
+       "cancel": "Antai",
+       "mytalk": "Dokon",
+       "navigation": "Navigasi",
+       "and": "&#32;dot",
+       "namespaces": "Namespaces",
+       "variants": "Mocoman",
+       "navigation-heading": "Menu Navigasi",
+       "returnto": "Keimulak tu $1",
+       "tagline": "Tingon {{SITENAME}}",
+       "help": "Tolong",
+       "search": "Jalaki",
+       "searchbutton": "Jalaki",
+       "searcharticle": "Kehe",
+       "history": "Sejarah alaman",
+       "history_short": "Sejarah",
+       "printableversion": "Versi cetak",
+       "permalink": "Tautan permanen",
+       "view": "Sise",
+       "view-foreign": "Sise i $1",
+       "edit": "Pature",
+       "create": "Baen",
+       "create-local": "Baen deskripsi lokal",
+       "delete": "Apus",
+       "newpage": "Alaman baru",
+       "talkpagelinktext": "Dokon",
+       "personaltools": "Alat pribadi",
+       "talk": "Marpokat",
+       "views": "Sise",
+       "toolbox": "Alat",
+       "otherlanguages": "I saro nalain",
+       "redirectedfrom": "(Ialihkon tingon $1)",
+       "redirectpagesub": "Alihkon alaman",
+       "redirectto": "Alihkon tu:",
+       "lastmodifiedat": "Alamanon parabisan ipature i $1, i $2.",
+       "jumpto": "Lumpat tu:",
+       "jumptonavigation": "navigasi",
+       "jumptosearch": "jalaki",
+       "aboutsite": "Satontang {{SITENAME}}",
+       "aboutpage": "Project:Satontang",
+       "copyrightpage": "{{ns:project}}:Hak cipta",
+       "currentevents": "Namasa sonnari",
+       "currentevents-url": "Project:Kajadian nabaru",
+       "disclaimers": "Panulakan",
+       "disclaimerpage": "Project:Panulakan umum",
+       "edithelp": "Bantuan pangeditan",
+       "mainpage": "Alaman Utamo",
+       "mainpage-description": "Alaman utamo",
+       "portal": "Portal komunitas",
+       "portal-url": "Project:Portal komunitas",
+       "privacy": "Kabijakan privasi",
+       "privacypage": "Project:Kabijakan privasi",
+       "retrievedfrom": "Dapot tingon \"$1\"",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|Amu puna}} $1 tingon {{PLURAL:$3|another user|$3 pamake}} ($2).",
+       "newmessageslinkplural": "{{PLURAL:$1|a new message|999=tona na baru}}",
+       "newmessagesdifflinkplural": "Parpudi {{PLURAL:$1|change|999=parubaan}}",
+       "editsection": "Pature",
+       "editold": "Pature",
+       "viewsourceold": "Sise sumber",
+       "editlink": "Pature",
+       "viewsourcelink": "Sise sumber",
+       "editsectionhint": "Pature bagian:$1",
+       "toc": "Isi",
+       "site-atom-feed": "$1 Umpan atom",
+       "page-atom-feed": "\"$1\" Umpan atom",
+       "red-link-title": "$1 (alaman inda adong)",
+       "nstab-main": "Alaman",
+       "nstab-user": "Alaman pamake",
+       "nstab-special": "Alaman istimewa",
+       "nstab-project": "Alaman proyek",
+       "nstab-image": "Berkas",
+       "nstab-mediawiki": "Tona",
+       "nstab-template": "Templat",
+       "nstab-category": "Kategori",
+       "mainpage-nstab": "Alaman utamo",
+       "nosuchspecialpage": "Inda adong alaman husus songon i",
+       "nospecialpagetext": "<strong>Amu madung mangido alaman husus naso valid.</strong>\n\nDaftar alaman husus bisa iligi i[[Special:SpecialPages|{{int:specialpages}}]].",
+       "badtitle": "Judul na jat",
+       "badtitletext": "Judul alaman na naipaido inda valid, kosong, sanga judul inter-sare sanga antar-wiki na sala ikaitkon. On mungkin marisi sada sanga lobi karakter na inda bisa ipake i judul.",
+       "viewsource": "Sise sumber",
+       "viewsource-title": "Sise sumber ni $1",
+       "viewsourcetext": "Amu bisa manyise dot mangkopi sumber ni alaman on",
+       "userlogin-yourname": "Gorar pamake",
+       "userlogin-yourname-ph": "Pamusuk gorar pamakemu",
+       "userlogin-yourpassword": "Hata kunci",
+       "userlogin-yourpassword-ph": "Pamasuk hata kunci",
+       "createacct-yourpassword-ph": "Pamasuk hata kunci",
+       "createacct-yourpasswordagain": "Konfirmasi hata kunci",
+       "createacct-yourpasswordagain-ph": "Pamasuk hata kunci mulak",
+       "userlogin-remembermypassword": "Jago totop masuk log",
+       "login": "Masuk",
+       "userlogin-noaccount": "Ulang adong akun",
+       "userlogin-joinproject": "Martop {{SITENAME}}",
+       "createaccount": "Baen akun",
+       "userlogin-resetpassword-link": "Lupa hata kuncimu?",
+       "userlogin-helplink2": "Tolong dot masuk log",
+       "createacct-emailoptional": "Alamat email (opsional)",
+       "createacct-email-ph": "Pamasuk alamat emailmu",
+       "createacct-submit": "Baen akunmu",
+       "createacct-benefit-heading": "{{SITENAME}} ibaen ni alak songon kamuon.",
+       "createacct-benefit-body1": "{{PLURAL:$1|edit|pature}}",
+       "createacct-benefit-body2": "{{PLURAL:$1|page|alaman}}",
+       "createacct-benefit-body3": "{{PLURAL:$1|contributor|kontributor}} baru",
+       "loginlanguagelabel": "Saro: $1",
+       "pt-login": "Masuk",
+       "pt-login-button": "Masuk log",
+       "pt-createaccount": "Baen akun",
+       "pt-userlogout": "Kaluar",
+       "botpasswords-label-needsreset": "(sandi porlu isitel mulak)",
+       "botpasswords-needs-reset": "Hata sandi bot tu gorar bot \"$2\" ni {{GENDER:$1|user}} \"$1\" angkon na isitel mulak.",
+       "passwordreset": "Gonti hata kunci",
+       "bold_sample": "Teks naapal",
+       "bold_tip": "Teks naapal",
+       "italic_sample": "Teks Italic",
+       "italic_tip": "Teks italic",
+       "link_sample": "Judul tautan",
+       "link_tip": "Pranala",
+       "extlink_sample": "http://www.example.com judul tautan",
+       "extlink_tip": "Tautan ruar (ingot http://prefix)",
+       "headline_sample": "Teks judul",
+       "headline_tip": "Judul tingkat 2",
+       "nowiki_sample": "Pamasuk teks naso iformat tuson",
+       "nowiki_tip": "Nangkon roaon pamformatan wiki",
+       "image_tip": "Berkas naisematkon",
+       "media_tip": "Tautan berkas",
+       "sig_tip": "Tekenanmu dot tando woktu",
+       "hr_tip": "Garis horizontal (pake dohot denggan)",
+       "summary": "Ringkasan:",
+       "minoredit": "On suntingan namenek",
+       "watchthis": "Pamatai alamanon",
+       "savearticle": "Simpan alaman",
+       "preview": "Cimak",
+       "showpreview": "Pitidaon pratayang",
+       "showdiff": "Patidaon parubaan",
+       "anoneditwarning": "<strong> Paringatan: </ strong> Amu indape masuk. Alamat IP Muyu nangkan tarida sacara publik molo Amu mambaen pangeditan. Molo Amu <strong> [$1 masuk] </ strong> sanga<strong> [$2 mambaen akun] </ strong>, hasil pangeditan Muyu nangkan ikaitkon dohot gorar pamake Muyu, rap dohot manfaat lainna.",
+       "blockedtext": "<strong>Alamat IP muyu madung iblokir sacara otomatis arani ipake ni pamake nalain,.</strong>\n\nNa iblokir ni $1.\nPamvlokiran ibaen arani <em>$2</em>.\n\n* Iblokir sian: $8\n* Blokir kadaluarsa i: $6\n* Sasarab pamblokiran: $7\n\nAmu bisa mayapai $1 sanga [[{{MediaWiki:Grouppage-sysop}}|administrator]] lainna tuna mamokatkon hal on.\n\nAmu inda bisa mamake fitur \"{{int:emailuser}}\" kacuali amu madung mamasukkon alamat surel na sah i [[Special:Preferences|preferensi akun]] dot amu inda iblokir mamakena.\n\nAlama IP muyu saonnari ima $3, dot ID pamblokiran ima #$5.\nTolong baen informasi-informasi in i satiop parsapaan muyu.",
+       "autoblockedtext": "Alamat IP mu nangkan otomatis iblokir arani ipake pamake nalain, na madung iblokir ni $1.\nAlasanna ima:\n\n:<em>$2</em>\n\n* Muloi i blokir: $8\n* Kadaluarsa blokir: $6\n* Blokir na ituju: $7\n\nSapai amuma $1 sanga sada tingon nalainnai [[{{MediaWiki:Grouppage-sysop}}|administrators]] giot mamokatkon blokiran on.\n\nRoaon molo Amu inda tola mamake fitur \"{{int: emailuser}}\" kacuali Amu puna alamat surel valid na tardaftar i [[Special:Preferences|preferensi pamake]] dot Amu indape iblokir mamakena.\n\nAlamat IP mu sonnari ima $3, dot blokir ID ima #$5.\nIaropkon baen sude rincian na iginjang singkop molo mambaen parsaapaan na ibaen muyu.",
+       "loginreqlink": "Masuk",
+       "newarticletext": "Amu madung paiut tautan tu alaman na so adong dope. Giot mambaen alaman, muloima mangetik i kotak i toru on (ligin [$1 alaman bantuan] giot info lobi lanjut). Molo Amu adong i son arani kasalahan, klik tombol <strong> back </ strong> i browser Muyu.\n\nTERJEMAHKAN",
+       "noarticletext": "Saonnari inda adong teks i alaman on. Amu bisa [[Special:Search/{{PAGENAME}}|manjalai judul alaman on]] i alaman lain, <span class = \"plainlinks\"> [{{fullurl: {{# Special: Log}} | page = { {FULLPAGENAMEE}}}} telusuri log terkait], atau [{{fullurl: {{FULLPAGENAME}} | action = edit}} baen alaman on] </ span>.",
+       "noarticletext-nopermission": "Saonnari inda adong teks i alaman on. Amu bisa [[Special:Search/{{PAGENAME}}|manjalai judul alaman on]] i alaman lain, sanga <span class = \"plainlinks\"> [{{fullurl:{{#Special:Log}}|alaman={{FULLPAGENAMEE}}}} jalai log tarkait] </ span>, tai Amu inda puna izin giot mambaen alaman on.",
+       "userpage-userdoesnotexist-view": "Akun pangguna ''$1'' inda tardaftar",
+       "editing": "Mangedit $1",
+       "creating": "Baen $1",
+       "editingsection": "Patureon $1 (bagian)",
+       "templatesused": "{{PLURAL:$1|Template|Templat}} baen tu alaman on:",
+       "template-protected": "Larangan",
+       "template-semiprotected": "(satonga-larangan)",
+       "hiddencategories": "Alaman on ima anggota {{PLURAL:$1|1 kategori namonjap|$1 kategori namonjap}}:",
+       "permissionserrors": "Santabi sega",
+       "permissionserrorstext-withaction": "Amu inda iizinkon $2, tu naonan {{PLURAL:$1|reason|alasan}}:",
+       "moveddeleted-notice": "Alaman on nangkan iapus. \nCatatan pangapusan, palarangan, dot pamindahan tu alaman ilehen i toru on manjadi referensi.",
+       "content-model-wikitext": "Tekswiki",
+       "viewpagelogs": "Sise log ni alaman on",
+       "currentrev-asof": "Parubaan parpudi ima $1",
+       "revisionasof": "Revisi par $1",
+       "revision-info": "Revisi par $1 by {{GENDER:$6|$2}}$7",
+       "previousrevision": "← Revisi na lobi onok",
+       "nextrevision": "Revisi tarbaru →",
+       "currentrevisionlink": "Revisi parpudi",
+       "cur": "Sonnari",
+       "last": "Cimak",
+       "histlegend": "Seleksi Diff: Tandai kotak radio tingon revisi giot mambandingkon dot pisat enter sanga tombol naitoru.<br />\nLegend: <strong>({{int:cur}})</strong> = parbedaan dohot revisi tarbaru, <strong>({{int:last}})</strong> = parbedaan dohot revisi naparjolo, <strong>{{int:minoreditletter}}</strong> = pengeditan menek.",
+       "history-fieldset-title": "Jalai revisi",
+       "histfirst": "Naonok",
+       "histlast": "Nabaru",
+       "history-feed-title": "Sejarah revisi",
+       "history-feed-description": "Sejarah revisi tu alaman i wiki",
+       "history-feed-item-nocomment": "$1 i $2",
+       "rev-delundel": "Uba visibilitas",
+       "history-title": "Sejarah Revisi ni \"$1\"",
+       "difference-title": "Parbedaan antara revisi \"$1\"",
+       "lineno": "Baris $1:",
+       "compareselectedversions": "Bandingkon dot revisi tarpili",
+       "editundo": "Mambuka",
+       "diff-multi-sameuser": "({{PLURAL:$1|Sada revisi manonga|$1 revisi manonga}} ni pangguna na sarupo inda ipatidaon)",
+       "searchresults": "Jalaki sude hasil",
+       "searchresults-title": "Jalaki sude hasil tu \"$1\"",
+       "prevn": "Cimak {{PLURAL:$1|$1}}",
+       "nextn": "Satorusna {{PLURAL:$1|$1}}",
+       "prevn-title": "Cimak $1 {{PLURAL:$1|result|hasil}}",
+       "nextn-title": "Satorusna $1 {{PLURAL:$1|result|hasil}}",
+       "shown-title": "Patidaon $1 {{PLURAL:$1|result|hasil}} par alaman",
+       "viewprevnext": "Sise ($1 {{int:pipe-separator}} $2) ($3)",
+       "searchmenu-exists": "<strong>Adong gorar ni alaman \"[[:$1]]\" i wiki on.</strong> {{PLURAL:$2|0=|Ligin juo panjalakan napasuo.}}",
+       "searchmenu-new": "<strong> Baen alaman \"[[:$1]]\" i wiki on! </strong> {{PLURAL:$2|0=|Ligin juo alaman na dapot dohot panjalakan Muyu.|Ligin juo hasil panjalakan na dapot.}}",
+       "searchprofile-articles": "Isi nialaman",
+       "searchprofile-images": "Multimedia",
+       "searchprofile-everything": "Sanga aha",
+       "searchprofile-advanced": "Torus",
+       "searchprofile-articles-tooltip": "Jalaki i $1",
+       "searchprofile-images-tooltip": "Jalai berkas",
+       "searchprofile-everything-tooltip": "Jalai sude tontang (ibagasan alaman parpokatan)",
+       "searchprofile-advanced-tooltip": "Jalaki i ruang gorar kustom",
+       "search-result-size": "$1 ({{PLURAL:$2|1 word|$2 hata}})",
+       "search-result-category-size": "{{PLURAL:$1|1 member|$1 anggota}} ({{PLURAL:$2|1 subcategory|$2 subkategori}}, {{PLURAL:$3|1 file|$3 berkas}})",
+       "search-redirect": "(alihkon tingon $1)",
+       "search-section": "(bagian $1)",
+       "search-file-match": "(isi berkas na cocok)",
+       "search-suggest": "On do na imaksudmi:$1",
+       "searchall": "Sude",
+       "search-showingresults": "{{PLURAL:$4|Hasil<strong>$1</strong> tingon <strong>$3</strong>|Hasil <strong>$1 – $2</strong> tingon <strong>$3</strong>}}",
+       "search-nonefound": "Inda adong hasil na cocok dohot kueri.",
+       "mypreferences": "Preferensi",
+       "group-bot": "Bot",
+       "group-sysop": "Administrator",
+       "grouppage-bot": "{{ns:project}}:Bot",
+       "right-writeapi": "Pamakean ni API tulis",
+       "newuserlogpage": "Log pambaenan pamake",
+       "action-edit": "Pature alaman on",
+       "action-createaccount": "baen akun pamake on",
+       "enhancedrc-history": "sejarah",
+       "recentchanges": "Parubaan tarbaru",
+       "recentchanges-legend": "Opsi parubaan tarbaru",
+       "recentchanges-summary": "Lacak parubaan tarbaru i wiki i alaman on.",
+       "recentchanges-noresult": "Inda adong parubaan saonok periode na ilehen sasuae dohot kriteria on.",
+       "recentchanges-feed-description": "Jalaki parubaan tarbaru i wiki i umpan on.",
+       "recentchanges-label-newpage": "Patureon on mammbaen alaman baru",
+       "recentchanges-label-minor": "On pature na menek",
+       "recentchanges-label-bot": "Naipature ni bot",
+       "recentchanges-label-unpatrolled": "Suntingan on indape ipareso",
+       "recentchanges-label-plusminus": "Ukuran alamanon iuba dohot bahatni byte",
+       "recentchanges-legend-heading": "<strong>tarombo:</strong>",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ligin juo [[Special:NewPages|daftar alaman nabaru]])",
+       "rcnotefrom": "Itoru {{PLURAL:$5|is the change|ima parubaan}} saonok<strong>$3, $4</strong> (sampe tu <strong>$1</strong> patidaon).",
+       "rclistfrom": "Patidaon parubaan tarbaru imuloi tingon $2, $3",
+       "rcshowhideminor": "$1 pature namenek",
+       "rcshowhideminor-show": "Patidaon",
+       "rcshowhideminor-hide": "Bunion",
+       "rcshowhidebots": "$1 bot",
+       "rcshowhidebots-show": "Patidaon",
+       "rcshowhidebots-hide": "Bunion",
+       "rcshowhideliu": "$1 pamake tardaftar",
+       "rcshowhideliu-show": "Patidaon",
+       "rcshowhideliu-hide": "Bunion",
+       "rcshowhideanons": "$1 pamake anonim",
+       "rcshowhideanons-show": "Patidaon",
+       "rcshowhideanons-hide": "Bunion",
+       "rcshowhidemine": "$1 naupature",
+       "rcshowhidemine-show": "Patidaon",
+       "rcshowhidemine-hide": "Bunion",
+       "rclinks": "Patidaon sude $1 parubaan $2 ari",
+       "diff": "diff",
+       "hist": "hist",
+       "hide": "Bunion",
+       "show": "Alaman pamake",
+       "minoreditletter": "m",
+       "newpageletter": "B",
+       "boteditletter": "b",
+       "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} sidung maruba",
+       "recentchangeslinked": "Parubaan tarkait",
+       "recentchangeslinked-feed": "Parubaan tarkait",
+       "recentchangeslinked-toolbox": "Parubaan tarkait",
+       "recentchangeslinked-title": "Parubaan tarkait tu \"$1\"",
+       "recentchangeslinked-summary": "Pamasuk gorar alaman giot maligi parubaaan i alaman na tarsambung tu sanga tingon alaman i. (Giot mangaligi anggota kategori, pamasuk {{ns: category}}: Gorar kategori). Parubaan i alaman [[Special:Watchlist|Daftar Naipamatai mu]] adong i <strong> bold </ strong>.",
+       "recentchangeslinked-page": "Gorar alaman:",
+       "recentchangeslinked-to": "Patidaon parubaaan tu alaman na itautkon tu alaman na baen",
+       "upload": "Unggah berkas",
+       "uploadlogpage": "Unggah log",
+       "filedesc": "Ringkasan",
+       "license": "Ilisensi",
+       "license-header": "Lisensi",
+       "imgfile": "Berkas",
+       "listfiles": "Daftar berkas",
+       "file-anchor-link": "Berkas",
+       "filehist": "Sejarah berkas",
+       "filehist-help": "Klik tanggal / woktu giot maligi file songon na na i woktu i.",
+       "filehist-current": "Saonnari",
+       "filehist-datetime": "Tangagal/Woktu",
+       "filehist-thumb": "Thumbnail",
+       "filehist-thumbtext": "Thumbnail tu versi par $1",
+       "filehist-user": "Pamake",
+       "filehist-dimensions": "Ukuran",
+       "filehist-comment": "Komentar",
+       "imagelinks": "Berkas ipake",
+       "linkstoimage": "Namamatai {{PLURAL:$1|page links|$1 tautan alaman}} tu berkas on:",
+       "nolinkstoimage": "Inda adong alaman na martaut tu berkason",
+       "sharedupload-desc-here": "File on tingon $1 dot bisa ipake ni proyek lain. Deskripsi i [alaman deskripsi file $2] i sadun ipatidaon naitoruon.",
+       "upload-disallowed-here": "Amu inda bisa manimpo berkas on.",
+       "randompage": "Gaor alaman",
+       "statistics": "Statistik",
+       "nbytes": "$1 {{PLURAL:$1|byte|bytes}}",
+       "nmembers": "$1 {{PLURAL:$1|member|members}}",
+       "prefixindex": "Sude alaman na prefix",
+       "listusers": "Daptar pamake",
+       "newpages": "Alaman baru",
+       "move": "Pindah",
+       "pager-newer-n": "{{PLURAL:$1|newer 1|nabaru $1}}",
+       "pager-older-n": "{{PLURAL:$1|older 1|parpudi $1}}",
+       "booksources": "Sumber buku",
+       "booksources-search-legend": "Jalai tu sumber buku",
+       "booksources-search": "Jalai",
+       "log": "Masuk",
+       "all-logs-page": "Sude log",
+       "logempty": "Inda adong item nacocok i log",
+       "allpages": "Sude alaman",
+       "allarticles": "Sude alaman",
+       "allpagessubmit": "Kehe",
+       "allpages-hide-redirects": "Bunion pangalihan",
+       "categories": "Kategori",
+       "emailuser": "Email ni pamake on",
+       "usermessage-editor": "Tona ni sistem",
+       "watchlist": "Pamataan",
+       "mywatchlist": "Pamatai",
+       "watchlistfor2": "Tu $1 $2",
+       "watch": "Pamatai",
+       "unwatch": "Inda ipamatai",
+       "watchlist-details": "{{PLURAL:$1|$1 page is|$1 alaman}} i pamataanmu (dot alaman parkobaran).",
+       "wlshowlast": "Patidaon parpudi $1 jom $2 ari",
+       "watchlist-options": "Opsi pamataan",
+       "enotif_reset": "Tandai sude alaman namadung iligi",
+       "dellogpage": "Apus log",
+       "rollbacklink": "balikkon",
+       "rollbacklinkcount": "Paulak $1 {{PLURAL:$1|edit|edits}}",
+       "protectlogpage": "Log nai jago",
+       "protectedarticle": "larangan \"[[$1]]\"",
+       "protect-default": "Patola sude pangguna",
+       "restriction-edit": "Pature",
+       "restriction-move": "Pindah",
+       "namespace": "Namespace:",
+       "invert": "Pilian sabalikna",
+       "tooltip-invert": "Centang kotak on giot mambunion parubaan tu alaman i ruang gorar na ipili (dot ruang girar tarkait molo icentang)",
+       "namespace_association": "Kumpulan ruang gorar",
+       "tooltip-namespace_association": "Centang kotak on giot mambunion ruang gorar pangecean sanga subjek na tarkait dohot ruang gorar na ipili",
+       "blanknamespace": "(Utamo)",
+       "contributions": "{{GENDER:$1|User}} kontribusi",
+       "contributions-title": "Kontribusi pannguna tu $1",
+       "mycontris": "Kontribusi",
+       "anoncontribs": "Kontribusingku",
+       "contribsub2": "Tu {{GENDER:$3|$1}} ($2)",
+       "uctop": "(sonnari)",
+       "month": "Tingon bulan (dot nasolpu)",
+       "year": "Tingon taon (dot nasolpu)",
+       "sp-contributions-newbies": "Patidaon kontribusi ni akun nabaru sajope",
+       "sp-contributions-blocklog": "Log blokir",
+       "sp-contributions-uploads": "Unggah",
+       "sp-contributions-logs": "Log",
+       "sp-contributions-talk": "Dokon",
+       "sp-contributions-search": "Jalaki kontribusi",
+       "sp-contributions-username": "Alama IP Pangguna",
+       "sp-contributions-toponly": "Umna patidaon editan revisi parpudi",
+       "sp-contributions-newonly": "Umna patidaon alaman naibuat",
+       "sp-contributions-submit": "Jalaki",
+       "whatlinkshere": "Tautan aha ison",
+       "whatlinkshere-title": "Alaman puna tautan tu \"$1\"",
+       "whatlinkshere-page": "Alaman:",
+       "linkshere-2": "Onma alaman namartaut tu <strong>$1</strong>:",
+       "nolinkshere-2": "Inda adong alaman na martaut tu <strong>$1</strong>.",
+       "isredirect": "Alaman pangalihan",
+       "istemplate": "transklusi",
+       "isimage": "Tautan berkas",
+       "whatlinkshere-prev": "{{PLURAL:$1|previous|parjolo $1}}",
+       "whatlinkshere-next": "{{PLURAL:$1|next|satorusna $1}}",
+       "whatlinkshere-links": "← tautan",
+       "whatlinkshere-hideredirs": "$1 ialihkon",
+       "whatlinkshere-hidetrans": "$1 transklusi",
+       "whatlinkshere-hidelinks": "$1 tautan",
+       "whatlinkshere-hideimages": "$1 tautan berkas",
+       "whatlinkshere-filters": "Saringan",
+       "ipboptions": "2 jom:2 hours,1 ari:1 day,3 ari:3 days,1 poken:1 week,2 poken:2 weeks,1 bulan:1 month,3 bulan:3 months,6 bulan:6 months,1 taon:1 year,onok:infinite",
+       "blocklink": "blokir",
+       "contribslink": "Kontributor",
+       "blocklogpage": "Blokir log",
+       "blocklogentry": "blokir [[$1]] dot woktu kadaluarsa $2 $3",
+       "proxyblocker": "Blokir proxi",
+       "movelogpage": "Pindah log",
+       "export": "Expor alaman",
+       "thumbnail-more": "Pagodang",
+       "importlogpage": "Log impor",
+       "tooltip-pt-userpage": "{{GENDER:|Your user}} alaman",
+       "tooltip-pt-mytalk": "{{GENDER:|Your}} alaman parkobaran",
+       "tooltip-pt-preferences": "{{GENDER:|Your}} preferensi",
+       "tooltip-pt-watchlist": "Daftar nialaman na parubaanna ipamataimu",
+       "tooltip-pt-mycontris": "Daftar {{GENDER:|your}} kontribusi",
+       "tooltip-pt-login": "Amu iaropkon masuk, tai inda wajib",
+       "tooltip-pt-logout": "Kaluar",
+       "tooltip-pt-createaccount": "Amu iaropkon mambaen akun dot masuk; taiba, i inda wajib",
+       "tooltip-ca-talk": "Pokat satontang isi ni alaman",
+       "tooltip-ca-edit": "Pature alamanon",
+       "tooltip-ca-addsection": "Baen bagian nabaru",
+       "tooltip-ca-viewsource": "Alaman on ilarang.\nAmu bisa manyise sumber",
+       "tooltip-ca-history": "Revisi parpudi ni alaman on",
+       "tooltip-ca-protect": "Jago alamanon",
+       "tooltip-ca-delete": "Apus alaman on",
+       "tooltip-ca-move": "Papindah alamanon",
+       "tooltip-ca-watch": "Baen alamanon tu pangawasanmu",
+       "tooltip-ca-unwatch": "Apus alaman on tingon pamataanmu",
+       "tooltip-search": "Jalaki {{SITENAME}}",
+       "tooltip-search-go": "Kehe tu alaman dohot gorar naonan molo adong.",
+       "tooltip-search-fulltext": "Jalaki alaman tu teks on",
+       "tooltip-p-logo": "Ligin alaman utamo",
+       "tooltip-n-mainpage": "Kehe tu alaman utamo",
+       "tooltip-n-mainpage-description": "Kei tu alaman utamo",
+       "tooltip-n-portal": "Satontang proyek, aha ma bisa ibaen kamu, anso dapot",
+       "tooltip-n-currentevents": "Jalai latar bolakang satontang kajadian tarbaru",
+       "tooltip-n-recentchanges": "Daftar parubaan tarbaru i Wikion",
+       "tooltip-n-randompage": "Muat alaman sumbarang",
+       "tooltip-n-help": "Inganan anso binoto",
+       "tooltip-t-whatlinkshere": "Daftar alaman wiki na martaut tuson",
+       "tooltip-t-recentchangeslinked": "Parubaan tarbaru i sude alaman namartautan tingon alaman on",
+       "tooltip-feed-atom": "Umpan atom ni alamaon",
+       "tooltip-t-contributions": "Daftar kontribusi ni {{GENDER:$1|pamake on}}",
+       "tooltip-t-emailuser": "Kirim email tu {{GENDER:$1|pamake on}}",
+       "tooltip-t-upload": "Unggah berkas-berkas",
+       "tooltip-t-specialpages": "Daftar ni sude alaman spesial",
+       "tooltip-t-print": "Versi cetak ni alamanon",
+       "tooltip-t-permalink": "Tautan permanen tu revisi ni alamanon",
+       "tooltip-ca-nstab-main": "Sise isi ni alaman",
+       "tooltip-ca-nstab-user": "Sise alaman pamake",
+       "tooltip-ca-nstab-special": "On alaman spesial, dot on inda bisa ipature",
+       "tooltip-ca-nstab-project": "Sise alaman proyek",
+       "tooltip-ca-nstab-image": "Sise alaman berkas",
+       "tooltip-ca-nstab-mediawiki": "Sise sistem tona",
+       "tooltip-ca-nstab-template": "Sise templat",
+       "tooltip-ca-nstab-category": "Sise kategori ni alaman",
+       "tooltip-minoredit": "Tandai on pangeditan namenek",
+       "tooltip-save": "Simpan parubaanmu",
+       "tooltip-preview": "Pareso naiubamu. Pake jolo on dompak so isimpan",
+       "tooltip-diff": "Patidaon sanga dia teks naiubamu",
+       "tooltip-compareselectedversions": "Ligin parbedaan antara dua revisi naipili ni alaman on",
+       "tooltip-watch": "Baen alamanon tu pamataanmu",
+       "tooltip-rollback": "\"Balikkon\" paulak pangedit kontributor parpudi tu alaman on dohot sa klik",
+       "tooltip-undo": "\"Undo\" pamulak pangeditan on dot mambuka formulir edit i mode pratinjau. On mamungkinkon manambaon alasan i ringkasan.",
+       "tooltip-summary": "Baen ringkasan pondok",
+       "simpleantispam-label": "Pareso Anti-spam.\nBaen <strong>inda</strong> isi ison!",
+       "pageinfo-title": "Informasi tu ''$1''",
+       "pageinfo-header-basic": "Informasi dasor",
+       "pageinfo-header-edits": "Sejarah edit",
+       "pageinfo-header-restrictions": "Alaman larangan",
+       "pageinfo-header-properties": "Parkuas alaman",
+       "pageinfo-display-title": "Judul tampilan",
+       "pageinfo-default-sort": "Kunci panyortiran default",
+       "pageinfo-length": "Lanjang alaman (i byte)",
+       "pageinfo-article-id": "ID alaman",
+       "pageinfo-language": "Bahasa isi ni alaman",
+       "pageinfo-content-model": "Model konten alaman",
+       "pageinfo-robot-policy": "Pangindeksan ni robot",
+       "pageinfo-watchers": "Bahatni alaman naipamatai",
+       "pageinfo-redirects-name": "Bahatni pangalihan tu alaman on",
+       "pageinfo-firstuser": "Pambaen alaman",
+       "pageinfo-firsttime": "Tanggal ibaen alaman",
+       "pageinfo-edits": "Bahat ni edit",
+       "pageinfo-hidden-categories": "Bunion {{PLURAL:$1|category|Kategori}} ($1)",
+       "pageinfo-templates": "Transclusi {{PLURAL:$1|template|templat}} ($1)",
+       "pageinfo-toolboxlink": "Informasi alaman",
+       "pageinfo-contentpage": "Ietong manjadi sada alaman",
+       "pageinfo-contentpage-yes": "Olo",
+       "patrol-log-page": "Log patroli",
+       "previousdiff": "← editan nasolpu",
+       "nextdiff": "Edit tarbaru →",
+       "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|page|alaman}}",
+       "file-info-size": "$1 × $2 piksel, ukuran berkas: $3, Type MIME: $4",
+       "file-nohires": "Indadongbe resolusi naum ginjang",
+       "svg-long-desc": "Berkas SVG, nominall $1 × $2 piksel, ukuran berkas: $3",
+       "show-big-image": "Berkas asli",
+       "show-big-image-preview": "Ukuran ni pratayang:$1",
+       "show-big-image-other": "Lainna {{PLURAL:$2|resolution|resolusi}}: $1.",
+       "show-big-image-size": "$1 × $2 piksel",
+       "metadata": "Metadata",
+       "metadata-help": "Berkas on marisi informasi tambahan, mungkin itambaon tingon kamera digital sanga pamindai na ipake tu mambaen sanga mandigitalkonna. Molo berkas madung imodifikasi tingon kaadaan aslina, sadebana detail mungkin inda sudena mancerminkon berkas na imodifikasi.",
+       "metadata-fields": "Bidang metadata gambar na tarcantum i tona on nangkan ibaenkon i tampilan alaman gambar atia tabel metadata iciutkon. \nNalain nangkan ibunion sacara default.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "exif-orientation": "Orientasi",
+       "exif-xresolution": "Resolusi horizontal",
+       "exif-yresolution": "Resolusi vertikal",
+       "exif-datetime": "Parubaan tanggal dot woktu berkas",
+       "exif-make": "Pambaen kamera",
+       "exif-model": "Model kamera",
+       "exif-software": "Perangkat lunak nai pake",
+       "exif-exifversion": "Model Exif",
+       "exif-colorspace": "Ruang warna",
+       "exif-datetimeoriginal": "Tanggal dot waktu pambuatan data",
+       "exif-datetimedigitized": "Tanggal dot woktu idigitalisasi",
+       "exif-orientation-1": "Biaso",
+       "namespacesall": "Sude",
+       "monthsall": "Sude",
+       "imgmultipagenext": "alaman satorusna →",
+       "imgmultigo": "Kei!",
+       "imgmultigoto": "Kei tu alaman $1",
+       "watchlisttools-clear": "Paias pamataan",
+       "watchlisttools-view": "Sise parubaan na pas",
+       "watchlisttools-edit": "Sise dot pature pamataan",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|obarkon]])",
+       "redirect": "Pangalihan ni berkas, pamake, alaman, revisi, sanga log ID",
+       "redirect-summary": "Alaman husus on mangalihkon tu berkas (ilehen gorar berkas), alaman (ilehen ID revisi sanga ID alaman), alaman pangguna (ilehen ID pangguna numerik), sanga entri log (ilehen ID log). Pamakean:\n[[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], sanga [[{{#Special:Redirect}}/logid/186]].",
+       "redirect-submit": "Kei",
+       "redirect-lookup": "Ligima:",
+       "redirect-value": "Nilai:",
+       "redirect-user": "ID pangguna",
+       "redirect-page": "ID alaman",
+       "redirect-revision": "Revisi alaman",
+       "redirect-file": "Gorarberkas:",
+       "specialpages": "Alaman Spesial",
+       "tag-filter": "[[Special:Tags|Tag]] saring:",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag|Tags}}]]: $2)",
+       "tags-active-yes": "Olo",
+       "tags-active-no": "Inda",
+       "tags-hitcount": "$1 {{PLURAL:$1|change|parubaan}}",
+       "logentry-delete-delete": "$1 {{GENDER:$2|iapus}} alaman $3",
+       "logentry-delete-revision": "$1 {{GENDER:$2|iuba}} visibilitas {{PLURAL:$5|a revision|$5 revisi}} i alaman $3: $4",
+       "revdelete-content-hid": "Isi naibunion",
+       "logentry-move-move": "$1 {{GENDER:$2|pindah}} alam $3 to $4",
+       "logentry-move-move-noredirect": "$1 {{GENDER:$2|pindah}} alaman $3 tu $4 inda maninggalkon pangalihan",
+       "logentry-move-move_redir": "$1 {{GENDER:$2|papindah}} alaman $3 tu $4 pangalihan lobi",
+       "logentry-patrol-patrol-auto": "$1 otomatis {{GENDER:$2|itandai}} revisi $4 ni alaman $3 naipatroli",
+       "logentry-newusers-create": "Akun pamake $1 ima {{GENDER:$2|baen}}",
+       "logentry-newusers-autocreate": "Akun pangguna $1 madung {{GENDER:$2|ibaen}} otomatis",
+       "logentry-upload-upload": "$1 {{GENDER:$2|maiunggah}} $3",
+       "searchsuggest-search": "Jalaki {{SITENAME}}",
+       "duration-days": "$1 {{PLURAL:$1|day|ari}}",
+       "randomrootpage": "Alaman urat kocok"
+}
index f4158ea..d4b37fc 100644 (file)
@@ -58,7 +58,8 @@
                        "Syum90",
                        "Xð",
                        "Abella",
-                       "Pierpao"
+                       "Pierpao",
+                       "Amire80"
                ]
        },
        "tog-underline": "Subratlla els enllaços:",
        "botpasswords-restriction-failed": "Les restriccions de contrasenyes de bots impedeixen aquest inici de sessió.",
        "botpasswords-invalid-name": "El nom d'usuari especificat no conté el separador de contrasenya de bot («$1»).",
        "botpasswords-not-exist": "L'usuari «$1» no té una contrasenya de bot anomenada «$2».",
+       "botpasswords-needs-reset": "Cal reinicialitzar la contrasenya del robot «$2» que pertany a {{GENDER:$1|l’usuari|la usuària}} «$1».",
        "resetpass_forbidden": "No poden canviar-se les contrasenyes",
        "resetpass_forbidden-reason": "Les contrasenyes no es poden canviar: $1",
        "resetpass-no-info": "Heu d'estar registrats en un compte per a poder accedir directament a aquesta pàgina.",
        "histlegend": "Simbologia: (act) = diferència amb la versió actual,\n(prev) = diferència amb la versió anterior, m = modificació menor",
        "history-fieldset-title": "Cerca revisions",
        "history-show-deleted": "Només revisions esborrades",
-       "histfirst": "més antigues",
-       "histlast": "més noves",
+       "histfirst": "les més antigues",
+       "histlast": "les més noves",
        "historysize": "({{PLURAL:$1|1 octet|$1 octets}})",
        "historyempty": "(buit)",
        "history-feed-title": "Historial de revisió",
        "prefs-watchlist-edits": "Nombre màxim de modificacions a mostrar en la llista de seguiment:",
        "prefs-watchlist-edits-max": "Nombre màxim: 1000",
        "prefs-watchlist-token": "Testimoni de llista de seguiment:",
+       "prefs-watchlist-managetokens": "Dirigeix testimonis",
        "prefs-misc": "Altres preferències",
        "prefs-resetpass": "Canvia la contrasenya",
        "prefs-changeemail": "Canvia o elimina l’adreça electrònica",
        "whatlinkshere": "Què hi enllaça",
        "whatlinkshere-title": "Pàgines que enllacen amb «$1»",
        "whatlinkshere-page": "Pàgina:",
-       "linkshere": "Les següents pàgines enllacen amb '''[[:$1]]''':",
-       "nolinkshere": "Cap pàgina no enllaça amb '''[[:$1]]'''.",
-       "nolinkshere-ns": "No s'enllaça cap pàgina a '''[[:$1]]''' en l'espai de noms triat.",
+       "linkshere-2": "Les següents pàgines enllacen amb '''$1''':",
+       "nolinkshere-2": "Cap pàgina no enllaça amb '''$1'''.",
+       "nolinkshere-ns-2": "No s'enllaça cap pàgina a '''$1''' en l'espai de noms triat.",
        "isredirect": "pàgina redirigida",
        "istemplate": "inclusió",
        "isimage": "enllaç a fitxer",
index c14d9f5..8ae463f 100644 (file)
        "undelete-search-submit": "尋討",
        "namespace": "Miàng-kŭng-găng:",
        "invert": "Huāng-sōng",
-       "blanknamespace": "(cuō-iéu)",
+       "blanknamespace": "(ciō-iéu)",
        "contributions": "{{GENDER:$1|User}}用戶貢獻",
        "contributions-title": "$1其用戶貢獻",
        "mycontris": "我其貢獻",
        "whatlinkshere": "Diē-nē̤ lièng gáu cē̤-nē̤",
        "whatlinkshere-title": "鏈接遘$1其頁面",
        "whatlinkshere-page": "頁面:",
-       "linkshere": "下底其頁面鏈接遘'''[[:$1]]''':",
-       "nolinkshere": "無頁鏈接遘'''[[:$1]]'''。",
+       "linkshere-2": "下底其頁面鏈接遘'''$1''':",
+       "nolinkshere-2": "無頁鏈接遘'''$1'''。",
        "isredirect": "重定向頁面",
        "isimage": "文件鏈接",
        "whatlinkshere-prev": "{{PLURAL:$1|前|前$1}}",
index 3de2d00..7603a1a 100644 (file)
        "linkstoimage-redirect": "$1 (файлан дӀасахьажорг) $2",
        "duplicatesoffile": "{{PLURAL:$1|Лахара файл ю дубликат|Лахара $1 файлаш ю дубликаташ}} хӀокху файлан ([[Special:FileDuplicateSearch/$2|мадарра]]):",
        "sharedupload": "ХӀара хӀума оцун $1 чура ю иза хила мега лелош кхечу проекташкахь.",
-       "sharedupload-desc-here": "Ð¥Ó\80аÑ\80а Ñ\84айл $1 Ñ\87Ñ\83Ñ\80а Ñ\8e Ð¸ Ð»ÐµÐ»Ð¾ Ð¹Ð¸Ñ\88 Ñ\8e Ð¼Ð°Ñ\81Ñ\81о Ð¿Ñ\80оекÑ\82аÑ\88каÑ\85Ñ\8c.\nЦÑ\83нна Ñ\85аам Ð³Ð°Ð¹Ñ\82ина Ð»Ð°Ñ\85аÑ\85Ñ\8c. [$2 Ð¤Ð°Ð¹Ð» Ð\92икигÑ\83ламехь]",
+       "sharedupload-desc-here": "Ð¥Ó\80аÑ\80а Ñ\84айл $1 Ñ\87Ñ\83Ñ\80а Ñ\8e Ð¸ Ð»ÐµÐ»Ð¾ Ð¹Ð¸Ñ\88 Ñ\8e Ð¼Ð°Ñ\81Ñ\81о Ð¿Ñ\80оекÑ\82аÑ\88каÑ\85Ñ\8c.\nЦÑ\83нна Ñ\85аам Ð³Ð°Ð¹Ñ\82ина Ð»Ð°Ñ\85аÑ\85Ñ\8c. [$2 Ð¤Ð°Ð¹Ð» Ð\92икилаÑ\80мехь]",
        "filepage-nofile": "Иштта цӀе йолуш файл яц.",
        "filepage-nofile-link": "Иштта цӀе йолуш файл яц. Хьа йиш ю и [$1 чуяккха].",
        "uploadnewversion-linktext": "Чуяккха керла верси хӀокху файлан",
        "whatlinkshere": "Кхуза хьажоргаш",
        "whatlinkshere-title": "«$1» тӀе хьажоргаш йолу агӀонаш",
        "whatlinkshere-page": "АгӀо:",
-       "linkshere": "ТӀаьхьайогӀу агӀонаш оцу '''[[:$1]]''': хьажоргца ю",
-       "nolinkshere": "ХӀокху '''[[:$1]]''' агӀона тӀе кхечу агӀонашкахь хьажоргаш яц.",
-       "nolinkshere-ns": "Хаьржинчу меттигехь яц '''[[:$1]]''' цӀе йолу агӀонаш",
+       "linkshere-2": "ТӀаьхьайогӀу агӀонаш оцу '''$1''': хьажоргца ю",
+       "nolinkshere-2": "ХӀокху '''$1''' агӀона тӀе кхечу агӀонашкахь хьажоргаш яц.",
+       "nolinkshere-ns-2": "Хаьржинчу меттигехь яц '''$1''' цӀе йолу агӀонаш",
        "isredirect": "агӀо-дӀасахьажорг",
        "istemplate": "юкъаялийнарш",
        "isimage": "Файлан хьажорг",
index 519f21e..415ae14 100644 (file)
        "whatlinkshere": "Unsay mga misumpay dinhi",
        "whatlinkshere-title": "Mga panid nga misumpay ngadto sa \"$1\"",
        "whatlinkshere-page": "Panid:",
-       "linkshere": "Ang mosunod nga mga panid misumpay sa '''[[:$1]]''':",
+       "linkshere-2": "Ang mosunod nga mga panid misumpay sa '''$1''':",
        "isredirect": "panid sa redirekta",
        "istemplate": "transklusyon",
        "isimage": "sumpay sa payl",
index 21c7ea1..138554b 100644 (file)
        "whatlinkshere": "Håfa ha na'chetton guini",
        "whatlinkshere-title": "I påhina siha ni mana'chetton yan \"$1\"",
        "whatlinkshere-page": "Påhina:",
-       "linkshere": "Umachetton i sigienten påhina siha yan '''[[:$1]]''':",
-       "nolinkshere": "Taya' umachetton yan '''[[:$1]]'''.",
+       "linkshere-2": "Umachetton i sigienten påhina siha yan '''$1''':",
+       "nolinkshere-2": "Taya' umachetton yan '''$1'''.",
        "isredirect": "dirihi i påhina",
        "istemplate": "sinaonao",
        "whatlinkshere-prev": "{{PLURAL:$1|ni må'pos|$1 ni manmå'pos}}",
index 79f2b2b..c0f78de 100644 (file)
        "rcfilters-limit-and-date-label": "$1 گۆڕانکاری، $2",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|ڕۆژ}}",
        "rcfilters-quickfilters": "پاڵوێنە پاشەکەوتکراوەکان",
+       "rcfilters-quickfilters-placeholder-title": "ھیچ پاڵوێنەیەک پاشەکەوت نەکراوە",
+       "rcfilters-quickfilters-placeholder-description": "بۆ پاشەکەوتکردنی ھەڵبژاردەی پاڵوێنەکان و دووبارە بەکارھێنانەوەیان، کرتە لەسەر نیشانی نیشانەی کتێبەکە بکە.",
        "rcfilters-savedqueries-defaultlabel": "پاڵوێنە پاشەکەوتکراوەکان",
        "rcfilters-savedqueries-setdefault": "بە بنەڕەتی کارای بکە",
        "rcfilters-savedqueries-new-name-label": "ناو",
        "whatlinkshere": "بەستەرەکان بە ئێرەوە",
        "whatlinkshere-title": "ئەو پەڕانەی بەستەریان ھەیە بۆ «$1»",
        "whatlinkshere-page": "پەڕە:",
-       "linkshere": "پەڕەکانی ژێرەوە بەستەر دراون بۆ <strong>[[:$1]]</strong>:",
-       "nolinkshere": "ھیچ پەڕەیەک بەستەری نییە بۆ <strong>[[:$1]]</strong>.",
-       "nolinkshere-ns": "ھیچ پەڕەیەک بەستەری نییە بۆ <strong>[[:$1]]</strong> لە بۆشایی ناوی هەڵبژێرراودا.",
+       "linkshere-2": "پەڕەکانی ژێرەوە بەستەر دراون بۆ <strong>$1</strong>:",
+       "nolinkshere-2": "ھیچ پەڕەیەک بەستەری نییە بۆ <strong>$1</strong>.",
+       "nolinkshere-ns-2": "ھیچ پەڕەیەک بەستەری نییە بۆ <strong>$1</strong> لە بۆشایی ناوی هەڵبژێرراودا.",
        "isredirect": "پەڕەی ڕەوانەکەر",
        "istemplate": "بەکارھێنراو",
        "isimage": "بەستەری پەڕگە",
        "fileduplicatesearch-result-n": "پەڕگەی «$1» {{PLURAL:$2|١ دووپاتکراوەی کوتوموتی|$2 دووپاتکراوەی کوتوموتی}} ھەیە.",
        "fileduplicatesearch-noresults": "پەڕگەیەک بە ناوی «$1» نەدۆزرایەوە.",
        "specialpages": "پەڕە تایبەتەکان",
+       "specialpages-note-restricted": "* پەڕە تایبەتە ئاساییەکان.\n* <span class=\"mw-specialpagerestricted\">پەڕە تایبەتە بەرگریلێکراوەکان.</span>",
        "specialpages-group-maintenance": "ڕاپۆرتەکانی چاکسازی",
        "specialpages-group-other": "پەڕە تایبەتەکانی دیکە",
        "specialpages-group-login": "چوونەژوورەوە / دروستکردنی ھەژمار",
index 56d36cd..360b865 100644 (file)
        "sp-contributions-submit": "Circà",
        "whatlinkshere": "Pagine chì leganu quì",
        "whatlinkshere-title": "Pagine ligate à \"$1\"",
-       "linkshere": "E seguente pagine sò culligate à '''[[:$1]]''':",
+       "linkshere-2": "E seguente pagine sò culligate à '''$1''':",
        "istemplate": "inclusione",
        "whatlinkshere-prev": "{{PLURAL:$1|precidente|precidenti $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|seguente|seguenti $1}}",
index 5e568a8..214edc4 100644 (file)
        "whatlinkshere": "Ang nagatabid diri",
        "whatlinkshere-title": "Mga pahina nga naga-link sa $1",
        "whatlinkshere-page": "Pahina:",
-       "linkshere": "Ang mga gasunod nga pahina ga-link sa '''[[:$1]]''':",
+       "linkshere-2": "Ang mga gasunod nga pahina ga-link sa '''$1''':",
        "isredirect": "pahina pangdirekta",
        "istemplate": "transklusyon",
        "isimage": "Link sang litrato",
index df4f8fd..27ff8ba 100644 (file)
        "whatlinkshere": "Бу саифеге багълантылар",
        "whatlinkshere-title": "«$1» саифесине багъланты олгъан саифелер",
        "whatlinkshere-page": "Саифе:",
-       "linkshere": "'''[[:$1]]''' саифесине багъланты берген саифелер:",
-       "nolinkshere": "'''[[:$1]]''' саифесине багъланты берген саифе ёкъ.",
-       "nolinkshere-ns": "Сайлангъан исим фезасында '''[[:$1]]''' саифесине багълангъан саифе ёкътыр.",
+       "linkshere-2": "'''$1''' саифесине багъланты берген саифелер:",
+       "nolinkshere-2": "'''$1''' саифесине багъланты берген саифе ёкъ.",
+       "nolinkshere-ns-2": "Сайлангъан исим фезасында '''$1''' саифесине багълангъан саифе ёкътыр.",
        "isredirect": "Ёллама саифеси",
        "istemplate": "кирсетильме",
        "isimage": "файл багълантысы",
index 7db085b..cd350ed 100644 (file)
        "whatlinkshere": "Bu saifege bağlantılar",
        "whatlinkshere-title": "“$1” saifesine bağlantı bergen saifeler",
        "whatlinkshere-page": "Saife:",
-       "linkshere": "'''[[:$1]]''' saifesine bağlantı bergen saifeler:",
-       "nolinkshere": "'''[[:$1]]''' saifesine bağlantı bergen saife yoq.",
-       "nolinkshere-ns": "Saylanğan isim fezasında '''[[:$1]]''' saifesine bağlanğan saife yoqtır.",
+       "linkshere-2": "'''$1''' saifesine bağlantı bergen saifeler:",
+       "nolinkshere-2": "'''$1''' saifesine bağlantı bergen saife yoq.",
+       "nolinkshere-ns-2": "Saylanğan isim fezasında '''$1''' saifesine bağlanğan saife yoqtır.",
        "isredirect": "Yollama saifesi",
        "istemplate": "kirsetilme",
        "isimage": "fayl bağlantısı",
index a37e90a..160fc43 100644 (file)
        "botpasswords-existing": "Stávající hesla pro boty",
        "botpasswords-createnew": "Vytvořit nové heslo pro boty",
        "botpasswords-editexisting": "Editovat existující heslo pro boty",
+       "botpasswords-label-needsreset": "(heslo se musí resetovat)",
        "botpasswords-label-appid": "Název bota:",
        "botpasswords-label-create": "Vytvořit",
        "botpasswords-label-update": "Aktualizovat",
        "botpasswords-restriction-failed": "Toto přihlášení bylo zamítnuto omezením hesel pro boty.",
        "botpasswords-invalid-name": "Uvedené uživatelské jméno neobsahuje oddělovač hesel pro boty („$1“).",
        "botpasswords-not-exist": "Uživatel „$1“ nemá heslo pro bota nazvaného „$2“.",
+       "botpasswords-needs-reset": "Heslo pro bota jménem „$2“ {{GENDER:$2|uživatele|uživatelky}} „$1“ se musí resetovat.",
        "resetpass_forbidden": "Hesla nelze změnit.",
        "resetpass_forbidden-reason": "Hesla nelze změnit: $1",
        "resetpass-no-info": "K této stránce mají přímý přístup jen přihlášení uživatelé.",
        "subject-preview": "Náhled předmětu:",
        "previewerrortext": "Při pokusu o zobrazení náhledu vašich změn došlo k chybě.",
        "blockedtitle": "Uživatel zablokován",
-       "blockedtext": "<strong>Vaší IP adrese či uživatelskému jménu byla zablokována možnost editace.</strong>\n\nZablokování {{GENDER:$4|provedl|provedla}} $1.\nUdaným důvodem bylo <em>$2</em>.\n\n* Začátek blokování: $8\n* Zablokování vyprší: $6\n* Blokovaný uživatel: $7\n\nPokud chcete zablokování prodiskutovat, můžete kontaktovat {{GENDER:$4|uživatele|uživatelku}} $1 či jiného [[{{MediaWiki:Grouppage-sysop}}|správce]].\nUvědomte si, že nemůžete použít funkci „Poslat e-mail“, jestliže nemáte ve svém [[Special:Preferences|nastavení]] uvedenu platnou e-mailovou adresu nebo pokud vám byla tato možnost zakázána.\nVaše IP adresa je $3 a&nbsp;identifikační číslo bloku je #$5; tyto údaje uvádějte ve všech dotazech na správce.",
-       "autoblockedtext": "Vaše IP adresa byla automaticky zablokována, protože ji používal jiný uživatel, kterého zablokoval $1.\nUdaný důvod blokování:\n\n:<em>$2</em>\n\n* Začátek blokování: $8\n* Konec blokování: $6\n* Původně blokovaný uživatel: $7\n\nZablokování můžete prodiskutovat se správcem $1 nebo některým z dalších [[{{MediaWiki:Grouppage-sysop}}|správců]].\n\nUvědomte si však, že funkci „Poslat e-mail tomuto uživateli“ nemůžete použít, pokud nemáte ve svém [[Special:Preferences|uživatelském nastavení]] zadaný platný e-mail a nebylo vám zablokováno jeho užívání.\n\nVaše současná IP adresa je $3, číslo vašeho zablokování je #$5.\nProsíme, uveďte tyto údaje při komunikaci se správci.",
+       "blockedtext": "<strong>Vaší IP adrese či uživatelskému jménu byla zablokována možnost editace.</strong>\n\nZablokování {{GENDER:$4|provedl|provedla}} $1.\nUdaným důvodem bylo <em>$2</em>.\n\n* Začátek blokování: $8\n* Zablokování vyprší: $6\n* Blokovaný uživatel: $7\n\nPokud chcete zablokování prodiskutovat, můžete kontaktovat {{GENDER:$4|uživatele|uživatelku}} $1 či jiného [[{{MediaWiki:Grouppage-sysop}}|správce]].\nUvědomte si, že nemůžete použít funkci „{{int:emailuser}}“, jestliže nemáte ve svém [[Special:Preferences|nastavení]] uvedenu platnou e-mailovou adresu nebo pokud vám byla tato možnost zakázána.\nVaše IP adresa je $3 a&nbsp;identifikační číslo bloku je #$5; tyto údaje uvádějte ve všech dotazech na správce.",
+       "autoblockedtext": "Vaše IP adresa byla automaticky zablokována, protože ji používal jiný uživatel, kterého zablokoval $1.\nUdaný důvod blokování:\n\n:<em>$2</em>\n\n* Začátek blokování: $8\n* Konec blokování: $6\n* Původně blokovaný uživatel: $7\n\nZablokování můžete prodiskutovat se správcem $1 nebo některým z dalších [[{{MediaWiki:Grouppage-sysop}}|správců]].\n\nUvědomte si však, že funkci „{{int:emailuser}}“ nemůžete použít, pokud nemáte ve svém [[Special:Preferences|uživatelském nastavení]] zadaný platný e-mail a nebylo vám zablokováno jeho užívání.\n\nVaše současná IP adresa je $3, číslo vašeho zablokování je #$5.\nProsíme, uveďte tyto údaje při komunikaci se správci.",
        "systemblockedtext": "Vaše IP adresa byla automaticky zablokována softwarem MediaWiki.\nUdaný důvod blokování:\n\n:<em>$2</em>\n\n* Začátek blokování: $8\n* Konec blokování: $6\n* Původně blokovaný uživatel: $7\n\nVaše současná IP adresa je $3.\nProsíme, uveďte tyto údaje při komunikaci se správci.",
        "blockednoreason": "důvod nebyl zadán",
        "whitelistedittext": "Pro editaci se musíte $1.",
        "protectedtitles-submit": "Zobrazit názvy",
        "listusers": "Uživatelé",
        "listusers-editsonly": "Zobrazit pouze uživatele s editacemi",
+       "listusers-temporarygroupsonly": "Zobrazit pouze uživatele v dočasných uživatelských skupinách",
        "listusers-creationsort": "Seřadit podle data registrace",
        "listusers-desc": "Řadit sestupně",
        "usereditcount": "$1 {{PLURAL:$1|editace|editace|editací}}",
        "apisandbox-dynamic-parameters-add-label": "Přidat parametr:",
        "apisandbox-dynamic-parameters-add-placeholder": "Jméno parametru",
        "apisandbox-dynamic-error-exists": "Parametr s názvem „$1“ již existuje.",
+       "apisandbox-templated-parameter-reason": "Tento [[Special:ApiHelp/main#main/templatedparams|šablonovaný parametr]] se nabízí na základě {{PLURAL:$1|hodnoty|hodnot}} parametru $2.",
        "apisandbox-deprecated-parameters": "Zavržené parametry",
        "apisandbox-fetch-token": "Automaticky naplnit token",
        "apisandbox-add-multi": "Přidat",
        "whatlinkshere": "Odkazuje sem",
        "whatlinkshere-title": "Stránky odkazující na „$1“",
        "whatlinkshere-page": "Strana:",
-       "linkshere": "Na '''[[:$1]]''' odkazují tyto stránky:",
-       "nolinkshere": "Žádná stránka na '''[[:$1]]''' neodkazuje.",
-       "nolinkshere-ns": "Ve zvoleném jmenném prostoru na '''[[:$1]]''' neodkazuje žádná stránka.",
+       "linkshere-2": "Na <strong>$1</strong> odkazují tyto stránky:",
+       "nolinkshere-2": "Žádná stránka na <strong>$1</strong> neodkazuje.",
+       "nolinkshere-ns-2": "Ve zvoleném jmenném prostoru na <strong>$1</strong> neodkazuje žádná stránka.",
        "isredirect": "přesměrování",
        "istemplate": "vložení",
        "isimage": "vložení souboru",
        "pagedata-title": "Data stránky",
        "pagedata-text": "Tato stránka poskytuje datové rozhraní ke stránkám. Uveďte prosím název stránky v URL pomocí syntaxe pro podstránky.\n* Funguje dohadování o obsahu na základě hlavičky Accept vašeho klienta. To znamená, že data stránky budou poskytnuta ve formátu preferovaném vaším klientem.",
        "pagedata-not-acceptable": "Nenalezen odpovídající formát. Podporované MIME typy: $1",
-       "pagedata-bad-title": "Neplatný název: $1."
+       "pagedata-bad-title": "Neplatný název: $1.",
+       "unregistered-user-config": "Z bezpečnostních důvodů nelze načítat uživatelské podstránky s JavaScriptem, CSS nebo JSONem u neregistrovaných uživatelů."
 }
index d441b53..3620a0b 100644 (file)
        "whatlinkshere": "Lënkùjącé",
        "whatlinkshere-title": "Starnë lënkùjącé do \"$1\"",
        "whatlinkshere-page": "Starna:",
-       "linkshere": "Do '''[[:$1]]''' lënkùją hewòtné starnë:",
-       "nolinkshere": "Niżódnô starna nie lënkùje do '''[[:$1]]'''.",
+       "linkshere-2": "Do '''$1''' lënkùją hewòtné starnë:",
+       "nolinkshere-2": "Niżódnô starna nie lënkùje do '''$1'''.",
        "isredirect": "starna przeczerowaniô",
        "istemplate": "doparłãczony",
        "isimage": "lënk do lopka",
index 6d27e3e..c490c2a 100644 (file)
@@ -11,7 +11,7 @@
                        "Vvs-dm"
                ]
        },
-       "tog-oldsig": "нꙑнѣшьн҄ь аѵтографъ :",
+       "tog-oldsig": "твои нꙑнѣшьн҄ь аѵтографъ :",
        "underline-always": "вьсѥгда",
        "underline-never": "никъгда",
        "sunday": "нєдѣлꙗ",
        "subcategories": "подъкатигорїѩ",
        "category-media-header": "катигорїѩ ⁖ $1 ⁖ дѣла",
        "category-empty": "''сѥи катигорїи нꙑнѣ страницѧ и дѣлъ нѣстъ''",
-       "hidden-categories": "{{PLURAL:$1|съкрꙑта катигорїꙗ|съкрꙑти катигорїи|съкрꙑтꙑ катигорїѩ}}",
+       "hidden-categories": "{{PLURAL:$1|съкрꙑта катигорїꙗ|съкрꙑтѣ катигорїи|съкрꙑтꙑ катигорїѩ}}",
        "hidden-category-category": "съкрꙑтꙑ катигорїѩ",
        "category-subcat-count": "{{PLURAL:$2|1=Сѥи катигорїи тъкъмо сꙗ подъкатигорїꙗ ѥстъ|Сѥи катигорїи {{PLURAL:$1|1=ѥдина подъкатигорїꙗ ѥстъ|2 подъкатигорїи ѥстє|$1 подъкатигорїѩ сѫтъ}} · а вьсѩ жє подъкатигорїѩ число $2 ѥстъ}}",
        "listingcontinuesabbrev": "· вѧщє",
+       "broken-file-category": "страницѧ ѩжє блаꙁничьнꙑ свѧꙁи съ дѣла имѫтъ",
        "about": "опьсаниѥ",
        "article": "члѣнъ",
-       "newwindow": "(иномь окънѣ)",
+       "newwindow": "(вÑ\8a Ð¸Ð½Ð¾Ð¼Ñ\8c Ð¾ÐºÑ\8aнѣ)",
        "cancel": "отъмѣтаниѥ",
        "moredotdotdot": "вѧщє ···",
        "mypage": "страница",
@@ -97,9 +98,9 @@
        "anontalk": "бєсѣда",
        "navigation": "плаваниѥ",
        "and": "&#32;и",
-       "faq": "чѧст въпроси",
+       "faq": "чѧсти въпроси",
        "actions": "дѣиства",
-       "namespaces": "имєнъ простор",
+       "namespaces": "имєнъ простори",
        "variants": "обраꙁи",
        "navigation-heading": "плаваниѥ",
        "errorpagetitle": "блаꙁна",
        "redirectedfrom": "(прѣнаправлѥниѥ отъ ⁖ $1 ⁖)",
        "redirectpagesub": "прѣнаправлѥниѥ",
        "redirectto": "прѣнаправлѥниѥ къ :",
-       "lastmodifiedat": "Ñ\81Ñ\82Ñ\80аниÑ\86ѧ Ð¿Ð¾Ñ\81лѣдÑ\8cнê\99\97 Ð¼Ñ£Ð½Ð° Ñ\81Ñ\8aÑ\82воÑ\80ѥна $2 Â· $1 Ð±Ñ£ ⁙",
+       "lastmodifiedat": "Ñ\81ѥѩ Ñ\81Ñ\82Ñ\80аниÑ\86ѧ Ð¿Ð¾Ñ\81лѣдÑ\8cнê\99\97 Ð¼Ñ£Ð½Ð° Ñ\81Ñ\8aÑ\82воÑ\80ѥна $2 Â· $1 Ð±Ñ£Ð°Ñ\88Ñ\94 ⁙",
        "protectedpage": "сꙗ страница ꙁабранѥна ѥстъ",
        "jumpto": "прѣиди къ :",
        "jumptonavigation": "плаваниѥ",
        "aboutsite": "{{grammar:genitive|{{SITENAME}}}} опьсаниѥ",
        "aboutpage": "Project:О сѥмь опꙑтьствовании",
        "copyright": "подъ прощєниѥмь $1 пьсано ѥстъ · ащє ино нє каꙁано ѥстъ",
-       "copyrightpage": "{{ns:project}}:ТвоÑ\80Ñ\8cÑ\86Ñ\8a права",
-       "currentevents": "сѫщѧѩ вѣщи",
-       "currentevents-url": "Project:Сѫщѧѩ вѣщи",
+       "copyrightpage": "{{ns:project}}:ТвоÑ\80Ñ\8cÑ\86Ñ\8c права",
+       "currentevents": "сѫщѧѩ вѣщиѥ",
+       "currentevents-url": "Project:Сѫщѧѩ вѣщиѥ",
        "disclaimers": "отърицаниꙗ",
        "disclaimerpage": "Project:Главьно отърицаниѥ",
        "edithelp": "помощь по исправлѥниѭ",
        "viewsource": "страницѧ источьнъ обраꙁъ",
        "viewsource-title": "вижьдь страницѧ ⁖ $1 ⁖ источьнъ обраꙁъ",
        "exception-nologin": "тꙑ нє въшьлъ ѥси",
-       "welcomeuser": "Добрѣ прити · $1!",
+       "welcomeuser": "радоуи сѧ · $1",
        "welcomecreation-msg": "твоѥ польꙃєватєльско мѣсто сътворєно ѥстъ ⁙\nнꙑнѣ иꙁмѣнити [[Special:Preferences|{{GRAMMAR:genitive|{{SITENAME}}}} строи]] можєши",
        "yourname": "твоѥ имѧ",
        "userlogin-yourname": "польꙃєватєлꙗ имѧ",
        "createacct-benefit-heading": "{{SITENAME}} съꙁьдаѥтъ сѧ чьловѣкꙑ · ижє ꙗко тꙑ сѫтъ",
        "createacct-benefit-body1": "{{PLURAL:$1|мѣна|мѣнꙑ|мѣнъ}}",
        "createacct-benefit-body2": "{{PLURAL:$1|страница|страници|страницѧ}}",
+       "createacct-benefit-body3": "{{PLURAL:$1|послѣдьн҄ь дѣтєл҄ь|послѣдьнꙗ дѣтєлꙗ|послѣдьни дѣтєлє}}",
        "userexists": "сѫщє польꙃєватєлꙗ имѧ пьса ⁙\nбѫди добръ · ино сѥ иꙁобрѧщи",
        "loginerror": "въхода блаꙁна",
        "createacct-error": "мѣста сътворѥниꙗ блаꙁна",
        "link_tip": "вънѫтрьнꙗ съвѧꙁь",
        "extlink_sample": "http://www.example.com съвѧꙁи имѧ",
        "extlink_tip": "вънѣщьнꙗ съвѧꙁь (помьни о http://)",
+       "headline_sample": "тїтла напьсаниѥ",
+       "headline_tip": "тїтлъ рѧда В҃",
        "media_tip": "дѣла съвѧꙁь",
        "sig_tip": "твои аѵтографъ и нꙑнѣшьна врѣмѧ и дьнь",
        "summary": "опьсаниѥ :",
        "minoredit": "малаꙗ мѣна",
        "watchthis": "сѥѩ страницѧ блюдєниѥ",
        "savearticle": "съхранѥниѥ",
-       "showpreview": "мѣнꙑ поꙁьрѣниѥ (бєꙁ съхранѥниꙗ)",
+       "showpreview": "мѣнꙑ поꙁьрѣниѥ (бєс съхранѥниꙗ)",
+       "showdiff": "раꙁьницѧ поꙁьрѣниѥ",
        "blockedtitle": "польꙃєватєл҄ь ꙁаграждєнъ ѥстъ",
        "loginreqlink": "въниди",
        "newarticle": "(новъ)",
        "noarticletext-nopermission": "нꙑнѣ с̑ьдє ничєсожє нє напьсано ѥстъ ⁙\n[[Special:Search/{{PAGENAME}}|сѥѩ страницѧ имѧ искати]] дроугꙑ страницѧ или\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} съвѧꙁанꙑ їсторїѩ видѣти]</span> можєши ⁙ сътворити жє сѭ страницѫ нє можєши",
        "userpage-userdoesnotexist": "польꙃєватєльска мѣста ⁖ $1 ⁖ нꙑнѣ нѣстъ ⁙\nпрѣдъ сътворѥниѥмь или исправлѥниѥмь сѥѩ страницѧ помꙑсли жє ащє исто тъ дѣиство ноуждьно ли",
        "userpage-userdoesnotexist-view": "польꙃєватєльско мѣсто ⁖ $1 ⁖ сътворєно нѣстъ",
-       "clearyourcache": "'''НАРОЧИТО''': По съхранѥнии можєши обити своѥго съмотрила съхранъ да видѣлъ би мѣнꙑ\n* '''Mozilla ли Firefox ли Safari''' ли жьмꙑи ''Shift'' а мꙑшиѭ жьми ''Reload'' или жьми ''Ctrl-F5'' ꙗко жє ''Ctrl-R'' (⌘-R вън Apple Mac)\n* '''Google Chrome:''' ли жьмꙑи ''Ctrl-Shift-R'' (⌘-Shift-R въ Mac)\n* '''Internet Explorer''' ли жьмꙑи ''Ctrl'' а мꙑшиѭ жьми ''Refresh'' или жьми ''Ctrl-F5'' \n* '''Опєрꙑ''' польꙃєватєльмъ можєть бꙑти ноужда пльнѣ поничьжити ихъ съмотрила съхранъ въ ''Tools → Preferences'' ⁙",
+       "clearyourcache": "<strong>НАРОЧИТО</strong>: По съхранѥнии можєши обити своѥго съмотрила съхранъ да видѣлъ би мѣнꙑ\n* <strong>Mozilla ли Firefox ли Safari</strong>''' ли жьмꙑи <em>Shift</em>'' а мꙑшиѭ жьми <em>Reload</em> или жьми <em>Ctrl-F5</em> ꙗко жє <em>Ctrl-R</em> (<em>⌘-R</em> вън Apple Mac)\n* <strong>Google Chrome:</strong> ли жьмꙑи <em>Ctrl-Shift-R</em>'' (<em>⌘-Shift-R</em> въ Mac)\n* <strong>Internet Explorer</strong>''' ли жьмꙑи <em>Ctrl</em> а мꙑшиѭ жьми <em>Refresh</em> или жьми <em>Ctrl-F5</em> \n* <strong>Опєрꙑ</strong> польꙃєватєльмъ можєть бꙑти ноужда пльнѣ поничьжити ихъ съмотрила съхранъ въ <em>Tools → Preferences</em> (<em>Opera → Preferences</em> вън Apple Mac) ⁙",
        "updated": "(оновлѥно ѥстъ)",
        "note": "'''НАРОЧИТО:'''",
        "editing": "исправлѥниѥ: $1",
        "template-protected": "(ꙁабранєно ѥстъ)",
        "template-semiprotected": "(чѧстьно ꙁабранѥно)",
        "hiddencategories": "сꙗ страница въ {{PLURAL:$1|1 съкрꙑтѣи катигорїи|$1 съкрꙑтѣхъ катигорїѩ}} сѧ авлꙗѥтъ :",
-       "moveddeleted-notice": "Ñ\81ê\99\97 Ñ\81Ñ\82Ñ\80аниÑ\86а Ð¿Ð¾Ð½Ð¸Ñ\87Ñ\8cжÑ\94на Ñ¥Ñ\81Ñ\82Ñ\8a â\81\99\nпониÑ\87Ñ\8cжÑ\94ниê\99\97 Ð¸ Ð¿Ñ\80ѣимÑ\94нованиê\99\97 Ñ\97Ñ\81Ñ\82оÑ\80ии Ñ\81ѥѩ Ñ\81Ñ\82Ñ\80аниÑ\86ѧ Ð½Ð¸Ð¶Ñ£ видѣти можєши",
+       "moveddeleted-notice": "Ñ\81ê\99\97 Ñ\81Ñ\82Ñ\80аниÑ\86а Ð¿Ð¾Ð½Ð¸Ñ\87Ñ\8cжÑ\94на Ñ¥Ñ\81Ñ\82Ñ\8a â\81\99\nпониÑ\87Ñ\8cжÑ\94ниê\99\97 Ð»Ð¸ Ð¿Ñ\80ѣимÑ\94нованиê\99\97 Ð»Ð¸ ê\99\81абÑ\80анѥниê\99\97 Ñ\97Ñ\81Ñ\82оÑ\80Ñ\97Ñ© Ð½Ð° Ñ\81ѥи Ñ\81Ñ\82Ñ\80аниÑ\86и Ð½Ð¸Ð¶Ñ\94 видѣти можєши",
        "postedit-confirmation-created": "страница сътворѥна ѥстъ",
        "postedit-confirmation-saved": "твоꙗ мѣна съхранѥна ѥстъ",
        "viewpagelogs": "сѥѩ страницѧ їсторїѩ",
+       "revisionasof": "обраꙁъ отъ $1",
+       "revision-info": "страницѧ обраꙁъ отъ $1 ижє {{GENDER:$6|$2}}$7 сътвори",
+       "previousrevision": "← прѣждьн҄ь обраꙁъ",
+       "currentrevisionlink": "послѣдьн҄ь обраꙁъ",
        "cur": "нꙑ҃н",
        "last": "пс҃лд",
        "page_first": "прьва страница",
        "editundo": "отъмѣтаниѥ",
        "searchresults": "исканиꙗ слѣдьствиѥ",
        "searchresults-title": "исканиꙗ ⁖ $1 ⁖ слѣдьствиѥ",
+       "prevn": "прѣждьнѩ {{PLURAL:$1|$1}}",
        "viewprevnext": "виждь ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-exists": "'''страница имєньмь ⁖ [[:$1]] ⁖ ѥстъ створѥна ю'''",
        "searchmenu-new": "<strong>страницѫ \"⁖ [[:$1]] ⁖\" сътворити можєши</strong> {{PLURAL:$2|0=|ꙁъри такождє страница ижє по искании авлєна ѥстъ|ꙁьри такождє исканиꙗ слѣдьствиꙗ}}",
        "searchprofile-articles-tooltip": "ищи въ $1",
        "searchprofile-images-tooltip": "исканиѥ дѣлъ",
        "searchprofile-everything-tooltip": "ищи вьсѩ страницѧ въкоупомь съ бѣсєдꙑ",
-       "search-result-size": "$1 ({{PLURAL:$2|$2 слово|$2 слова|$2 словєсъ}})",
-       "search-redirect": "(прѣнаправлєниѥ $1)",
+       "search-result-size": "$1 ({{PLURAL:$2|$2 слово|$2 словєсѣ|$2 словєсъ}})",
+       "search-redirect": "(прѣнаправлєниѥ отъ $1)",
        "search-section": "(чѧсть $1)",
        "search-suggest": "⁖ $1 ⁖ мьниши ли",
-       "search-interwiki-caption": "родьствьна опꙑтьствованиꙗ",
+       "search-interwiki-caption": "иꙁд родьствьнъ опꙑтьствовании вѣстиѥ",
        "search-interwiki-more": "(вѧщє)",
        "searchall": "вьсꙗ",
        "search-nonefound": "исканиѥ сꙗ слова ничєсо жє нє авило ѥстъ",
        "prefs-namespaces": "имєнъ просторꙑ",
        "prefs-files": "дѣла",
        "username": "{{GENDER:$1|польꙃєватєлꙗ имѧ}} :",
-       "prefs-memberingroups": "{{GENDER:$2|польꙃєватєлꙗ}} {{PLURAL:$1|чинъ|чина|чинꙑ}} :",
+       "prefs-memberingroups": "{{GENDER:$2|польꙃєватєлꙗ|польꙃєватєлицѧ}} {{PLURAL:$1|чинъ|чина|чини}} :",
        "yourrealname": "истиньно имѧ :",
        "yourlanguage": "ѩꙁꙑкъ :",
        "yournick": "новъ аѵтографъ :",
        "gender-male": "онъ исправитъ страницѧ",
        "gender-female": "она исправитъ страницѧ",
        "prefs-signature": "аѵтографъ",
-       "userrights": "чина польꙃєватєлꙗ строи",
+       "userrights": "польꙃєватєлꙗ чинъ",
        "userrights-reason": "какъ съмꙑслъ :",
        "group": "чинъ :",
        "group-user": "польꙃєватєлє",
        "booksources-search-legend": "кънигъ кладѧꙃь исканиѥ",
        "booksources-search": "исканиѥ",
        "specialloguserlabel": "испльнитєл҄ь :",
-       "speciallogtitlelabel": "страницѧ или польꙃєватєлꙗ имѧ :",
+       "speciallogtitlelabel": "страницѧ или {{ns:user}}:польꙃєватєлꙗ имѧ :",
        "log": "їсторїѩ",
        "all-logs-page": "вьсѩ обьщѧ їсторїѩ",
        "allpages": "вьсѩ страницѧ",
        "watchlist": "блюдєниꙗ",
        "mywatchlist": "блюдєниꙗ",
        "watchlistfor2": "дѣлꙗ ⁖ $1 ⁖ $2",
-       "addedwatchtext": "Ñ\81Ñ\82Ñ\80аниÑ\86а â\81\96 [[:$1]] â\81\96 Ð½ê\99\91нѣ Ð¿Ð¾Ð´Ñ\8a Ñ\82воимÑ\8c [[Special:Watchlist|блÑ\8eдÑ\94ниѥмÑ\8c]] Ñ¥Ñ\81Ñ\82Ñ\8a â\81\99\nвÑ\81ê\99\97 Ñ¥Ñ© Ð¸ Ñ¥Ñ©Ð¶Ñ\94 Ð±Ñ\94Ñ\81ѣдê\99\91 Ñ\81Ñ\82Ñ\80аниÑ\86ѧ Ð¼Ñ£Ð½ê\99\91 Ñ\82воê\99\97 Ð±Ð»Ñ\8eдÑ\94нии ÐºÐ°Ñ\82алоê\99\83Ñ£ Ð¿Ð¾ÐºÐ°ê\99\81анê\99\91 Ð±Ñ«Ð´Ñ«Ñ\82Ñ\8a",
-       "removedwatchtext": "Ñ\81Ñ\82Ñ\80аниÑ\86а â\81\96 [[:$1]] â\81\96 Ð½ê\99\91нѣ твоѥго [[Special:Watchlist|блюдєниꙗ]] иꙁнєсєна ѥстъ",
+       "addedwatchtext": "Ñ\81Ñ\82Ñ\80аниÑ\86а â\81\96 [[:$1]] â\81\96 Ð¸ Ñ¥Ñ©Ð¶Ñ\94 Ð±Ñ\94Ñ\81ѣда Ð½ê\99\91нѣ Ð¿Ð¾Ð´Ñ\8a Ñ\82воимÑ\8c [[Special:Watchlist|блÑ\8eдÑ\94ниѥмÑ\8c]] Ñ¥Ñ\81Ñ\82Ñ\94 â\81\99",
+       "removedwatchtext": "Ñ\81Ñ\82Ñ\80аниÑ\86а â\81\96 [[:$1]] â\81\96 Ð¸ Ñ¥Ñ©Ð¶Ñ\94 Ð±Ñ\94Ñ\81ѣда Ð½ê\99\91нѣ Ð¸Ñ\81 твоѥго [[Special:Watchlist|блюдєниꙗ]] иꙁнєсєна ѥстъ",
        "watch": "блюдєниѥ",
        "watchthispage": "сѥѩ страницѧ блюдєниѥ",
        "unwatch": "остави блюдєниѥ",
        "created": "сътворѥнъ ѥстъ",
        "deletepage": "поничьжєниѥ",
        "excontent": "вънѫтри бѣ: '$1'",
-       "excontentauthor": "вънѫтри бѣ : '$1' (и послѣдьн҄ии дѣтєл҄ь бѣ '[[Special:Contributions/$2|$2]]')",
+       "excontentauthor": "вънѫтри бѣ : '$1' · и послѣдьн҄ии дѣтєл҄ь бѣ [[Special:Contributions/$2|$2]] ([[User talk:$2|бєсѣда]])",
        "delete-legend": "поничьжєниѥ",
        "actioncomplete": "дѣиство сътворєно ѥстъ",
        "deletedtext": "страница ⁖ $1 ⁖ поничьжєна ѥстъ ⁙\nвиждь ⁖ $2 ⁖ послѣдьнъ поничьжєниѩ дѣлꙗ",
        "undelete-show-file-submit": "да",
        "namespace": "имєнъ просторъ:",
        "invert": "обрати иꙁборъ",
-       "namespace_association": "съвѧꙁанꙑ имєнъ просторꙑ",
+       "namespace_association": "съвѧꙁани имєнъ простори",
        "blanknamespace": "(главьно)",
        "contributions": "{{GENDER:$1|польꙃєватєлꙗ|польꙃєватєлицѧ}} добродѣꙗниꙗ",
        "contributions-title": "польꙃєватєлꙗ ⁖ $1 ⁖ добродѣꙗниꙗ",
        "mycontris": "добродѣꙗниꙗ",
        "anoncontribs": "добродѣꙗниꙗ",
-       "contribsub2": "польꙃєватєлꙗ имѧ ⁖ {{GENDER:$3|$1}} ⁖ ѥстъ ($2)",
+       "contribsub2": "{{GENDER:$3|польꙃєватєлꙗ|польꙃєватєлицѧ}} имѧ ⁖ $1 ⁖ ѥстъ ($2)",
        "uctop": "(нꙑнѣщьн҄ь обраꙁъ)",
        "month": "отъ мѣсѧца и давѣѥ :",
-       "year": "отъ лѣта и давѣѥ :",
+       "year": "отъ лѣта и давѣи :",
        "sp-contributions-blocklog": "ꙁаграждєниꙗ їсторїꙗ",
-       "sp-contributions-deleted": "поничьжєнꙑ добродѣꙗниꙗ",
+       "sp-contributions-deleted": "{{GENDER:$1|поꙁєватєлꙗ|польꙃєватєлицѧ}} поничьжєнꙑ добродѣꙗниꙗ",
        "sp-contributions-uploads": "положєнꙑ дѣла",
        "sp-contributions-logs": "їсторїѩ",
        "sp-contributions-talk": "бєсѣда",
        "sp-contributions-username": "IP число или польꙃєватєлꙗ имѧ :",
        "sp-contributions-submit": "ищи",
-       "whatlinkshere": "дос҄ьдєщьнѩ съвѧꙁи",
+       "whatlinkshere": "дос҄ьдєщьнѩ съвѧꙁиѥ",
        "whatlinkshere-title": "страницѧ ижє съ ⁖ $1 ⁖ съвѧꙁи имѫтъ",
        "whatlinkshere-page": "страница :",
+       "linkshere-2": "сѩ страницѧ съ <strong>$1</strong> съвѧꙁи имѫтъ :",
        "isredirect": "прѣнаправлѥниѥ",
        "istemplate": "внѫтри страницѧ",
        "isimage": "дѣла съвѧꙁь",
-       "whatlinkshere-links": "← съвѧꙁи",
+       "whatlinkshere-links": "← съвѧꙁиѥ",
        "whatlinkshere-hideredirs": "$1 прѣнаправлѥниꙗ",
-       "whatlinkshere-hidelinks": "$1 съвѧꙁи",
-       "whatlinkshere-filters": "сит",
+       "whatlinkshere-hidelinks": "$1 съвѧꙁиѥ",
+       "whatlinkshere-filters": "сита",
        "block": "ꙁагради польꙃєватєл҄ь",
        "blockip": "ꙁагради {{GENDER:$1|польꙃєватєл҄ь}}",
        "ipaddressorusername": "IP число или польꙃєватєлꙗ имѧ :",
        "blocklink": "ꙁагради",
        "contribslink": "добродѣꙗниꙗ",
        "blocklogpage": "ꙁаграждєниꙗ їсторїꙗ",
-       "blocklogentry": "ꙁаградилъ [[$1]] на врѣмѧ $2 $3",
+       "blocklogentry": "ꙁагради [[$1]] на врѣмѧ $2 $3",
        "block-log-flags-anononly": "тъкъмо анѡнѷмьнꙑ польꙃєватєлє",
        "block-log-flags-nocreate": "сътворѥниѥ мѣстъ ꙁабранєно ѥстъ",
        "ipb_already_blocked": "⁖ $1 ⁖ ю ꙁаграждєнъ ѥстъ",
        "tooltip-pt-userpage": "{{GENDER:|твоꙗ польꙃєватєл҄ьска}} страница",
        "tooltip-pt-mytalk": "{{GENDER:|твоꙗ}} бєсѣдꙑ страница",
        "tooltip-pt-preferences": "{{GENDER:|твои}} строи",
-       "tooltip-pt-watchlist": "страницѧ ижє ихъжє иꙁмѣнѥниꙗ подъ твоимь блюдєниѥмь сѫтъ",
+       "tooltip-pt-watchlist": "страницѧ ѩжє ихъжє иꙁмѣнѥниꙗ подъ твоимь блюдєниѥмь сѫтъ",
        "tooltip-pt-mycontris": "{{GENDER:|твоѩ}} добродѣꙗнии каталогъ",
        "tooltip-pt-logout": "ис̾ходъ",
        "tooltip-ca-talk": "сѥѩ страницѧ бєсѣда",
        "tooltip-ca-edit": "сѥѩ страницѧ исправлѥниѥ",
        "tooltip-ca-viewsource": "си страница ꙁабранєна ѥстъ ⁙\nѥѩ источьнъ обраꙁъ видєти можєши",
+       "tooltip-ca-history": "сѥѩ страницѧ прѣждьни обраꙁи",
        "tooltip-ca-protect": "сѥѩ страницѧ ꙁабранєниѥ",
        "tooltip-ca-delete": "сѥѩ страницѧ поничьжєниѥ",
        "tooltip-ca-move": "сѥѩ страницѧ прѣимєнованиѥ",
        "tooltip-search-go": "прѣиди къ страницѧ съ симь имєньмь ащє жє та страница ѥстъ",
        "tooltip-search-fulltext": "исканиѥ страницѧ ижє сѥ напьсаниѥ дрьжатъ",
        "tooltip-p-logo": "главьна страница",
-       "tooltip-n-mainpage": "виждь главьноу страницѫ",
-       "tooltip-n-mainpage-description": "виждь главьноу страницѫ",
+       "tooltip-n-mainpage": "виждь главьнѫ страницѫ",
+       "tooltip-n-mainpage-description": "виждь главьнѫ страницѫ",
        "tooltip-n-recentchanges": "послѣдьн҄ь мѣнъ каталогъ",
-       "tooltip-t-whatlinkshere": "страницѧ ижє съвѧꙁи дос҄ьдє имѫтъ",
+       "tooltip-n-randompage": "виждь страницѫ въ нєꙁаапѫ",
+       "tooltip-t-whatlinkshere": "страницѧ ѩжє съвѧꙁи дос҄ьдє имѫтъ",
        "tooltip-t-contributions": "{{GENDER:$1|польꙃєватєлꙗ|польꙃєватєлицѧ}} добродѣꙗнии каталогъ",
        "tooltip-t-upload": "положєниѥ дѣлъ",
        "tooltip-t-specialpages": "вьсѣѩ нарочьнъ страницѧ каталогъ",
        "tooltip-t-print": "сѥѩ страницѧ пєчатьнъ обраꙁъ",
+       "tooltip-t-permalink": "вѣчьна съвѧꙁь съ симь страницѧ обраꙁомь",
        "tooltip-ca-nstab-user": "виждь польꙃєватєлꙗ страницѫ",
        "tooltip-ca-nstab-special": "сѥ нарочьна страница ѥстъ · ѥѩжє иꙁмѣнꙗти нє можєши",
        "tooltip-ca-nstab-image": "виждь дѣла страницѫ",
        "tags-deactivate-reason": "какъ съмꙑслъ :",
        "htmlform-no": "нѣтъ",
        "htmlform-yes": "да",
-       "logentry-delete-delete": "$1 {{GENDER:$2|поничьжилъ|поничьжила}} страницѫ ⁖ $3 ⁖",
+       "logentry-delete-delete": "$1 {{GENDER:$2|поничьжи}} страницѫ ⁖ $3 ⁖",
        "logentry-block-block": "$1 {{GENDER:$2|ꙁаградилъ|ꙁаградила}} {{GENDER:$4|$3}} на врѣмѧ $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|ꙁаграждєнъ|ꙁаграждєна}} ѥстъ {{GENDER:$4|$3}} врѣмєньмь $5 $6",
        "logentry-move-move": "$1 {{GENDER:$2|нарєчє}} страницѫ ⁖ $3 ⁖ имєньмь ⁖ $4 ⁖",
index 946c6c9..eaa60c0 100644 (file)
        "toc": "Тупмалли",
        "showtoc": "кăтартмалла",
        "hidetoc": "кӑтартмалла мар",
+       "collapsible-expand": "Çавăр",
        "thisisdeleted": "$1 пăхса каялла тавăрмалла-и?",
        "viewdeleted": "$1 пăхар-и?",
        "restorelink": "{{PLURAL:$1|кăларса пăрахнă тӳрлетнине|$1 кăларса пăрахнă тӳрлетнисене}}",
        "searchprofile-articles": "Статьясем",
        "searchprofile-images": "Мультимедиа",
        "searchprofile-everything": "Пур ҫӗрте",
-       "searchprofile-advanced": "Ð\90нлÓ\91лаÑ\82нÓ\91",
+       "searchprofile-advanced": "СаÑ\80лакаÑ\80аÑ\85",
        "searchprofile-articles-tooltip": "$1 -ре шырани",
        "searchprofile-images-tooltip": "Файăлсене шырани",
        "searchprofile-everything-tooltip": "Мӗнпур элсенче (сӳтсе явнинче те) шыра",
-       "searchprofile-advanced-tooltip": "ЯÑ\82аÑ\80лÓ\91 Ñ\8fÑ\82 Ñ\82алккÓ\91Ñ\88Ó\97сенче шыра",
+       "searchprofile-advanced-tooltip": "Ð\9fанÄ\83 Ñ\8fÑ\82 Ñ\85Ñ\83Ñ\88Ñ\88исенче шыра",
        "search-result-size": "$1 ({{PLURAL:$2|1 сăмах|$2 сăмах}})",
        "search-category": "(категори $1)",
        "search-interwiki-caption": "Тăван проектсем",
        "searchrelated": "çыхăнă",
        "showingresults": "Аяларах эсир <strong>$2</strong> пуçласа кăтартнă <strong>$1</strong> йĕркене куратăр.",
        "powersearch-legend": "Анлă шырав",
+       "powersearch-ns": "Ят хушшисенче шыра:",
+       "powersearch-togglelabel": "Тĕрĕсреххи:",
+       "powersearch-toggleall": "Пурне те",
        "powersearch-togglenone": "Нимĕнте",
        "search-external": "Тулти шырамалли",
        "preferences": "Ĕнерлевсем",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (пăхăр [[Special:NewPages|çĕнĕ страницăсен списокĕ]])",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "Кăтарт",
+       "rcfilters-legend-heading": "<strong>Кĕскетнисем:</strong>",
+       "rcfilters-other-review-tools": "Урăх пăхмаллисем",
+       "rcfilters-filterlist-title": "Фильтрсем",
+       "rcfilters-filter-editsbyself-label": "Хăвăр улăштарнисем",
+       "rcfilters-filter-editsbyother-label": "Урăххисем улăштарнисем",
        "rcfilters-filter-user-experience-level-newcomer-label": "Çĕнĕ хутшăнакансем",
+       "rcfilters-filter-user-experience-level-learner-label": "Вĕренекенсем",
+       "rcfilters-filtergroup-automated": "Автоматлă хушнисем",
+       "rcfilters-filter-bots-label": "Бот",
+       "rcfilters-filter-humans-label": "Çын (бот мар)",
+       "rcfilters-filtergroup-significance": "Пĕлтерни",
+       "rcfilters-filter-minor-label": "Кăштах тӳрлетнисем",
+       "rcfilters-filter-major-label": "Ахаль тӳрлетнисем",
+       "rcfilters-filter-categorization-label": "Категорине улăштарнисем",
+       "rcfilters-filtergroup-lastRevision": "Юлашки версисем",
+       "rcfilters-filter-lastrevision-label": "Хальхи верси",
+       "rcfilters-filter-previousrevision-label": "Юлашки верси мар",
        "rclistfrom": "$2, $3 тытăнса çĕнĕ улăшăнисене кăтартни",
        "rcshowhideminor": "пĕчĕк тӳрлетнисене $1",
        "rcshowhideminor-show": "кăтартмалла",
        "longpages": "Вăрăм страницăсем",
        "deadendpages": "Нимĕнпе те çыхăнман страницăсем",
        "protectedpages": "Хӳтĕленĕ страницăсем",
+       "protectedpages-filters": "Фильтрсем:",
        "protectedtitles": "Юраман ятсем",
        "listusers": "Хутшăнакансен списокĕ",
        "newpages": "Çĕнĕ страницăсем",
        "sp-contributions-submit": "Шыра",
        "whatlinkshere": "Кунта каçаканнисем",
        "whatlinkshere-title": "\"$1\" çине каçакан страницăсем",
-       "linkshere": "<strong>[[:$1]]</strong> çине каçакан страницăсем:",
-       "nolinkshere": "'''[[:$1]]''' страница çине ытти страницăсенчен килме пулмасть.",
+       "linkshere-2": "<strong>$1</strong> çине каçакан страницăсем:",
+       "nolinkshere-2": "'''$1''' страница çине ытти страницăсенчен килме пулмасть.",
        "whatlinkshere-prev": "{{PLURAL:$1|унчченхи|унчченхи $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|урăххи|урăххисем $1}}",
        "whatlinkshere-links": "← каçаканнисем",
        "whatlinkshere-hideredirs": "куçарнисене $1",
        "whatlinkshere-hidelinks": "Каçаканнисене $1",
-       "whatlinkshere-filters": "Ð\90ласем",
+       "whatlinkshere-filters": "ФилÑ\8cÑ\82Ñ\80сем",
        "whatlinkshere-submit": "Ту",
        "blockip": "{{GENDER:$1|хутшăнакана}} чар",
        "ipaddressorusername": "IP адрес е усă куракан ят:",
        "tooltip-pt-watchlist": "Эсир пăхакан страницисем",
        "tooltip-pt-mycontris": "Сирĕн хушнисем",
        "tooltip-pt-anoncontribs": "Ку IP адреспа тӳрлетнисем",
-       "tooltip-pt-login": "Ð\9aÓ\97ме ÐºÐ¸Ñ\80леÑ\85 Ð¼Ð°Ñ\80\85а Ñ\82а, Ð°Ñ\80а Ð°Ð²Ð°Ð½Ñ\80аÑ\85.",
+       "tooltip-pt-login": "Ð\90ккаÑ\83нÑ\82 Ñ\82Ñ\83Ñ\81а ÐºÄ\95Ñ\80Ä\95Ñ\80, ÐºÄ\95меÑ\81Ä\95Ñ\80 Ñ\82е Ñ\8eÑ\80аÑ\82Ñ\8c",
        "tooltip-pt-logout": "Сеансне пĕтер",
-       "tooltip-pt-createaccount": "Ð\90ккаÑ\83нÑ\82 Ñ\82Ñ\83 Ñ\82а Ñ\81иÑ\81Ñ\82емÓ\91на ÐºÓ\97Ñ\80. Ð\9fаллаÑ\85, Ñ\83нÑ\81Ó\91Ñ\80аÑ\85 Ñ\82а Ñ\8eÑ\80аÑ\82Ñ\8c, Ð°Ð½Ñ\87аÑ\85 Ñ\82а Ð°ÐºÐºÐ°Ñ\83нÑ\82па ÐºÓ\97ни Ð»Ð°Ð¹Ó\91Ñ\85Ñ\80аÑ\85.",
+       "tooltip-pt-createaccount": "Ð\9aÄ\95ме Ð°ÐºÐºÐ°Ñ\83нÑ\82 Ñ\82Ä\83вÄ\83Ñ\80, ÐºÄ\95меÑ\81Ä\95Ñ\80 Ñ\82е Ñ\8eÑ\80аÑ\82Ñ\8c",
        "tooltip-ca-talk": "Статьяна сӳтсе явасси",
-       "tooltip-ca-edit": "Эле тӳрлет",
+       "tooltip-ca-edit": "Ð\9aÄ\83на тӳрлет",
        "tooltip-ca-addsection": "Çĕнĕ пай ту",
        "tooltip-ca-viewsource": "Ку страницӑна эсир улӑштарма пултараймастӑр. Ӑна мӗнле ҫырнине кӑна пӑхма пултаратӑр.",
-       "tooltip-ca-history": "Эле Ñ\83лÓ\91Ñ\88Ñ\82аÑ\80нин ÐºÑ\83н-Ò«Ñ\83лÓ\97",
+       "tooltip-ca-history": "Ð\9aÑ\83нÄ\83н Ñ\83лÓ\91Ñ\88Ä\83нниÑ\81ем",
        "tooltip-ca-protect": "Улӑшратусенчен сыхласси",
        "tooltip-ca-delete": "Страницӑна кӑларса пӑрахмалли",
        "tooltip-ca-move": "Страницӑна урӑх ҫӗре куҫарасси",
index d6fb2bf..fc7cf59 100644 (file)
        "whatlinkshere": "Beth sy'n cysylltu yma",
        "whatlinkshere-title": "Tudalennau sy'n cysylltu â \"$1\"",
        "whatlinkshere-page": "Tudalen:",
-       "linkshere": "Mae'r tudalennau isod yn cysylltu â '''[[:$1]]''':",
-       "nolinkshere": "Nid oes cyswllt ar unrhyw dudalen arall syn arwain at '''[[:$1]]'''.",
-       "nolinkshere-ns": "Nid oes cyswllt ar unrhyw dudalen yn y parth dewisedig sy'n arwain at '''[[:$1]]'''.",
+       "linkshere-2": "Mae'r tudalennau isod yn cysylltu â '''$1''':",
+       "nolinkshere-2": "Nid oes cyswllt ar unrhyw dudalen arall syn arwain at '''$1'''.",
+       "nolinkshere-ns-2": "Nid oes cyswllt ar unrhyw dudalen yn y parth dewisedig sy'n arwain at '''$1'''.",
        "isredirect": "tudalen ailgyfeirio",
        "istemplate": "cynhwysiad",
        "isimage": "cyswllt ffeil",
index 652e426..3112c59 100644 (file)
        "subject-preview": "Forhåndsvisning af emne/overskrift:",
        "previewerrortext": "Der opstod en fejl under forsøget på at lave en forhåndsvisning af dine ændringer.",
        "blockedtitle": "Du eller din IP-adresse er blokeret",
-       "blockedtext": "'''Dit brugernavn eller din IP-adresse er blevet blokeret.'''\n\nBlokeringen er foretaget af $1.\nDen anførte grund er ''$2''.\n\nBlokeringen starter: $8\nBlokeringen udløber: $6\nBlokeringen er rettet mod: $7\n\nDu kan kontakte $1 eller en af de andre [[{{MediaWiki:Grouppage-sysop}}|administratorer]] for at diskutere blokeringen.\nDu kan ikke bruge funktionen 'e-mail til denne bruger' medmindre der er angivet en gyldig e-mailadresse i dine\n[[Special:Preferences|kontoindstillinger]], og du ikke er blevet blokeret fra at bruge den.\n\nDin nuværende IP-adresse er $3, og blokerings-id er #$5.\nAngiv venligst alle ovenstående detaljer ved henvendelser om blokeringen.",
+       "blockedtext": "<strong>Dit brugernavn eller din IP-adresse er blevet blokeret.</strong>\n\nBlokeringen er foretaget af $1.\nDen anførte grund er <em>$2</em>.\n\nBlokeringen starter: $8\nBlokeringen udløber: $6\nBlokeringen er rettet mod: $7\n\nDu kan kontakte $1 eller en af de andre [[{{MediaWiki:Grouppage-sysop}}|administratorer]] for at diskutere blokeringen.\nDu kan ikke bruge funktionen \"{{int:emailuser}}\" medmindre der er angivet en gyldig e-mailadresse i dine [[Special:Preferences|kontoindstillinger]], og du ikke er blevet blokeret fra at bruge den.\n\nDin nuværende IP-adresse er $3, og blokerings-id er #$5.\nAngiv venligst alle ovenstående detaljer ved henvendelser om blokeringen.",
        "autoblockedtext": "Din IP-adresse er blevet blokeret automatisk fordi den blev brugt af en anden bruger som er blevet blokeret af $1.\nBegrundelsen for det er:\n\n:''$2''\n\n* Blokeringsperiodens start: $8\n* Blokeringen udløber: $6\n* Blokeringen er ment for: $7\n\nDu kan kontakte $1 eller en af de andre [[{{MediaWiki:Grouppage-sysop}}|administratorer]] for at diskutere blokeringen.\n\nBemærk at du ikke kan bruge funktionen \"e-mail til denne bruger\" medmindre du har en gyldig e-mailadresse registreret i din [[Special:Preferences|brugerindstilling]], og du ikke er blevet blokeret fra at bruge den.\n\nDin nuværende IP-adresse er $3, og blokerings-id'et er #$5.\nAngiv venligst alle de ovenstående detaljer ved eventuelle henvendelser.",
        "systemblockedtext": "Dit brugernavn eller din IP-adresse er automatisk blokeret af MediaWiki.\nBegrundelsen for det er:\n\n:<em>$2</em>\n\n* Blokeringsperiodens start: $8\n* Blokeringen udløber: $6\n* Blokeringen er ment for: $7\n\nDin nuværende IP-adresse er $3.\nAngiv venligst alle de ovenstående detaljer ved eventuelle henvendelser.",
        "blockednoreason": "ingen begrundelse givet",
        "recentchangeslinked-feed": "Relaterede ændringer",
        "recentchangeslinked-toolbox": "Relaterede ændringer",
        "recentchangeslinked-title": "Ændringer der relaterer til \"$1\"",
-       "recentchangeslinked-summary": "Indtast et sidenavn for at sændringer på sider henvist til eller fra den side. (For at se medlemmer af en kategori indtast Category:Kategorinavn). Ændringer til sider på [[Special:Watchlist|din overvågningsliste]] er vist med <strong>fed</strong> skrift.",
+       "recentchangeslinked-summary": "Indtast et sidenavn for at sændringer på sider henvist til eller fra den side. (For at se medlemmer af en kategori indtast {{ns:category}}:Kategorinavn). Ændringer til sider på [[Special:Watchlist|din overvågningsliste]] er vist med <strong>fed</strong> skrift.",
        "recentchangeslinked-page": "Sidenavn:",
        "recentchangeslinked-to": "Vis ændringer i sider der henviser til den angivne side i stedet",
        "recentchanges-page-added-to-category": "[[:$1]] tilføjet til kategori",
        "whatlinkshere": "Hvad henviser hertil",
        "whatlinkshere-title": "Sider der linker til \"$1\"",
        "whatlinkshere-page": "Side:",
-       "linkshere": "De følgende sider henviser til '''„[[:$1]]“''':",
-       "nolinkshere": "Ingen sider henviser til '''„[[:$1]]“'''.",
-       "nolinkshere-ns": "Ingen side henviser til '''„[[:$1]]“''' i det valgte navnerum.",
+       "linkshere-2": "De følgende sider henviser til '''„$1“''':",
+       "nolinkshere-2": "Ingen sider henviser til '''„$1“'''.",
+       "nolinkshere-ns-2": "Ingen side henviser til '''„$1“''' i det valgte navnerum.",
        "isredirect": "omdirigeringsside",
        "istemplate": "indlejring",
        "isimage": "filhenvisning",
        "fileduplicatesearch-noresults": "Ingen fil med navnet \"$1\" blev fundet.",
        "specialpages": "Specialsider",
        "specialpages-note-top": "Forklaring",
+       "specialpages-note-restricted": "* Normale specialsider.\n* <span class=\"mw-specialpagerestricted\">Specialsider med begrænset adgang.</span>",
        "specialpages-group-maintenance": "Vedligeholdelsesside",
        "specialpages-group-other": "Andre specialsider",
        "specialpages-group-login": "Log på / opret bruger",
index 98438c2..2718774 100644 (file)
        "blanknamespace": "(Seiten)",
        "contributions-title": "Benutzerbeiträge von «$1»",
        "whatlinkshere-title": "Seiten, die auf «$1» verlinken",
-       "linkshere": "Die folgenden Seiten verlinken auf '''«[[:$1]]»''':",
-       "nolinkshere": "Keine Seite verlinkt auf '''«[[:$1]]»'''.",
-       "nolinkshere-ns": "Keine Seite verlinkt auf '''«[[:$1]]»''' im gewählten Namensraum.",
+       "linkshere-2": "Die folgenden Seiten verlinken auf '''«$1»''':",
+       "nolinkshere-2": "Keine Seite verlinkt auf '''«$1»'''.",
+       "nolinkshere-ns-2": "Keine Seite verlinkt auf '''«$1»''' im gewählten Namensraum.",
        "ipb-confirmhideuser": "Du bist gerade dabei, einen Benutzer im Modus «Benutzer verstecken» zu sperren. Dies führt dazu, dass der Benutzername in allen Listen und Logbüchern unterdrückt wird. Möchtest du das wirklich tun?",
        "ipb-unblock-addr": "«$1» freigeben",
        "ipb-blocklist-contribs": "Benutzerbeiträge von «$1»",
index 0470691..bbc8a08 100644 (file)
        "subject-preview": "Vorschau der Zusammenfassungszeile:",
        "previewerrortext": "Beim Versuch, eine Vorschau deiner Änderungen anzuzeigen, ist ein Fehler aufgetreten.",
        "blockedtitle": "Benutzer ist gesperrt",
-       "blockedtext": "'''Dein Benutzername oder deine IP-Adresse wurde gesperrt.'''\n\nDie Sperrung wurde vom Administrator $1 durchgeführt.\nAls Grund wurde ''$2'' angegeben.\n\n* Beginn der Sperre: $8\n* Ende der Sperre: $6\n* Sperre betrifft: $7\n\nDu kannst $1 oder einen der anderen [[{{MediaWiki:Grouppage-sysop}}|Administratoren]] kontaktieren, um über die Sperre zu diskutieren.\nDu kannst die „E-Mail an diesen Benutzer“-Funktion nicht nutzen, solange keine gültige E-Mail-Adresse in deinen [[Special:Preferences|Benutzerkonto-Einstellungen]] eingetragen ist oder diese Funktion für dich gesperrt wurde.\nDeine aktuelle IP-Adresse ist $3 und die Sperrkennung lautet $5.\nBitte füge alle Informationen jeder Anfrage hinzu, die du stellst.",
-       "autoblockedtext": "Deine IP-Adresse wurde automatisch gesperrt, da sie von einem anderen Benutzer genutzt wurde, der von $1 gesperrt wurde.\nAls Grund wurde angegeben:\n\n:''$2''\n\n* Beginn der Sperre: $8\n* Ende der Sperre: $6\n* Sperre betrifft: $7\n\nDu kannst $1 oder einen der anderen [[{{MediaWiki:Grouppage-sysop}}|Administratoren]] kontaktieren, um über die Sperre zu diskutieren.\n\nDu kannst die „E-Mail an diesen Benutzer“-Funktion nicht nutzen, solange keine gültige E-Mail-Adresse in deinen [[Special:Preferences|Benutzerkonto-Einstellungen]] eingetragen ist oder diese Funktion für dich gesperrt wurde.\n\nDeine aktuelle IP-Adresse ist $3, und die Sperr-ID ist $5.\nBitte füge alle Informationen jeder Anfrage hinzu, die du stellst.",
+       "blockedtext": "'''Dein Benutzername oder deine IP-Adresse wurde gesperrt.'''\n\nDie Sperrung wurde vom Administrator $1 durchgeführt.\nAls Grund wurde ''$2'' angegeben.\n\n* Beginn der Sperre: $8\n* Ende der Sperre: $6\n* Sperre betrifft: $7\n\nDu kannst $1 oder einen der anderen [[{{MediaWiki:Grouppage-sysop}}|Administratoren]] kontaktieren, um über die Sperre zu diskutieren.\nDu kannst die „{{int:emailuser}}“-Funktion nicht nutzen, solange keine gültige E-Mail-Adresse in deinen [[Special:Preferences|Benutzerkonto-Einstellungen]] eingetragen ist oder diese Funktion für dich gesperrt wurde.\nDeine aktuelle IP-Adresse ist $3 und die Sperrkennung lautet $5.\nBitte füge alle Informationen jeder Anfrage hinzu, die du stellst.",
+       "autoblockedtext": "Deine IP-Adresse wurde automatisch gesperrt, da sie von einem anderen Benutzer genutzt wurde, der von $1 gesperrt wurde.\nAls Grund wurde angegeben:\n\n:''$2''\n\n* Beginn der Sperre: $8\n* Ende der Sperre: $6\n* Sperre betrifft: $7\n\nDu kannst $1 oder einen der anderen [[{{MediaWiki:Grouppage-sysop}}|Administratoren]] kontaktieren, um über die Sperre zu diskutieren.\n\nDu kannst die „{{int:emailuser}}“-Funktion nicht nutzen, solange keine gültige E-Mail-Adresse in deinen [[Special:Preferences|Benutzerkonto-Einstellungen]] eingetragen ist oder diese Funktion für dich gesperrt wurde.\n\nDeine aktuelle IP-Adresse ist $3, und die Sperr-ID ist $5.\nBitte füge alle Informationen jeder Anfrage hinzu, die du stellst.",
        "systemblockedtext": "Dein Benutzername oder deine IP-Adresse wurde von MediaWiki automatisch gesperrt.\nDer angegebene Grund ist:\n\n:<em>$2</em>\n\n* Beginn der Sperre: $8\n* Ablauf der Sperre: $6\n* Sperre betrifft: $7\n\nDeine aktuelle IP-Adresse ist $3.\nBitte gib alle oben stehenden Details in jeder Anfrage an.",
        "blockednoreason": "keine Begründung angegeben",
        "whitelistedittext": "Du musst dich $1, um Seiten bearbeiten zu können.",
        "protectedtitles-submit": "Titel anzeigen",
        "listusers": "Benutzerverzeichnis",
        "listusers-editsonly": "Zeige nur Benutzer mit Beiträgen",
+       "listusers-temporarygroupsonly": "Nur Benutzer in temporären Benutzergruppen anzeigen",
        "listusers-creationsort": "Nach Erstelldatum sortieren",
        "listusers-desc": "In absteigender Reihenfolge sortieren",
        "usereditcount": "$1 {{PLURAL:$1|Bearbeitung|Bearbeitungen}}",
        "apisandbox-dynamic-parameters-add-label": "Parameter hinzufügen:",
        "apisandbox-dynamic-parameters-add-placeholder": "Name des Parameters",
        "apisandbox-dynamic-error-exists": "Ein Parameter mit dem Namen „$1“ ist bereits vorhanden.",
+       "apisandbox-templated-parameter-reason": "Diese [[Special:ApiHelp/main#main/templatedparams|Vorlagenparameter]] werden basierend auf {{PLURAL:$1|dem Wert|den Werten}} von $2 angeboten.",
        "apisandbox-deprecated-parameters": "Veraltete Parameter",
        "apisandbox-fetch-token": "Den Token automatisch ausfüllen",
        "apisandbox-add-multi": "Hinzufügen",
        "whatlinkshere": "Links auf diese Seite",
        "whatlinkshere-title": "Seiten, die auf „$1“ verlinken",
        "whatlinkshere-page": "Seite:",
-       "linkshere": "Die folgenden Seiten verlinken auf <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Keine Seite verlinkt auf '''„[[:$1]]“'''.",
-       "nolinkshere-ns": "Keine Seite verlinkt auf '''„[[:$1]]“''' im gewählten Namensraum.",
+       "linkshere-2": "Die folgenden Seiten verlinken auf <strong>$1</strong>:",
+       "nolinkshere-2": "Keine Seite verlinkt auf '''„$1“'''.",
+       "nolinkshere-ns-2": "Keine Seite verlinkt auf '''„$1“''' im gewählten Namensraum.",
        "isredirect": "Weiterleitungsseite",
        "istemplate": "Vorlageneinbindung",
        "isimage": "Dateilink",
        "pagedata-title": "Seitendaten",
        "pagedata-text": "Diese Seite stellt eine Datenschnittstelle für Seiten zur Verfügung. Bitte gib mithilfe der Unterseitensyntax den Seitentitel in der URL an.\n* Übertragungen von Inhalten werden basierend auf dem Accept-Header deines Clients ausgeführt. Das bedeutet, dass die Seitendaten in dem Format zur Verfügung gestellt werden, das von deinem Client bevorzugt wird.",
        "pagedata-not-acceptable": "Kein passendes Format gefunden. Unterstützte MIME-Typen: $1",
-       "pagedata-bad-title": "Ungültiger Titel: $1."
+       "pagedata-bad-title": "Ungültiger Titel: $1.",
+       "unregistered-user-config": "Aus Sicherheitsgründen können JavaScript-, CSS- und JSON-Benutzerunterseiten nicht für unangemeldete Benutzer geladen werden.",
+       "passwordpolicies": "Passwortrichtlinien",
+       "passwordpolicies-summary": "Dies ist eine Liste der wirksamen Passwortrichtlinien für die in diesem Wiki definierten Benutzergruppen.",
+       "passwordpolicies-group": "Gruppe",
+       "passwordpolicies-policies": "Richtlinien",
+       "passwordpolicies-policy-minimalpasswordlength": "Ein Passwort muss mindestens {{PLURAL:$1|ein|$1}} Zeichen lang sein",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Ein Passwort muss mindestens {{PLURAL:$1|ein|$1}} Zeichen zur Anmeldung lang sein",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Ein Passwort kann nicht mit dem Benutzernamen identisch sein",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Ein Passwort kann nicht mit speziellen schwarzgelisteten Passwörtern übereinstimmen",
+       "passwordpolicies-policy-maximalpasswordlength": "Ein Passwort muss weniger als {{PLURAL:$1|ein|$1}} Zeichen lang sein",
+       "passwordpolicies-policy-passwordcannotbepopular": "Ein Passwort kann nicht {{PLURAL:$1|das beliebteste Passwort|in der Liste der $1 beliebtesten Passwörter}} sein"
 }
index 2ad2c5a..f80e87f 100644 (file)
        "rcnotefrom": "Cêr de <strong>$2</strong> ra nata {{PLURAL:$5|vurnayışiyê}} asenê (tewr vêşi <strong>$1</strong> asenê) <strong>$3, $4</strong>",
        "rclistfrom": "$3 sehat $2 ra tepiya vurnayışanê neweyan bımotne",
        "rcshowhideminor": "Vırnayışê werdiy $1",
-       "rcshowhideminor-show": "Bımotne",
+       "rcshowhideminor-show": "Bımocne",
        "rcshowhideminor-hide": "Bınımne",
        "rcshowhidebots": "botan $1",
-       "rcshowhidebots-show": "Bımotne",
+       "rcshowhidebots-show": "Bımocne",
        "rcshowhidebots-hide": "Bınımne",
        "rcshowhideliu": "karberê qeydbiyay $1",
        "rcshowhideliu-show": "Bımocne",
        "rcshowhideliu-hide": "Bınımne",
        "rcshowhideanons": "$1 karberê bênamey",
-       "rcshowhideanons-show": "Bımotne",
+       "rcshowhideanons-show": "Bımocne",
        "rcshowhideanons-hide": "Bınımne",
        "rcshowhidepatr": "$1 vurnayışê ke dewriya geyrayê",
        "rcshowhidepatr-show": "Bımocne",
        "rcshowhidepatr-hide": "Bınımne",
        "rcshowhidemine": "vırnayışê mı $1",
-       "rcshowhidemine-show": "Bımotne",
+       "rcshowhidemine-show": "Bımocne",
        "rcshowhidemine-hide": "Bınımne",
        "rcshowhidecategorization": "kategorizasyoni $1",
-       "rcshowhidecategorization-show": "Bımotné",
+       "rcshowhidecategorization-show": "Bımocne",
        "rcshowhidecategorization-hide": "Bınımne",
        "rclinks": "$1 vurnayışê peyênê ke $2 rocanê peyênan de biyê, inan bımocne",
        "diff": "ferq",
        "hist": "verên",
        "hide": "Bınımne",
-       "show": "Bımotne",
+       "show": "Bımocne",
        "minoreditletter": "q",
        "newpageletter": "N",
        "boteditletter": "b",
        "withoutinterwiki": "Perrê ke zıwananê binan rê gıreyê cı çıni yo",
        "withoutinterwiki-summary": "Enê pelî ke versiyonê ziwanî binî ra link nidano.",
        "withoutinterwiki-legend": "Verole",
-       "withoutinterwiki-submit": "Bımotne",
+       "withoutinterwiki-submit": "Bımocne",
        "fewestrevisions": "Perrê kı tewr tayn timaryayê",
        "nbytes": "$1 {{PLURAL:$1|bayt|bayti}}",
        "ncategories": "$1 {{PLURAL:$1|Kategori|Kategoriy}}",
        "usereditcount": "$1 {{PLURAL:$1|vurnayîş|vurnayîşî}}",
        "usercreated": "$2 de $1 {{GENDER:$3|viraziya}}",
        "newpages": "Perrê newey",
-       "newpages-submit": "Bımotne",
+       "newpages-submit": "Bımocne",
        "newpages-username": "Nameyê karberi:",
        "ancientpages": "Tewr pelê kıhani",
        "move": "Bıkırışe",
        "specialloguserlabel": "Kerdoğ:",
        "speciallogtitlelabel": "Meqsed (sername ya zi {{ns:user}}:karberi rê nameyê karberi):",
        "log": "Qeydi",
-       "logeventslist-submit": "Bımotne",
+       "logeventslist-submit": "Bımocne",
        "all-logs-page": "Heme qeydê pêroyi",
        "alllogstext": "qey {{SITENAME}}i mocnayişê heme rocaneyani.\ntipa rocaneyi, nameyê karberi (herfa pil u qıci re hessas a), ya zi peli (reyna hessasiyê herfa pil u qıciyi) bıweçine u esayiş qıc kerê.",
        "logempty": "Qeydan dı malumato unasin çıni yo.",
        "linksearch-line": "$1, $2 ra link biya",
        "linksearch-error": "jokeri têna nameyê makina ya serekini de aseni/eseni.",
        "listusersfrom": "karber ê ke pey ıney detpêkeni ramocın:",
-       "listusers-submit": "Bımotne",
+       "listusers-submit": "Bımocne",
        "listusers-noresult": "karber nêdiyayo/a.",
        "listusers-blocked": "(blok biy)",
        "activeusers": "Lista karberanê aktifan",
        "wlnote": "$3 saete $4 ra dıme {{PLURAL:$2|yew saete de|'''$2''' saetan de}} {{PLURAL:$1|vurnayışo peyên|vurnayışê '''$1''' peyêni}} cêrderê.",
        "wlshowlast": "Peyni de  $1 seata u $2 roca  bıasne",
        "watchlist-hide": "Bınımne",
-       "watchlist-submit": "Bımotne",
+       "watchlist-submit": "Bımocne",
        "wlshowtime": "Periyoda zemani asenayışi:",
        "wlshowhideminor": "vırnayışê werdiy",
        "wlshowhidebots": "boti",
        "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ê}}:",
-       "historyaction-submit": "Bımotne",
+       "historyaction-submit": "Bımocne",
        "confirmdeletetext": "Tı ho yew pele u tarixê pele wederneno.\nTı ra rica keno, tı zani tı ho sekeno, tı zani neticeyanê eno wedarnayışi u tı zani tı ser [[{{MediaWiki:Policy-url}}|poliçe]] kar keno.",
        "actioncomplete": "Kar bi temam",
        "actionfailed": "kar nêbı",
        "whatlinkshere": "Linkê tedeestey",
        "whatlinkshere-title": "Wesiqe da \"$1\" rê gıre dayen perri",
        "whatlinkshere-page": "Pele:",
-       "linkshere": "Pera <strong>[[:$1]]</strong> rê gıre dayen perri",
-       "nolinkshere": "Per da '''[[:$1]]''' rê pera ke gıre dana çıniya.",
-       "nolinkshere-ns": "Cayo ke namey rê weçinayo de qet perre '''[[:$1]]''' rê link nêbena.",
+       "linkshere-2": "Pera <strong>$1</strong> rê gıre dayen perri",
+       "nolinkshere-2": "Per da '''$1''' rê pera ke gıre dana çıniya.",
+       "nolinkshere-ns-2": "Cayo ke namey rê weçinayo de qet perre '''$1''' rê link nêbena.",
        "isredirect": "pera hetenayışi",
        "istemplate": "Açarnayene",
        "isimage": "gırey dosye",
        "fileduplicatesearch-noresults": "Ebe namey \"$1\" ra dosya nêdiyayê.",
        "specialpages": "Perrê xısusiy",
        "specialpages-note-top": "Kıtabek",
+       "specialpages-note-restricted": "* Pelê xasê normali.\n* <span class=\"mw-specialpagerestricted\">Pelê xasê nımıtey.</span>",
        "specialpages-group-maintenance": "Raporê pawıtışi",
        "specialpages-group-other": "Pelê xısusiyê bini",
        "specialpages-group-login": "Dekew / hesab vıraz",
index 1cffbde..2b8e205 100644 (file)
        "whatlinkshere": "Wótkaze na toś ten bok",
        "whatlinkshere-title": "Boki, kótarež wótkazuju na \"$1\"",
        "whatlinkshere-page": "bok:",
-       "linkshere": "Toś te boki wótkazuju na '''„[[:$1]]“''':",
-       "nolinkshere": "Žedne boki njewótkazuju na '''[[:$1]]'''.",
-       "nolinkshere-ns": "Žedne boki we wubranem mjenjowem rumje njewótkazuju na '''[[:$1]]'''.",
+       "linkshere-2": "Toś te boki wótkazuju na '''„$1“''':",
+       "nolinkshere-2": "Žedne boki njewótkazuju na '''$1'''.",
+       "nolinkshere-ns-2": "Žedne boki we wubranem mjenjowem rumje njewótkazuju na '''$1'''.",
        "isredirect": "dalejpósrědnjujucy bok",
        "istemplate": "zawězanje pśedłogi",
        "isimage": "datajowy wótkaz",
        "fileduplicatesearch-noresults": "Žedna dataja z mjenim \"$1\" namakana.",
        "specialpages": "Specialne boki",
        "specialpages-note-top": "Legenda",
+       "specialpages-note-restricted": "* Normalne specialne boki.\n* <span class=\"mw-specialpagerestricted\">Specialne boki z wobgranicowanym pśistupom.</span>",
        "specialpages-group-maintenance": "Wótwardowańske lisćiny",
        "specialpages-group-other": "Druge specialne boki",
        "specialpages-group-login": "Pśizjawiś/Konto załožyś",
index 64052ed..00b5f14 100644 (file)
        "whatlinkshere": "Nunu poingoput hiti",
        "whatlinkshere-title": "Bolikon di poingoput id \"$1\"",
        "whatlinkshere-page": "Bolikon:",
-       "linkshere": "Bolikon diti poingoput kumaa id  '''[[:$1]]''':",
-       "nolinkshere": "Ingaa bolikon poingoput id '''[[:$1]]'''.",
+       "linkshere-2": "Bolikon diti poingoput kumaa id  '''$1''':",
+       "nolinkshere-2": "Ingaa bolikon poingoput id '''$1'''.",
        "isredirect": "bolikon pinotilombus",
        "istemplate": "alanai",
        "isimage": "noputan do upa",
index b1ed3d9..99021a1 100644 (file)
        "whatlinkshere": "याँखाइ कि जोणीन्छ",
        "whatlinkshere-title": "$1 सित जोडियाऽ पन्नाअन",
        "whatlinkshere-page": "पानो",
-       "linkshere": "निम्न पानाहरू '''[[:$1]]''' मी जुडन्छ :",
-       "nolinkshere-ns": "चुनियाको नामस्थानमी '''[[:$1]]''' सित जुड्न्या पानाहरू नाइथिन्।",
+       "linkshere-2": "निम्न पानाहरू '''$1''' मी जुडन्छ :",
+       "nolinkshere-ns-2": "चुनियाको नामस्थानमी '''$1''' सित जुड्न्या पानाहरू नाइथिन्।",
        "isredirect": "अनुप्रेषित पानो",
        "istemplate": "पारदर्शिता",
        "isimage": "फाइल लिङ्क",
        "redirect-revision": "पन्ना संशोधन",
        "redirect-file": "फाइलनाउँ",
        "specialpages": "खास पन्नाअन",
+       "specialpages-note-restricted": "* साधारण खास पानाहरू।\n* <span class=\"mw-specialpagerestricted\">निषेधित खास पानाहरू।</span>",
        "specialpages-group-changes": "अल्लैका परिवर्तन लगहरू",
        "tags": "मान्य परिवर्तन ट्यागहरू",
        "tag-filter": "[[Special:Tags|पुछड]] छानिन्या",
index 2e187cc..e8cbc3f 100644 (file)
        "whatlinkshere": "A pûnten ché",
        "whatlinkshere-title": "Pàgini che pûnten a \"$1\"",
        "whatlinkshere-page": "Pàgina:",
-       "linkshere": "Al pàgini segvèinti a gh'àn di colegamèint a '''[[:$1]]'''.",
-       "nolinkshere": "Nisóna pàgina la gh'à dèinter colegamèint che pûnten a '''[[:$1]]'''.",
+       "linkshere-2": "Al pàgini segvèinti a gh'àn di colegamèint a '''$1'''.",
+       "nolinkshere-2": "Nisóna pàgina la gh'à dèinter colegamèint che pûnten a '''$1'''.",
        "isredirect": "Pàgina redirect",
        "istemplate": "uniòun",
        "isimage": "Colegamèint vêrs al file",
index f54ef28..ec816d5 100644 (file)
        "subject-preview": "Προεπισκόπηση θέματος:",
        "previewerrortext": "Παρουσιάστηκε σφάλμα κατά την προσπάθεια για να κάνετε προεπισκόπηση των αλλαγών σας.",
        "blockedtitle": "Ο χρήστης έχει υποστεί φραγή.",
-       "blockedtext": "'''Το όνομα χρήστη σας ή η διεύθυνση IP σας έχει υποστεί φραγή.'''\n\nΗ φραγή έγινε από τον/την $1.\nΗ αιτιολογία που δόθηκε είναι: ''$2''.\n\n* Έναρξη φραγής: $8\n* Λήξη φραγής: $6\n* Η φραγή προορίζεται για το χρήστη: $7\n\nΜπορείτε να απευθυνθείτε στον/στην $1 ή σε κάποιον άλλον [[{{MediaWiki:Grouppage-sysop}}|διαχειριστή]] για να συζητήσετε τη φραγή.\nΔεν μπορείτε να χρησιμοποιήσετε την δυνατότητα «αποστολή e-mail σε αυτό το χρήστη» εκτός αν μια έγκυρη ηλεκτρονική διεύθυνση έχει οριστεί στις [[Special:Preferences|προτιμήσεις χρήστη]] σας.\nΗ τρέχουσα διεύθυνση IP σας είναι $3, και ο αριθμός αναγνώρισης της φραγής είναι #$5.\nΠαρακαλούμε περιλαμβάνετε οποιοδήποτε ή και τα δύο από αυτά σε οποιαδήποτε ερωτήματα σας.",
+       "blockedtext": "<strong>Το όνομα χρήστη σας ή η διεύθυνση IP σας έχει υποστεί φραγή.</strong>\n\nΗ φραγή έγινε από τον/την $1.\nΗ αιτιολογία που δόθηκε είναι: <em>$2</em>.\n\n* Έναρξη φραγής: $8\n* Λήξη φραγής: $6\n* Η φραγή προορίζεται για το χρήστη: $7\n\nΜπορείτε να απευθυνθείτε στον/στην $1 ή σε κάποιον άλλον [[{{MediaWiki:Grouppage-sysop}}|διαχειριστή]] για να συζητήσετε τη φραγή.\nΔεν μπορείτε να χρησιμοποιήσετε την δυνατότητα \"{{int:emailuser}}\" εκτός αν μια έγκυρη ηλεκτρονική διεύθυνση έχει οριστεί στις [[Special:Preferences|προτιμήσεις χρήστη]] σας.\nΗ τρέχουσα διεύθυνση IP σας είναι $3, και ο αριθμός αναγνώρισης της φραγής είναι #$5.\nΠαρακαλούμε περιλαμβάνετε οποιοδήποτε ή και τα δύο από αυτά σε οποιαδήποτε ερωτήματα σας.",
        "autoblockedtext": "Η διεύθυνση IP σας έχει υποστεί φραγή αυτόματα επειδή χρησιμοποιήθηκε από έναν άλλο χρήστη, ο οποίος και αποκλείστηκε από τον/την $1.\nΗ αιτιολόγηση που δόθηκε είναι η εξής:\n\n:<em>$2</em>\n\n* Έναρξη φραγής: $8\n* Λήξη φραγής: $6\n* Επιδιωκόμενος αποκλεισμένος: $7\n\nΜπορείτε να επικοινωνήσετε με τον/την $1 ή με κάποιον από τους άλλους [[{{MediaWiki:Grouppage-sysop}}|διαχειριστές]] για να συζητήσετε τη φραγή.\n\nΝα σημειωθεί ότι δεν μπορείτε να χρησιμοποιήσετε τη λειτουργία «αποστολή μηνύματος ηλεκτρονικού ταχυδρομείου σε αυτόν τον χρήστη» εκτός αν έχετε μια έγκυρη διεύθυνση ηλεκτρονικού ταχυδρομείου καταχωρισμένη στις [[Special:Preferences|προτιμήσεις χρήστη]] σας.\n\nΗ τρέχουσα διεύθυνση IP σας είναι $3 και το αναγνωριστικό της φραγής σας είναι #$5. Παρακαλούμε συμπεριλάβετε τις παραπάνω λεπτομέρειες σε όποια ερωτήματα κάνετε.",
        "systemblockedtext": "Το όνομα χρήστη σας ή η διεύθυνση IP έχει αποκλειστεί αυτόματα από το MediaWiki.\nΗ αιτία που δόθηκε είναι:\n\n:<em>$2</em>\n\n* Έναρξη φραγής: $8\n* Λήξη φραγής: $6\n* Στόχος φραγής: $7\n\nΗ τρέχουσα διεύθυνση IP σας είναι $3.\nΠαρακαλούμε να συμπεριλάβετε όλα τα παραπάνω στοιχεία σε τυχόν απορίες σας.",
        "blockednoreason": "δεν δόθηκε λόγος",
        "sp-deletedcontributions-contribs": "συνεισφορές",
        "linksearch": "Αναζήτηση εξωτερικών συνδέσμων",
        "linksearch-pat": "Μοτίβο αναζήτησης:",
-       "linksearch-ns": "ΠεÏ\81ιοÏ\87ή:",
+       "linksearch-ns": "Î\9fνομαÏ\84οÏ\87Ï\8eÏ\81οÏ\82:",
        "linksearch-ok": "Αναζήτηση",
        "linksearch-text": "Μπορούν να χρησιμοποιηθούν χαρακτήρες μπαλαντέρ όπως \"*.wikipedia.org\". \nΧρειάζεται τουλάχιστον μια κατάληξη ανωτάτου επιπέδου, για παράδειγμα \"*.org\".<br />\n{{PLURAL:$2|Υποστηριζόμενο πρωτόκολλο|Υποστηριζόμενα πρωτόκολλα}}: $1 (αν δεν οριστεί πρωτόκολλο η προεπιλογή είναι http://).",
        "linksearch-line": "Η σελίδα $1 συνδέεται από την $2",
        "whatlinkshere": "Τι συνδέει εδώ",
        "whatlinkshere-title": "Σελίδες που συνδέουν στη σελίδα «$1»",
        "whatlinkshere-page": "Σελίδα:",
-       "linkshere": "Οι ακόλουθες σελίδες συνδέουν στη σελίδα '''[[:$1]]''':",
-       "nolinkshere": "Δεν υπάρχουν σελίδες που να συνδέουν στη σελίδα '''[[:$1]]'''.",
-       "nolinkshere-ns": "Καμία σελίδα δεν συνδέει στο '''[[:$1]]''' στον επιλεγμένο ονοματοχώρο.",
+       "linkshere-2": "Οι ακόλουθες σελίδες συνδέουν στη σελίδα '''$1''':",
+       "nolinkshere-2": "Δεν υπάρχουν σελίδες που να συνδέουν στη σελίδα '''$1'''.",
+       "nolinkshere-ns-2": "Καμία σελίδα δεν συνδέει στο '''$1''' στον επιλεγμένο ονοματοχώρο.",
        "isredirect": "σελίδα ανακατεύθυνσης",
        "istemplate": "ενσωμάτωση",
        "isimage": "σύνδεσμος αρχείου",
        "fileduplicatesearch-noresults": "Δεν βρέθηκε κανένα αρχείο με το όνομα «$1».",
        "specialpages": "Ειδικές σελίδες",
        "specialpages-note-top": "Υπόμνημα",
+       "specialpages-note-restricted": "* Κανονικές ειδικές σελίδες.\n* <span class=\"mw-specialpagerestricted\">Ειδικές σελίδες με περιορισμούς.</span>",
        "specialpages-group-maintenance": "Αναφορές συντήρησης",
        "specialpages-group-other": "Άλλες ειδικές σελίδες",
        "specialpages-group-login": "Σύνδεση / δημιουργία λογαριασμού",
index ca3a000..f07453b 100644 (file)
        "italic_sample": "Italic text",
        "savearticle": "Save page",
        "anonpreviewwarning": "<em>You are not logged in. Saving will record your IP address in this page's edit history.</em>",
-       "blockedtext": "<strong>Your username or IP address has been blocked.</strong>\n\nThe block was made by $1.\nThe reason given is <em>$2</em>.\n\n* Start of block: $8\n* Expiry of block: $6\n* Intended blockee: $7\n\nYou can contact $1 or another [[{{MediaWiki:Grouppage-sysop}}|administrator]] to discuss the block.\nYou cannot use the \"email this user\" feature unless a valid email address is specified in your [[Special:Preferences|account preferences]] and you have not been blocked from using it.\nYour current IP address is $3, and the block ID is #$5.\nPlease include all above details in any queries you make.",
+       "blockedtext": "<strong>Your username or IP address has been blocked.</strong>\n\nThe block was made by $1.\nThe reason given is <em>$2</em>.\n\n* Start of block: $8\n* Expiration of block: $6\n* Intended blockee: $7\n\nYou can contact $1 or another [[{{MediaWiki:Grouppage-sysop}}|administrator]] to discuss the block.\nYou cannot use the \"{{int:emailuser}}\" feature unless a valid e-mail address is specified in your [[Special:Preferences|account preferences]] and you have not been blocked from using it.\nYour current IP address is $3, and the block ID is #$5.\nPlease include all above details in any queries you make.",
        "autoblockedtext": "Your IP address has been automatically blocked because it was used by another user, who was blocked by $1.\nThe reason given is:\n\n:<em>$2</em>\n\n* Start of block: $8\n* Expiry of block: $6\n* Intended blockee: $7\n\nYou may contact $1 or one of the other [[{{MediaWiki:Grouppage-sysop}}|administrators]] to discuss the block.\n\nNote that you may not use the \"email this user\" feature unless you have a valid email address registered in your [[Special:Preferences|user preferences]] and you have not been blocked from using it.\n\nYour current IP address is $3, and the block ID is #$5.\nPlease include all above details in any queries you make.",
        "loginreqlink": "log in",
        "noarticletext": "There is currently no text in this page.\nYou can [[Special:Search/{{PAGENAME}}|search for this page title]] in other pages,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs],\nor [{{fullurl:{{FULLPAGENAME}}|action=edit}} create this page]</span>.",
        "boteditletter": "b",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} after change",
        "recentchangeslinked-toolbox": "Related changes",
-       "recentchangeslinked-summary": "This is a list of changes made recently to pages linked from a specified page (or to members of a specified category).\nPages on [[Special:Watchlist|your watchlist]] are <strong>bold</strong>.",
+       "recentchangeslinked-summary": "Enter a page name to see changes on the pages linked to or from that page. (To see members of a category, enter \"{{ns:category}}:Name of category\"). Changes to pages on [[Special:Watchlist|your Watchlist]] are highlighted in <strong>bold</strong>.",
        "upload": "Upload file",
        "license": "Licencing:",
        "license-header": "Licencing",
        "newpages": "New pages",
        "allpagessubmit": "Go",
        "listgrants-summary": "The following is a list of grants with their associated access to user rights. Users can authorise applications to use their account, but with limited permissions based on the grants the user gave to the application. An application acting on behalf of a user cannot actually use rights that the user does not have however.\nThere may be [[{{MediaWiki:Listgrouprights-helppage}}|additional information]] about individual rights.",
+       "emailuser": "E-mail this user",
        "wlshowhidecategorization": "page categorisation",
        "rollbacklink": "rollback",
        "sessionfailure": "There seems to be a problem with your login session;\nthis action has been cancelled as a precaution against session hijacking.\nGo back to the previous page, reload that page and then try again.",
        "tooltip-t-whatlinkshere": "A list of all wiki pages that link here",
        "tooltip-t-recentchangeslinked": "Recent changes in pages linked from this page",
        "tooltip-feed-atom": "Atom feed for this page",
+       "tooltip-t-emailuser": "Send an e-mail to {{GENDER:$1|this user}}",
        "tooltip-t-upload": "Upload files",
        "tooltip-t-specialpages": "A list of all special pages",
        "tooltip-t-print": "Printable version of this page",
index 4befdc5..837e3b5 100644 (file)
        "subject-preview": "Preview of subject:",
        "previewerrortext": "An error occurred while attempting to preview your changes.",
        "blockedtitle": "User is blocked",
-       "blockedtext": "<strong>Your username or IP address has been blocked.</strong>\n\nThe block was made by $1.\nThe reason given is <em>$2</em>.\n\n* Start of block: $8\n* Expiration of block: $6\n* Intended blockee: $7\n\nYou can contact $1 or another [[{{MediaWiki:Grouppage-sysop}}|administrator]] to discuss the block.\nYou cannot use the \"email this user\" feature unless a valid email address is specified in your [[Special:Preferences|account preferences]] and you have not been blocked from using it.\nYour current IP address is $3, and the block ID is #$5.\nPlease include all above details in any queries you make.",
-       "autoblockedtext": "Your IP address has been automatically blocked because it was used by another user, who was blocked by $1.\nThe reason given is:\n\n:<em>$2</em>\n\n* Start of block: $8\n* Expiration of block: $6\n* Intended blockee: $7\n\nYou may contact $1 or one of the other [[{{MediaWiki:Grouppage-sysop}}|administrators]] to discuss the block.\n\nNote that you may not use the \"email this user\" feature unless you have a valid email address registered in your [[Special:Preferences|user preferences]] and you have not been blocked from using it.\n\nYour current IP address is $3, and the block ID is #$5.\nPlease include all above details in any queries you make.",
+       "blockedtext": "<strong>Your username or IP address has been blocked.</strong>\n\nThe block was made by $1.\nThe reason given is <em>$2</em>.\n\n* Start of block: $8\n* Expiration of block: $6\n* Intended blockee: $7\n\nYou can contact $1 or another [[{{MediaWiki:Grouppage-sysop}}|administrator]] to discuss the block.\nYou cannot use the \"{{int:emailuser}}\" feature unless a valid email address is specified in your [[Special:Preferences|account preferences]] and you have not been blocked from using it.\nYour current IP address is $3, and the block ID is #$5.\nPlease include all above details in any queries you make.",
+       "autoblockedtext": "Your IP address has been automatically blocked because it was used by another user, who was blocked by $1.\nThe reason given is:\n\n:<em>$2</em>\n\n* Start of block: $8\n* Expiration of block: $6\n* Intended blockee: $7\n\nYou may contact $1 or one of the other [[{{MediaWiki:Grouppage-sysop}}|administrators]] to discuss the block.\n\nNote that you may not use the \"{{int:emailuser}}\" feature unless you have a valid email address registered in your [[Special:Preferences|user preferences]] and you have not been blocked from using it.\n\nYour current IP address is $3, and the block ID is #$5.\nPlease include all above details in any queries you make.",
        "systemblockedtext": "Your username or IP address has been automatically blocked by MediaWiki.\nThe reason given is:\n\n:<em>$2</em>\n\n* Start of block: $8\n* Expiration of block: $6\n* Intended blockee: $7\n\nYour current IP address is $3.\nPlease include all above details in any queries you make.",
        "blockednoreason": "no reason given",
        "whitelistedittext": "Please $1 to edit pages.",
        "listusers": "User list",
        "listusers-summary": "",
        "listusers-editsonly": "Show only users with edits",
+       "listusers-temporarygroupsonly": "Show only users in temporary user groups",
        "listusers-creationsort": "Sort by creation date",
        "listusers-desc": "Sort in descending order",
        "usereditcount": "$1 {{PLURAL:$1|edit|edits}}",
        "apisandbox-dynamic-parameters-add-label": "Add parameter:",
        "apisandbox-dynamic-parameters-add-placeholder": "Parameter name",
        "apisandbox-dynamic-error-exists": "A parameter named \"$1\" already exists.",
+       "apisandbox-templated-parameter-reason": "This [[Special:ApiHelp/main#main/templatedparams|templated parameter]] is offered based on the {{PLURAL:$1|value|values}} of $2.",
        "apisandbox-deprecated-parameters": "Deprecated parameters",
        "apisandbox-fetch-token": "Auto-fill the token",
        "apisandbox-add-multi": "Add",
        "whatlinkshere-title": "Pages that link to \"$1\"",
        "whatlinkshere-summary": "",
        "whatlinkshere-page": "Page:",
-       "linkshere": "The following pages link to <strong>[[:$1]]</strong>:",
-       "nolinkshere": "No pages link to <strong>[[:$1]]</strong>.",
-       "nolinkshere-ns": "No pages link to <strong>[[:$1]]</strong> in the chosen namespace.",
+       "linkshere-2": "The following pages link to <strong>$1</strong>:",
+       "nolinkshere-2": "No pages link to <strong>$1</strong>.",
+       "nolinkshere-ns-2": "No pages link to <strong>$1</strong> in the chosen namespace.",
        "isredirect": "redirect page",
        "istemplate": "transclusion",
        "isimage": "file link",
        "pagedata-title": "Page data",
        "pagedata-text": "This page provides a data interface to pages. Please provide the page title in the URL, using subpage syntax.\n* Content negotiation applies based on your client's Accept header. This means that the page data will be provided in the format preferred by your client.",
        "pagedata-not-acceptable": "No matching format found. Supported MIME types: $1",
-       "pagedata-bad-title": "Invalid title: $1."
+       "pagedata-bad-title": "Invalid title: $1.",
+       "unregistered-user-config": "For security reasons JavaScript, CSS and JSON user subpages cannot be loaded for unregistered users.",
+       "passwordpolicies": "Password policies",
+       "passwordpolicies-summary": "This is a list of the effective password policies for the user groups defined in this wiki.",
+       "passwordpolicies-group": "Group",
+       "passwordpolicies-policies": "Policies",
+       "passwordpolicies-policy-display": "<span class=\"passwordpolicies-policy\">$1 <code>($2)</code></span>",
+       "passwordpolicies-policy-minimalpasswordlength": "Password must be at least $1 {{PLURAL:$1|character|characters}} long",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Password must be at least $1 {{PLURAL:$1|character|characters}} long to be able to login",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Password cannot be the same as username",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Password cannot match specifically blacklisted passwords",
+       "passwordpolicies-policy-maximalpasswordlength": "Password must be less than $1 {{PLURAL:$1|character|characters}} long",
+       "passwordpolicies-policy-passwordcannotbepopular": "Password cannot be {{PLURAL:$1|the popular password|in the list of $1 popular passwords}}"
 }
index 7353f90..cebd18b 100644 (file)
        "botpasswords-existing": "Ekzistantaj robotaj pasvortoj",
        "botpasswords-createnew": "Krei novan robotan pasvorton",
        "botpasswords-editexisting": "Redakti ekzistantan robotan pasvorton",
+       "botpasswords-label-needsreset": "(oni devas rekomencigi la pasvorton)",
        "botpasswords-label-appid": "Robota nomo:",
        "botpasswords-label-create": "Krei",
        "botpasswords-label-update": "Ĝisdatigi",
        "subject-preview": "Antaŭrigardo de temo:",
        "previewerrortext": "Dum provo antaŭrigardi viajn ŝanĝojn okazis eraro.",
        "blockedtitle": "La uzanto estas forbarita.",
-       "blockedtext": "'''Via konto aŭ IP-adreso estis forbarita'''\n\nLa forbaro estis farita de $1.\nLa skribita kialo estas ''$2''.\n\n* Komenco de forbaro: $8\n* Findato de forbarado: $6\n* Intencita forbarito: $7\n\nVi rajtas kontakti $1 aŭ alian [[{{MediaWiki:Grouppage-sysop}}|administranton]] por pridiskuti la forbaradon.\nVi ne povas uzi la 'retpoŝtan' funkcion, escepte se vi indikis validan retpoŝtan adreson en viaj [[Special:Preferences|kontaj agordoj]] kaj vi ne estas blokita uzi ĝin.\nVia IP-adreso estas $3 kaj la ID de la forbarado estas $5.\nBonvolu mencii jenajn indikojn en viaj ĉi-temaj kontaktoj.",
+       "blockedtext": "'''Via konto aŭ IP-adreso estis blokita'''\n\nLa bloko estis farita de $1.\nLa skribita kialo estas ''$2''.\n\n* Komenco de forbaro: $8\n* Findato de forbarado: $6\n* Intencita forbarito: $7\n\nVi rajtas kontakti $1 aŭ alian [[{{MediaWiki:Grouppage-sysop}}|administranton]] por pridiskuti la forbaradon.\nVi ne povas uzi la funkcion “{{int:emailuser}}”, escepte se vi indikis validan retpoŝtan adreson en viaj [[Special:Preferences|kontaj agordoj]] kaj vi ne estas blokita uzi ĝin.\nVia IP-adreso estas $3 kaj la ID de la forbarado estas $5.\nBonvolu mencii jenajn indikojn en viaj ĉi-temaj kontaktoj.",
        "autoblockedtext": "Via IP-adreso estas aŭtomate forbarita, ĉar uzis ĝin alia uzanto, kiun baris $1.\nLa donita kialo estas:\n\n:''$2''\n\n*Komenco de forbaro: $8\n*Limdato de la blokado: $6\n*Intencis forbari uzanton: $7\n\nVi povas kontakti $1 aŭ iun ajn el la aliaj [[{{MediaWiki:Grouppage-sysop}}|administrantojn]] por diskuti la blokon.\n\nNotu, ke vi ne povas uzi la servon \"Retpoŝtu ĉi tiu uzanton\" krom se vi havas validan retpoŝt-adreson registritan en viaj [[Special:Preferences|preferojn]], kaj vi estas ne blokita kontraŭ ĝia uzado.\n\nVia nuna IP-adreso estas $3, kaj la forbaro-identigo estas $5.\nBonvolu inkluzivi tiujn detalojn en iuj ajn demandoj kiun vi farus.",
        "systemblockedtext": "Via salutnomo aŭ IPa adreso estis aŭtomate forbarita de MediaWiki.\nLa kialo donita estas:\n\n:<em>$2</em>\n\n* Komenco de forbaro: $8\n* Eksvalidiĝo de forbaro: $6\n* Intenca forbarulo: $7\n\nVia nuna IPa adreso estas $3.\nBonvolu inkluzivi ĉiuj supraj detaloj en ajnaj demandoj vi faras.",
        "blockednoreason": "neniu kialo estis donita",
        "recentchangeslinked-feed": "Rilataj paĝoj",
        "recentchangeslinked-toolbox": "Rilataj ŝanĝoj",
        "recentchangeslinked-title": "Ŝanĝoj rilataj al \"$1\"",
-       "recentchangeslinked-summary": "Entajpu nomon de paĝo por vidi ŝanĝojn sur paĝoj ligitaj el aŭ al tiu ĉi paĝo. (Por vidi anojn de kategorio, entajpu Category:nomo de kategorio). Ŝanĝoj sur paĝoj en [[Special:Watchlist|via atentaro]] markiĝas <strong>grase</strong>.",
+       "recentchangeslinked-summary": "Entajpu nomon de paĝo por vidi ŝanĝojn sur paĝoj ligitaj el aŭ al tiu ĉi paĝo. (Por vidi anojn de kategorio, entajpu {{ns:category}}:nomon de kategorio). Ŝanĝoj sur paĝoj en [[Special:Watchlist|via atentaro]] markiĝas <strong>grase</strong>.",
        "recentchangeslinked-page": "Nomo de paĝo:",
        "recentchangeslinked-to": "Montru ŝanĝojn al paĝoj ligitaj al la specifa paĝo anstataŭe.",
        "recentchanges-page-added-to-category": "[[:$1]] aldonita al la kategorio",
        "whatlinkshere": "Ligiloj ĉi tien",
        "whatlinkshere-title": "Paĝoj ligantaj al \"$1\"",
        "whatlinkshere-page": "Paĝo:",
-       "linkshere": "La jenaj paĝoj ligas al '''[[:$1]]''':",
-       "nolinkshere": "Neniu paĝo ligas al '''[[:$1]]'''.",
-       "nolinkshere-ns": "Neniuj paĝoj ligas al '''[[:$1]]''' en la elektita nomspaco.",
+       "linkshere-2": "La jenaj paĝoj ligas al '''$1''':",
+       "nolinkshere-2": "Neniu paĝo ligas al '''$1'''.",
+       "nolinkshere-ns-2": "Neniuj paĝoj ligas al '''$1''' en la elektita nomspaco.",
        "isredirect": "alidirektilo",
        "istemplate": "inkludo",
        "isimage": "ligilo al dosiero",
        "fileduplicatesearch-noresults": "Neniu dosiero nomita \"$1\" troviĝis.",
        "specialpages": "Specialaj paĝoj",
        "specialpages-note-top": "Klarigo",
+       "specialpages-note-restricted": "* Normaj specialaj paĝoj.\n* <span class=\"mw-specialpagerestricted\">Limigitaj specialaj paĝoj.</span>",
        "specialpages-group-maintenance": "Raportoj pri prizorgado",
        "specialpages-group-other": "Aliaj specialaj paĝoj",
        "specialpages-group-login": "Ensaluti /  registriĝi",
index 7199df9..2fac3ff 100644 (file)
        "tog-watchlisthideminor": "Ocultar las ediciones menores de la lista de seguimiento",
        "tog-watchlisthideliu": "Ocultar las ediciones de los usuarios registrados de la lista de seguimiento",
        "tog-watchlistreloadautomatically": "Recargar la lista de seguimiento automáticamente cuando se modifica un filtro (requiere JavaScript)",
-       "tog-watchlistunwatchlinks": "Añadir enlaces directos para seguir o dejar de seguir las entradas de la lista de seguimiento (se requiere JavaScript para utilizar esta funcionalidad)",
+       "tog-watchlistunwatchlinks": "Añadir enlaces directos ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) para seguir o dejar de seguir las entradas de la lista de seguimiento (se requiere JavaScript para utilizar esta funcionalidad)",
        "tog-watchlisthideanons": "Ocultar las ediciones de los usuarios anónimos de la lista de seguimiento",
        "tog-watchlisthidepatrolled": "Ocultar las ediciones verificadas de la lista de seguimiento",
        "tog-watchlisthidecategorization": "Ocultar la categorización de páginas",
        "cascadeprotected": "Esta página ha sido protegida contra edición porque está transcluida en {{PLURAL:$1|la siguiente página protegida|las siguientes páginas protegidas}} con la opción de «cascada» activa:\n$2",
        "namespaceprotected": "No tienes permiso para editar las páginas del espacio de nombres <strong>$1</strong>.",
        "customcssprotected": "No tienes permiso para editar esta página CSS, porque contiene configuraciones personales de otro usuario.",
+       "customjsonprotected": "No tienes permiso para editar esta página JSON porque contiene configuraciones personales de otro usuario.",
        "customjsprotected": "No tienes permiso para editar esta página JavaScript, porque contiene configuraciones personales de otro usuario.",
        "mycustomcssprotected": "No tienes permiso para editar esta página CSS.",
        "mycustomjsonprotected": "No tienes permiso para editar esta página JSON.",
        "createacct-another-realname-tip": "El nombre real es opcional.\nSi lo proporcionas, se usará para dar atribución al trabajo del usuario.",
        "pt-login": "Acceder",
        "pt-login-button": "Acceder",
-       "pt-login-continue-button": "Continuar inicio de sesión",
+       "pt-login-continue-button": "Continuar con el acceso",
        "pt-createaccount": "Crear una cuenta",
        "pt-userlogout": "Salir",
        "php-mail-error-unknown": "Error desconocido en la función mail() de PHP.",
        "botpasswords-existing": "Contraseñas de bots existentes",
        "botpasswords-createnew": "Crear una contraseña de robot nueva",
        "botpasswords-editexisting": "Editar una contraseña de robot existente",
+       "botpasswords-label-needsreset": "(la contraseña debe restablecerse)",
        "botpasswords-label-appid": "Nombre del robot:",
        "botpasswords-label-create": "Crear",
        "botpasswords-label-update": "Actualizar",
        "botpasswords-restriction-failed": "Las restricciones de la contraseña de bot impiden este inicio de sesión.",
        "botpasswords-invalid-name": "El nombre de usuario especificado no contiene el separador de contraseña de bot (\"$1\").",
        "botpasswords-not-exist": "El usuario \"$1\" no tiene una contraseña de bot llamada \"$2\".",
+       "botpasswords-needs-reset": "Se debe restablecer la contraseña del robot «$2», propiedad {{GENDER:$1|del usuario|de la usuaria}} «$1».",
        "resetpass_forbidden": "No se pueden cambiar las contraseñas",
        "resetpass_forbidden-reason": "Las contraseñas no pueden cambiarse: $1",
        "resetpass-no-info": "Debes iniciar sesión para acceder directamente a esta página.",
        "subject-preview": "Previsualización del asunto:",
        "previewerrortext": "Se ha producido un error al intentar la vista previa de los cambios.",
        "blockedtitle": "El usuario está bloqueado",
-       "blockedtext": "<strong>Tu nombre de usuario o dirección IP ha sido bloqueada.</strong>\n\nEl bloqueo lo hizo $1.\nLa razón dada es <em>$2</em>.\n\n* Inicio del bloqueo: $8\n* Caducidad del bloqueo: $6\n* Bloqueo destinado a: $7\n\nPuedes contactar a $1 o con otro de los [[{{MediaWiki:Grouppage-sysop}}|administradores]] para discutir el bloqueo.\nNo puedes utilizar la función «enviar correo electrónico a este usuario» a menos que tengas una dirección de correo electrónico válida registrada en tus [[Special:Preferences|preferencias de usuario]] y la función no haya sido también bloqueada.\n\nTu dirección IP actual es $3, y el identificador del bloqueo es #$5.\nIncluye todos los datos aquí mostrados en cualquier consulta que hagas.",
-       "autoblockedtext": "Tu dirección IP ha sido bloqueada automáticamente porque fue utilizada por otro usuario, que resultó bloqueado por $1.\nEl motivo dado es el siguiente:\n\n:<em>$2</em>\n\n* Inicio del bloqueo: $8\n* Caducidad del bloqueo: $6\n* Bloqueo destinado a: $7\n\nPuedes contactar con $1 o con otro de los [[{{MediaWiki:Grouppage-sysop}}|administradores]] para discutir el bloqueo.\n\nTen en cuenta que no puedes utilizar la función «enviar correo electrónico a este usuario» a menos que tengas una dirección de correo electrónico válida registrada en tus [[Special:Preferences|preferencias de usuario]] y la función no haya sido también bloqueada.\n\nTu dirección IP actual es $3, y el identificador del bloqueo es #$5.\nIncluye todos los datos aquí mostrados en cualquier consulta que hagas.",
+       "blockedtext": "<strong>Tu nombre de usuario o dirección IP ha sido bloqueada.</strong>\n\nEl bloqueo fue realizado por $1.\nLa razón dada es <em>$2</em>.\n\n* Inicio del bloqueo: $8\n* Caducidad del bloqueo: $6\n* Bloqueo destinado a: $7\n\nPuedes contactar a $1 o con otro de los [[{{MediaWiki:Grouppage-sysop}}|administradores]] para discutir el bloqueo.\nNo puedes utilizar la función «{{int:emailuser}}» a menos que tengas una dirección de correo electrónico válida registrada en tus [[Special:Preferences|preferencias de usuario]] y el bloqueo no haya deshabilitado también esta posibilidad.\nTu dirección IP actual es $3, y el identificador del bloqueo es #$5.\nIncluye todos los datos aquí mostrados en cualquier consulta que hagas.",
+       "autoblockedtext": "Tu dirección IP ha sido bloqueada automáticamente porque fue utilizada por otro usuario, que resultó bloqueado por $1.\nEl motivo dado es el siguiente:\n\n:<em>$2</em>\n\n* Inicio del bloqueo: $8\n* Caducidad del bloqueo: $6\n* Bloqueo destinado a: $7\n\nPuedes contactar con $1 o con otro de los [[{{MediaWiki:Grouppage-sysop}}|administradores]] para discutir el bloqueo.\n\nObserva que no puedes utilizar la función «{{int:emailuser}}» a menos que hayas registrado una dirección de correo electrónico válida en tus [[Special:Preferences|preferencias de usuario]] y la función no haya sido también bloqueada.\n\nTu dirección IP actual es $3, y el identificador del bloqueo es n.º $5.\nIncluye todos los datos aquí mostrados en cualquier consulta que hagas.",
        "systemblockedtext": "Tu nombre de usuario o dirección IP ha sido bloqueado automáticamente por el software MediaWiki.\nLa razón dada es:\n\n:<em>$2</em>\n\n* Inicio del bloqueo: $8\n* Caducidad de bloqueo: $6\n* Destinatario del bloqueo: $7\n\nTu dirección IP actual es $3.\nPor favor, incluye todos los datos aquí mostrados en cualquier consulta que hagas.",
        "blockednoreason": "no se ha especificado el motivo",
        "whitelistedittext": "Tienes que $1 para editar páginas.",
        "userjsonyoucanpreview": "<strong>Consejo:</strong> usa el botón «{{int:showpreview}}» para probar el código JSON nuevo antes de guardarlo.",
        "userjsyoucanpreview": "<strong>Consejo:</strong> usa el botón «{{int:showpreview}}» para probar el código JavaScript nuevo antes de guardarlo.",
        "usercsspreview": "<strong>Recuerda que solo estás previsualizando tu CSS de usuario.\n¡Aún no se ha guardado!</strong>",
+       "userjsonpreview": "<strong>Recuerda que solo estas previsualizando tu configuración JSON de usuario. ¡Aún no se ha guardado!</strong>",
        "userjspreview": "<strong>¡Recuerda que solo estás previsualizando tu JavaScript de usuario.\n¡Aún no se ha guardado!</strong>",
        "sitecsspreview": "<strong>Recuerda que solo estás previsualizando este CSS.\n¡Aún no se ha guardado!</strong>",
+       "sitejsonpreview": "<strong>Recuerda que solo estas previsualizando esta configuración JSON. ¡Aún no se ha guardado!</strong>",
        "sitejspreview": "<strong>Recuerda que solo estás previsualizando este código JavaScript.\n¡Aún no se ha guardado!</strong>",
        "userinvalidconfigtitle": "<strong>Atención:</strong> no existe la apariencia «$1».\nLas páginas de archivos .css, .json y .js personalizados comienzan por minúscula; p. ej., se usa «{{ns:user}}:Ejemplo/vector.css» en vez de «{{ns:user}}:Ejemplo/Vector.css».",
        "updated": "(Actualizado)",
        "longpageerror": "<strong>Error: el texto que has enviado ocupa {{PLURAL:$1|un kilobyte|$1 kilobytes}}, que supera el máximo de {{PLURAL:$2|un kilobyte|$2 kilobytes}}.</strong>\nPor tanto, no lo podemos guardar.",
        "readonlywarning": "<strong>Advertencia: La base de datos ha sido bloqueada por labores de mantenimiento, así que en este momento no puedes guardar tus ediciones.</strong>\nQuizás quieras copiar y pegar tu texto en un archivo de texto y guardarlo para después.\n\nEl administrador que la bloqueó ha dado esta explicación: $1",
        "protectedpagewarning": "<strong>Advertencia: Esta página ha sido protegida para que solo puedan editarla los usuarios con permisos de administrador.</strong>\nA continuación se muestra la última entrada de registro para más información:",
-       "semiprotectedpagewarning": "<strong>Nota:</strong> Esta página ha sido protegida para que solo puedan editarla los usuarios registrados.\nA continuación se muestra la última entrada de registro para más información:",
+       "semiprotectedpagewarning": "<strong>Nota:</strong> Esta página ha sido protegida para que solo puedan editarla usuarios autoconfirmados.\nA continuación se muestra la última entrada de registro para más información:",
        "cascadeprotectedwarning": "<strong>Aviso:</strong> esta página está protegida y solo pueden editarla usuarios con [[Special:ListGroupRights|permisos específicos]] porque está transcluida en {{PLURAL:$1|la siguiente página protegida|las siguientes páginas protegidas}} en cascada:",
        "titleprotectedwarning": "<strong>Aviso: esta página está protegida de modo que se necesitan [[Special:ListGroupRights|permisos específicos]] para crearla.</strong>\nA continuación se muestra la última entrada del registro como referencia:",
        "templatesused": "{{PLURAL:$1|Plantilla usada|Plantillas usadas}} en esta página:",
        "prefs-watchlist-edits": "Número máximo de ediciones a mostrar en la lista de seguimiento:",
        "prefs-watchlist-edits-max": "Cantidad máxima: 1000",
        "prefs-watchlist-token": "Clave de lista de seguimiento:",
+       "prefs-watchlist-managetokens": "Gestionar fichas",
        "prefs-misc": "Varias",
        "prefs-resetpass": "Cambiar contraseña",
        "prefs-changeemail": "Cambiar o eliminar la dirección de correo electrónico",
        "recentchangescount": "Número de ediciones que mostrar de manera predeterminada en Cambios recientes, los historiales de las páginas y en los registros:",
        "prefs-help-recentchangescount": "Número máximo: 1000",
        "prefs-help-watchlist-token2": "Esta es la clave secreta del suministro web de tu lista de seguimiento.\nCualquiera que la conozca podrá consultar la lista, así que no la compartas.\n[[Special:ResetTokens|Puedes restablecerla si lo necesitas]].",
+       "prefs-help-tokenmanagement": "Puedes ver y reiniciar la clave secreta que te permite ver tu lista de seguimiento vía Web. Cualquier persona que conozca dicha clave podrá ver tu lista de seguimiento. No la compartas.",
        "savedprefs": "Se han guardado tus preferencias.",
        "savedrights": "Se han guardado los grupos de {{GENDER:$1|usuario|usuaria}} de $1.",
        "timezonelegend": "Huso horario:",
        "right-edituserjson": "Editar archivos JSON de otros usuarios",
        "right-edituserjs": "Editar las páginas de JavaScript de otros usuarios",
        "right-editmyusercss": "Editar tus archivos CSS",
+       "right-editmyuserjson": "Editar tus propias páginas en formato JSON",
        "right-editmyuserjs": "Editar tus archivos JavaScript",
        "right-viewmywatchlist": "Ver su propia lista de seguimiento",
        "right-editmywatchlist": "Editar su propia lista de seguimiento (algunas acciones seguirán añadiendo páginas aun sin este permiso).",
        "grant-createaccount": "Crear cuentas",
        "grant-createeditmovepage": "Crear, editar y trasladar páginas",
        "grant-delete": "Borrar páginas, revisiones y entradas del registro",
-       "grant-editinterface": "Editar el espacio de nombres MediaWiki y el CSS/JavaScript de usuarios",
+       "grant-editinterface": "Editar el espacio de nombres MediaWiki y el CSS/JSON/JavaScript de los usuarios",
        "grant-editmycssjs": "Editar tu CSS/JSON/JavaScript",
        "grant-editmyoptions": "Editar tus preferencias de usuario",
        "grant-editmywatchlist": "Editar tu lista de seguimiento",
        "rcfilters-filter-humans-label": "Ser humano (no robot)",
        "rcfilters-filter-humans-description": "Ediciones realizadas por editores humanos.",
        "rcfilters-filtergroup-reviewstatus": "Estado de revisión",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Ediciones no marcadas como revisadas manual o automáticamente.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "No patrulladas",
+       "rcfilters-filter-reviewstatus-manual-description": "Ediciones manualmente marcadas como revisadas.",
        "rcfilters-filter-reviewstatus-manual-label": "Verificado manualmente",
        "rcfilters-filter-reviewstatus-auto-description": "Ediciones por usuarios avanzados cuyo trabajo se marca automáticamente como verificado.",
        "rcfilters-filter-reviewstatus-auto-label": "Autoverificado",
        "recentchangeslinked-feed": "Cambios relacionados",
        "recentchangeslinked-toolbox": "Cambios relacionados",
        "recentchangeslinked-title": "Cambios relacionados con «$1»",
-       "recentchangeslinked-summary": "Escribe el nombre de una página para ver cambios realizados en páginas con enlaces entrantes o salientes a esa página. (Para ver lo que pertenece a una categoría, escribe «Categoría:Nombre de la categoría»). Los cambios en páginas de tu [[Special:Watchlist|lista de seguimiento]] aparecen en <strong>negrita</strong>.",
+       "recentchangeslinked-summary": "Introduce el nombre de una página para ver los cambios en las páginas enlazadas. (Para ver miembros de una categoría, introduce {{ns:category}}:Nombre de la categoría). Los cambios realizados a la páginas que tengas en tu [[Special:Watchlist|lista de seguimiento]] se resaltarán en <strong>negritas</strong>.",
        "recentchangeslinked-page": "Nombre de la página:",
        "recentchangeslinked-to": "Mostrar los cambios en páginas enlazadas con la página seleccionada",
        "recentchanges-page-added-to-category": "[[:$1]] añadida a la categoría",
        "protectedpages-params": "Parámetros de protección",
        "protectedpages-reason": "Motivo",
        "protectedpages-submit": "Mostrar páginas",
-       "protectedpages-unknown-timestamp": "Desconocido",
+       "protectedpages-unknown-timestamp": "Desconocidas",
        "protectedpages-unknown-performer": "Usuario desconocido",
        "protectedtitles": "Títulos protegidos",
        "protectedtitles-summary": "Esta página enumera títulos que actualmente están protegidos desde su creación. Para una lista de las páginas existentes que están protegidas, véase [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitles-submit": "Mostrar títulos",
        "listusers": "Lista de usuarios",
        "listusers-editsonly": "Muestra sólo usuarios con ediciones",
+       "listusers-temporarygroupsonly": "Mostrar solo usuarios en grupos de usuario temporales",
        "listusers-creationsort": "Ordenado por fecha de creación",
        "listusers-desc": "Ordenar de forma descendente",
        "usereditcount": "$1 {{PLURAL:$1|edición|ediciones}}",
        "apisandbox-dynamic-parameters-add-placeholder": "Nombre del parámetro",
        "apisandbox-dynamic-error-exists": "Ya existe un parámetro llamado \"$1\".",
        "apisandbox-deprecated-parameters": "Parámetros desaconsejados",
-       "apisandbox-fetch-token": "Auto-llenar el token",
+       "apisandbox-fetch-token": "Rellenar la ficha automáticamente",
        "apisandbox-add-multi": "Añadir",
        "apisandbox-submit-invalid-fields-title": "Algunos campos no son válidos",
        "apisandbox-submit-invalid-fields-message": "Corrige los campos señalados e inténtalo de nuevo.",
        "restriction-move": "Trasladar",
        "restriction-create": "Crear",
        "restriction-upload": "Subir",
-       "restriction-level-sysop": "completamente protegida",
-       "restriction-level-autoconfirmed": "semiprotegida",
+       "restriction-level-sysop": "protección completa",
+       "restriction-level-autoconfirmed": "semiprotección",
        "restriction-level-all": "cualquier nivel",
        "undelete": "Ver páginas borradas",
        "undeletepage": "Ver y restaurar páginas borradas",
        "whatlinkshere": "Lo que enlaza aquí",
        "whatlinkshere-title": "Páginas que enlazan con «$1»",
        "whatlinkshere-page": "Página:",
-       "linkshere": "Las siguientes páginas enlazan a <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Ninguna página enlaza con <strong>[[:$1]]</strong>.",
-       "nolinkshere-ns": "Ninguna página enlaza con <strong>[[:$1]]</strong> en el espacio de nombres elegido.",
+       "linkshere-2": "Las siguientes páginas enlazan a <strong>$1</strong>:",
+       "nolinkshere-2": "Ninguna página enlaza con <strong>$1</strong>.",
+       "nolinkshere-ns-2": "Ninguna página enlaza con <strong>$1</strong> en el espacio de nombres elegido.",
        "isredirect": "página redirigida",
        "istemplate": "inclusión",
        "isimage": "enlace de archivo",
        "group-bot.css": "/* Los estilos CSS colocados aquí se aplicarán para todos los usuarios del grupo Robots */",
        "group-sysop.css": "/* Los estilos CSS colocados aquí se aplicarán para todos los usuarios del grupo Administradores */",
        "group-bureaucrat.css": "/* Los estilos CSS colocados aquí se aplicarán para todos los usuarios del grupo Burócratas */",
+       "common.json": "/* Cualquier esquema JSON escrito aquí se cargará para todos los usuarios en cada carga de página. */",
        "common.js": "/* Cualquier código JavaScript escrito aquí se cargará para todos los usuarios en cada carga de página */",
        "group-autoconfirmed.js": "/* Cualquier código JavaScript escrito aquí se cargará para todos los usuarios del grupo Usuarios autoconfirmados */",
        "group-user.js": "/* Cualquier código JavaScript escrito aquí se cargará para todos los usuarios registrados */",
        "authform-nosession-login": "La autenticación fue exitosa, pero tu navegador no «recuerda» haber accedido a la cuenta.\n\n$1",
        "authform-nosession-signup": "Se ha creado la cuenta, pero tu navegador no «recuerda» haber accedido a ella.\n\n$1",
        "authform-newtoken": "Falta token. $1",
-       "authform-notoken": "Falta token",
-       "authform-wrongtoken": "Token incorrecto",
+       "authform-notoken": "Falta la ficha",
+       "authform-wrongtoken": "Ficha incorrecta",
        "specialpage-securitylevel-not-allowed-title": "No está permitido",
        "specialpage-securitylevel-not-allowed": "No puedes utilizar esta página porque no se pudo verificar tu identidad.",
        "authpage-cannot-login": "No se puede iniciar la sesión.",
        "pagedata-title": "Datos de la página",
        "pagedata-text": "Esta página provee una interfaz de datos a otras páginas. Por favor proporcione el título de la página en la URL usando la sintaxis de subpáginas.\n* La negociación del contenido se aplica en base a la cabecera Accept de su cliente. Esto significa que los datos de la página se proporcionarán en su formato de preferencia.",
        "pagedata-not-acceptable": "No se ha encontrado un formato coincidente. Tipos MIME admitidos: $1",
-       "pagedata-bad-title": "El título «$1» no es válido."
+       "pagedata-bad-title": "El título «$1» no es válido.",
+       "unregistered-user-config": "Por razones de seguridad, no se pueden cargar los códigos JavaScript, CSS o JSON localizados en subpáginas de usuarios no registrados.",
+       "passwordpolicies": "Normativas para contraseñas",
+       "passwordpolicies-summary": "Esta es una lista de políticas de contraseñas efectivas para cada grupo de usuarios definidos en este wiki.",
+       "passwordpolicies-group": "Grupo",
+       "passwordpolicies-policies": "Normativas",
+       "passwordpolicies-policy-minimalpasswordlength": "La contraseña debe tener al menos $1 {{PLURAL:$1|carácter|caracteres}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "La contraseña debe tener al menos $1 {{PLURAL:$1|carácter|caracteres}} para poder iniciar sesión",
+       "passwordpolicies-policy-passwordcannotmatchusername": "La contraseña no puede ser la misma que el nombre de usuario",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "La contraseña no puede coincidir con la lista de contraseñas específicamente prohibidas",
+       "passwordpolicies-policy-maximalpasswordlength": "La contraseña no puede tener más de $1 {{PLURAL:$1|caracter|caracteres}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "La contraseña no puede {{PLURAL:$1|ser la contraseña más popular|encontrarse en la lista de $1 contraseñas populares}}"
 }
index 9969926..abffdb9 100644 (file)
        "whatlinkshere": "Lingid siia",
        "whatlinkshere-title": "Leheküljed, mis viitavad lehele \"$1\"",
        "whatlinkshere-page": "Lehekülg:",
-       "linkshere": "Lehele '''[[:$1]]''' viitavad järgmised leheküljed:",
-       "nolinkshere": "Lehele '''[[:$1]]''' ei viita ükski lehekülg.",
-       "nolinkshere-ns": "Leheküljele <strong>[[:$1]]</strong> ei ole valitud nimeruumis linke.",
+       "linkshere-2": "Lehele '''$1''' viitavad järgmised leheküljed:",
+       "nolinkshere-2": "Lehele '''$1''' ei viita ükski lehekülg.",
+       "nolinkshere-ns-2": "Leheküljele <strong>$1</strong> ei ole valitud nimeruumis linke.",
        "isredirect": "ümbersuunamislehekülg",
        "istemplate": "kasutamine mallina",
        "isimage": "faililink",
index f100487..7417273 100644 (file)
        "savechanges": "Aldaketak gorde",
        "publishpage": "Orrialdea argitaratu",
        "publishchanges": "Aldaketak argitaratu",
+       "savearticle-start": "Gorde orria...",
        "savechanges-start": "Aldaketak gorde...",
        "publishpage-start": "Orrialdea argitaratu...",
        "publishchanges-start": "Aldaketak argitaratu...",
        "whatlinkshere": "Honanzko lotura duten orriak",
        "whatlinkshere-title": "$1(e)ra lotura duten orriak",
        "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.",
+       "linkshere-2": "Hauek dute '''$1''' orrialderako lotura:",
+       "nolinkshere-2": "Ez dago '''$1''' lotura duen orrialderik.",
+       "nolinkshere-ns-2": "Hautatutako izen-tartean ez dago '''$1''' orrialderako lotura duenik.",
        "isredirect": "birbideratze orrialdea",
        "istemplate": "erabilpena",
        "isimage": "fitxategi lotura",
        "permanentlink": "Lotura finkoa",
        "permanentlink-revid": "Berrikuspen IDa",
        "permanentlink-submit": "Berrikusketara joan",
-       "dberr-problems": "Barkatu! Webgune honek zailtasun teknikoak jasaten ari da.",
+       "dberr-problems": "Barkatu! Webgune hau zailtasun teknikoak izaten ari da.",
        "dberr-again": "Saiatu pare bat minutu itxaroten edo kargatu ezazu orrialdea berriro.",
        "dberr-info": "($1: Ezin da datu-basera konektatu)",
        "dberr-info-hidden": "(Ezin da konektatu datu-basera)",
index 59a32c5..73086be 100644 (file)
        "whatlinkshere": "Lo que atija aquina",
        "whatlinkshere-title": "Páhinas que atihan a $1",
        "whatlinkshere-page": "Páhina:",
-       "linkshere": "Las siguientis páhinas atihan a '''[[:$1]]''':",
-       "nolinkshere": "Denguna páhina atiha a '''[[:$1]]'''.",
-       "nolinkshere-ns": "Nu ai denguna páhina qu´atihi a '''[[:$1]]''' nel espaciu e nombris lihiu.",
+       "linkshere-2": "Las siguientis páhinas atihan a '''$1''':",
+       "nolinkshere-2": "Denguna páhina atiha a '''$1'''.",
+       "nolinkshere-ns-2": "Nu ai denguna páhina qu´atihi a '''$1''' nel espaciu e nombris lihiu.",
        "isredirect": "Rederihil páhina",
        "istemplate": "inclusión",
        "isimage": "atihu la imahin",
index 9a3dee6..1d17909 100644 (file)
        "whatlinkshere": "پیوندها به این صفحه",
        "whatlinkshere-title": "صفحه‌هایی که به «$1» پیوند دارند",
        "whatlinkshere-page": "صفحه:",
-       "linkshere": "صفحه‌های زیر به '''[[:$1]]''' پیوند دارند:",
-       "nolinkshere": "هیچ صفحه‌ای به '''[[:$1]]''' پیوند ندارد.",
-       "nolinkshere-ns": "هیچ صفحه‌ای از فضای نام انتخاب شده به '''[[:$1]]''' پیوند ندارد.",
+       "linkshere-2": "صفحه‌های زیر به '''$1''' پیوند دارند:",
+       "nolinkshere-2": "هیچ صفحه‌ای به '''$1''' پیوند ندارد.",
+       "nolinkshere-ns-2": "هیچ صفحه‌ای از فضای نام انتخاب شده به '''$1''' پیوند ندارد.",
        "isredirect": "صفحهٔ تغییرمسیر",
        "istemplate": "تراگنجانش‌ها",
        "isimage": "پیوند به پرونده",
index 0e22f6f..182e853 100644 (file)
        "botpasswords-existing": "Olemassaolevat bottisalasanat",
        "botpasswords-createnew": "Luo uusi bottisalasana",
        "botpasswords-editexisting": "Muokkaa olemassaolevaa bottisalasanaa",
+       "botpasswords-label-needsreset": "(salasanat täytyy nollata)",
        "botpasswords-label-appid": "Botin nimi:",
        "botpasswords-label-create": "Luo",
        "botpasswords-label-update": "Päivitä",
        "botpasswords-restriction-failed": "Bottisalasanan rajoitukset estävät tämän sisäänkirjautumisen.",
        "botpasswords-invalid-name": "Annetussa käyttäjätunnuksessa ei ole bottisalasanan erotinta (\"$1\").",
        "botpasswords-not-exist": "Käyttäjällä \"$1\" ei ole bottisalasanaa nimellä \"$2\".",
+       "botpasswords-needs-reset": "Bottisalasana {{GENDER:$1|käyttäjän}} \"$1\" bottinimelle \"$2\" täytyy nollata.",
        "resetpass_forbidden": "Salasanoja ei voi vaihtaa.",
        "resetpass_forbidden-reason": "Salasanoja ei voi muuttaa: $1",
        "resetpass-no-info": "Et voi nähdä tätä sivua kirjautumatta sisään.",
        "subject-preview": "Aiheotsikon esikatselu:",
        "previewerrortext": "Muokkaustesi esikatselun toteuttamisessa on tapahtunut virhe.",
        "blockedtitle": "Käyttäjä on estetty",
-       "blockedtext": "'''Käyttäjätunnuksesi tai IP-osoitteesi on estetty.'''\n\nEston on asettanut $1.\nSyy: '''$2'''\n\n* Eston alkamisaika: $8\n* Eston päättymisaika: $6\n* Kohde: $7\n\nVoit keskustella ylläpitäjän $1 tai toisen [[{{MediaWiki:Grouppage-sysop}}|ylläpitäjän]] kanssa estosta.\nHuomaa, ettet voi lähettää sähköpostia {{GRAMMAR:genitive|{{SITENAME}}}} kautta, ellet ole asettanut olemassa olevaa sähköpostiosoitetta [[Special:Preferences|asetuksissa]] tai jos esto on asetettu koskemaan myös sähköpostin lähettämistä.\nIP-osoitteesi on $3 ja estotunnus on #$5.\nLiitä kaikki yllä olevat tiedot mahdollisiin kyselyihisi.",
-       "autoblockedtext": "IP-osoitteesi on estetty automaattisesti, koska sitä on käyttänyt toinen käyttäjä, jonka on estänyt ylläpitäjä $1.\nEston syy on:\n\n:''$2''\n\n* Eston alkamisaika: $8\n* Eston päättymisaika: $6\n* Kohde: $7\n\nVoit keskustella ylläpitäjän $1 tai toisen [[{{MediaWiki:Grouppage-sysop}}|ylläpitäjän]] kanssa estosta.\n\nHuomaa, ettet voi lähettää sähköpostia {{GRAMMAR:genitive|{{SITENAME}}}} kautta, ellet ole asettanut olemassa olevaa sähköpostiosoitetta [[Special:Preferences|asetuksissa]] tai jos esto on asetettu koskemaan myös sähköpostin lähettämistä.\n\nIP-osoitteesi on $3 ja estotunnus on #$5.\nLiitä kaikki yllä olevat tiedot mahdollisiin kyselyihisi.",
+       "blockedtext": "<strong>Käyttäjätunnuksesi tai IP-osoitteesi on estetty.</strong>\n\nEston on asettanut $1.\nAnnettu syy on <em>$2</em>.\n\n* Eston alkamisaika: $8\n* Eston päättymisaika: $6\n* Kohde: $7\n\nVoit keskustella ylläpitäjän $1 tai toisen [[{{MediaWiki:Grouppage-sysop}}|ylläpitäjän]] kanssa estosta.\nHuomaa, ettet voi lähettää sähköpostia {{GRAMMAR:genitive|{{SITENAME}}}} kautta, ellet ole asettanut olemassa olevaa sähköpostiosoitetta [[Special:Preferences|asetuksissa]] tai jos esto on asetettu koskemaan myös sähköpostin lähettämistä.\nIP-osoitteesi on $3 ja estotunnus on #$5.\nLiitä kaikki yllä olevat tiedot mahdollisiin kyselyihisi.",
+       "autoblockedtext": "IP-osoitteesi on estetty automaattisesti, koska sitä on käyttänyt toinen käyttäjä, jonka on estänyt ylläpitäjä $1.\nAnnettu syy on:\n\n:<em>$2</em>\n\n* Eston alkamisaika: $8\n* Eston päättymisaika: $6\n* Kohde: $7\n\nVoit keskustella ylläpitäjän $1 tai toisen [[{{MediaWiki:Grouppage-sysop}}|ylläpitäjän]] kanssa estosta.\n\nHuomaa, ettet voi lähettää sähköpostia {{GRAMMAR:genitive|{{SITENAME}}}} kautta, ellet ole asettanut olemassa olevaa sähköpostiosoitetta [[Special:Preferences|asetuksissa]] tai jos esto on asetettu koskemaan myös sähköpostin lähettämistä.\n\nIP-osoitteesi on $3 ja estotunnus on #$5.\nLiitä kaikki yllä olevat tiedot mahdollisiin kyselyihisi.",
        "systemblockedtext": "Käyttäjätunnuksesi tai IP-osoitteesi on automaattisesti estetty MediaWikin toimesta.\nAnnettu syy on:\n\n:<em>$2</em>\n\n* Start of block: $8\n* Expiration of block: $6\n* Intended blockee: $7\n\nTämänhetkinen IP-osoitteesi on $3.\nOle hyvä ja liitä kaikki yllä olevat tiedot mahdollisiin kyselyihisi.",
        "blockednoreason": "(syytä ei annettu)",
        "whitelistedittext": "Sinun täytyy $1, jotta voisit muokata sivuja.",
        "blocked-notice-logextract": "Tämä käyttäjä on tällä hetkellä estetty.\nAlla on viimeisin estolokin tapahtuma:",
        "clearyourcache": "<strong>Huomautus:</strong> Selaimen välimuisti pitää tyhjentää asetusten tallentamisen jälkeen, jotta muutokset tulisivat voimaan.\n* <strong>Firefox ja Safari:</strong> Napsauta <em>Shift</em>-näppäin pohjassa <em>Päivitä</em>, tai paina <em>Ctrl-F5</em> tai <em>Ctrl-R</em> (<em>⌘-R</em> Macilla)\n* <strong>Google Chrome:</strong> Paina <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> Macilla)\n* <strong>Internet Explorer:</strong> Napsauta <em>Ctrl</em>-näppäin pohjassa <em>Päivitä</em> tai paina <em>Ctrl-F5</em>\n* <strong>Opera:</strong> <em>Menu → Settings</em> (<em>Opera → Preferences</em> Macilla) ja sitten <em>Privacy & security → Clear browsing data → Cached images and files</em>.",
        "usercssyoucanpreview": "Voit testata uutta CSS:ää ennen tallennusta käyttämällä painiketta ”{{int:showpreview}}”.",
+       "userjsonyoucanpreview": "<strong>Vihje:</strong> Käytä \"{{int:showpreview}}\" painiketta testataksesi uutta JSON:iasi ennen tallentamista.",
        "userjsyoucanpreview": "Voit testata uutta JavaScriptiä ennen tallennusta käyttämällä painiketta ”{{int:showpreview}}”.",
        "usercsspreview": "'''Tämä on CSS:n esikatselu. Muutoksia ei ole vielä tallennettu.'''",
        "userjspreview": "'''Tämä on JavaScriptin esikatselu.'''",
        "recentchangeslinked-feed": "Linkitettyjen sivujen muutokset",
        "recentchangeslinked-toolbox": "Linkitettyjen sivujen muutokset",
        "recentchangeslinked-title": "Sivulta $1 linkitettyjen sivujen muutokset",
-       "recentchangeslinked-summary": "Kirjoita sivun nimi nähdäksesi muutokset sivuihin jotka on linkitetty tai ovat tältä sivulta. (Nähdäksesi luokan jäsenet, kirjoita {{ns:category}}:Luokan nimi). Muutokset sivuihin [[Special:Watchlist|tarkkailulistallasi]] on <strong>lihavoitu</strong>.",
+       "recentchangeslinked-summary": "Kirjoita sivun nimi nähdäksesi muutokset sivuihin, joista on linkki tähän sivuun tai joihin on linkki tältä sivulta. (Luokan sisällön saat näkyviin kirjoittamalla {{ns:category}}:Luokan nimen). Muutokset [[Special:Watchlist|tarkkailulistallasi]] oleviin sivuihin on <strong>lihavoitu</strong>.",
        "recentchangeslinked-page": "Sivun nimi:",
        "recentchangeslinked-to": "Näytä sen sijaan muutokset sivuihin, joista on linkki tähän sivuun",
        "recentchanges-page-added-to-category": "[[:$1]] lisätty luokkaan",
        "protectedtitles-submit": "Hae sivunimet",
        "listusers": "Käyttäjien luettelo",
        "listusers-editsonly": "Näytä vain käyttäjät, joilla on muokkauksia",
+       "listusers-temporarygroupsonly": "Näytä vain väliaikaisten käyttäjäryhmien käyttäjät",
        "listusers-creationsort": "Lajittele tunnuksen luontipäivämäärän mukaan",
        "listusers-desc": "Lajittele alenevassa järjestyksessä",
        "usereditcount": "$1 {{PLURAL:$1|muokkaus|muokkausta}}",
        "whatlinkshere": "Tänne viittaavat sivut",
        "whatlinkshere-title": "Sivut, jotka viittaavat sivulle $1",
        "whatlinkshere-page": "Sivu:",
-       "linkshere": "Seuraavilta sivuilta on linkki sivulle <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Sivulle <strong>[[:$1]]</strong> ei ole linkkejä.",
-       "nolinkshere-ns": "Sivulle <strong>[[:$1]]</strong> ei ole linkkejä valitussa nimiavaruudessa.",
+       "linkshere-2": "Seuraavilta sivuilta on linkki sivulle <strong>$1</strong>:",
+       "nolinkshere-2": "Sivulle <strong>$1</strong> ei ole linkkejä.",
+       "nolinkshere-ns-2": "Sivulle <strong>$1</strong> ei ole linkkejä valitussa nimiavaruudessa.",
        "isredirect": "ohjaussivu",
        "istemplate": "sisällytetty",
        "isimage": "tiedostolinkki",
        "undelete-cantcreate": "Et voi palauttaa tätä sivua, koska tällä nimellä ei ole olemassaolevaa sivua eikä sinulla ole oikeutta luoda tätä sivua.",
        "pagedata-title": "Sivudata",
        "pagedata-not-acceptable": "Vastaavaa muotoa ei löytynyt. Tuetut MIME-tyypit: $1",
-       "pagedata-bad-title": "Virheellinen otsikko: $1."
+       "pagedata-bad-title": "Virheellinen otsikko: $1.",
+       "passwordpolicies": "Salasanakäytännöt",
+       "passwordpolicies-group": "Ryhmä",
+       "passwordpolicies-policies": "Käytännöt",
+       "passwordpolicies-policy-minimalpasswordlength": "Salasanan on oltava ainakin $1 {{PLURAL:$1|merkki|merkkiä}} pitkä",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Salasana ei voi olla sama kuin käyttäjänimi",
+       "passwordpolicies-policy-maximalpasswordlength": "Salasanan on oltava vähemmän kuin $1 {{PLURAL:$1|merkki|merkkiä}} pitkä"
 }
index 9c39499..34b3a95 100644 (file)
        "whatlinkshere": "Hvat slóðar higar",
        "whatlinkshere-title": "Síður sum slóða til \"$1\"",
        "whatlinkshere-page": "Síða:",
-       "linkshere": "Hesar síður slóða til '''[[:$1]]''':",
-       "nolinkshere": "Ongar síður slóða til '''[[:$1]]'''.",
-       "nolinkshere-ns": "Ongar síður slóða til '''[[:$1]]''' í tí valda navnarúminum.",
+       "linkshere-2": "Hesar síður slóða til '''$1''':",
+       "nolinkshere-2": "Ongar síður slóða til '''$1'''.",
+       "nolinkshere-ns-2": "Ongar síður slóða til '''$1''' í tí valda navnarúminum.",
        "isredirect": "ávísingarsíða",
        "istemplate": "leggjast innan í",
        "isimage": "fílu slóð",
index 783a778..b0d2b27 100644 (file)
        "botpasswords-restriction-failed": "Les restrictions de mot de passe de robots empêchent cette connexion.",
        "botpasswords-invalid-name": "Le nom d’utilisateur spécifié ne contient pas de séparateur de mot de passe de robots (« $1 »).",
        "botpasswords-not-exist": "L’{{GENDER:$1|utilisateur|utilisatrice}} « $1 » n’a pas de mot de passe de robot nommé « $2 ».",
-       "botpasswords-needs-reset": "Le mot de passe du robot de nom \"$2\" de l'utilisat{{GENDER:$1|eur}} \"$1\" doit être réinitialisé.",
+       "botpasswords-needs-reset": "Le mot de passe du robot de nom « $2 » de l’utilisat{{GENDER:$1|eur|rice}} « $1 » doit être réinitialisé.",
        "resetpass_forbidden": "Les mots de passe ne peuvent pas être changés",
        "resetpass_forbidden-reason": "Les mots de passe ne peuvent pas être modifiés : $1",
        "resetpass-no-info": "Vous devez être connecté(e) pour accéder directement à cette page.",
        "subject-preview": "Aperçu du sujet :",
        "previewerrortext": "Une erreur s’est produite lors de la tentative de prévisualisation de vos modifications.",
        "blockedtitle": "L’utilisateur est bloqué.",
-       "blockedtext": "<strong>Votre compte utilisateur ou votre adresse IP a été bloqué.</strong>\n\nLe blocage a été effectué par $1.\nLa raison invoquée est la suivante : <em>$2</em>.\n\n* Début du blocage : $8\n* Expiration du blocage : $6\n* Compte bloqué : $7.\n\nVous pouvez contacter $1 ou un autre [[{{MediaWiki:Grouppage-sysop}}|administrateur]] pour en discuter.\nVous ne pouvez utiliser la fonction « {{int:emailuser}} » que si une adresse de courriel valide est spécifiée dans vos [[Special:Preferences|préférences]] et que si cette fonctionnalité n’a pas été bloquée.\nVotre adresse IP actuelle est $3 et votre identifiant de blocage est $5.\nVeuillez inclure tous les détails ci-dessus dans chacune des requêtes que vous ferez.",
-       "autoblockedtext": "Votre adresse IP a été bloquée automatiquement car elle a été utilisée par un autre utilisateur, lui-même bloqué par $1.\nLa raison invoquée est :\n\n: <em>$2</em>.\n\n* Début du blocage : $8\n* Expiration du blocage : $6\n* Compte bloqué : $7\n\nVous pouvez contacter $1 ou l’un des autres [[{{MediaWiki:Grouppage-sysop}}|administrateurs]] pour discuter de ce blocage.\n\nNotez que vous ne pourrez utiliser la fonctionnalité d’envoi de courriel que si vous avez une adresse de courriel validée dans vos [[Special:Preferences|préférences]] et que cette fonctionnalité n’a pas été désactivée.\n\nVotre adresse IP actuelle est $3, et le numéro de blocage est $5.\nVeuillez inclure tous les détails ci-dessus dans chacune des requêtes que vous ferez.",
+       "blockedtext": "<strong>Votre compte utilisateur ou votre adresse IP a été bloqué.</strong>\n\nLe blocage a été effectué par $1.\nLa raison invoquée est la suivante : <em>$2</em>.\n\n* Début du blocage : $8\n* Expiration du blocage : $6\n* Compte bloqué : $7.\n\nVous pouvez contacter $1 ou un autre [[{{MediaWiki:Grouppage-sysop}}|administrateur]] pour en discuter.\nVous ne pouvez utiliser la fonction « {{int:emailuser}} » que si une adresse de courriel valide est spécifiée dans vos [[Special:Preferences|préférences]] et que si cette fonctionnalité n’a pas été bloquée.\nVotre adresse IP actuelle est $3 et votre identifiant de blocage est $5.\nVeuillez inclure tous les détails ci-dessus dans chacune des requêtes que vous ferez.",
+       "autoblockedtext": "Votre adresse IP a été bloquée automatiquement car elle a été utilisée par un autre utilisateur, lui-même bloqué par $1.\nLa raison invoquée est :\n\n: <em>$2</em>.\n\n* Début du blocage : $8\n* Expiration du blocage : $6\n* Compte bloqué : $7\n\nVous pouvez contacter $1 ou l’un des autres [[{{MediaWiki:Grouppage-sysop}}|administrateurs]] pour discuter de ce blocage.\n\nNotez que vous ne pourrez utiliser la fonctionnalité « {{int:emailuser}} » que si vous avez une adresse de courriel validée dans vos [[Special:Preferences|préférences]] et que cette fonctionnalité n’a pas été désactivée.\n\nVotre adresse IP actuelle est $3, et le numéro de blocage est $5.\nVeuillez inclure tous les détails ci-dessus dans chacune des requêtes que vous ferez.",
        "systemblockedtext": "Votre nom d'utilisateur ou votre adresse IP ont été bloqués automatiquement par MediaWiki.\nLa raison donnée est la suivante:\n\n: <em>$2</em>.\n\n* Le début du blocage: $8\n* Expiration du délai de blocage: $6\n* Elément concerné: $7\n\nVotre adresse IP actuelle est $3.\nVeuillez inclure tous les détails ci-dessus dans chacune des requêtes que vous ferez.",
        "blockednoreason": "aucune raison donnée",
        "whitelistedittext": "Vous devez vous $1 pour avoir la permission de modifier le contenu.",
        "protectedtitles-submit": "Afficher les titres",
        "listusers": "Liste des utilisateurs",
        "listusers-editsonly": "Ne montrer que les utilisateurs ayant fait des modifications.",
+       "listusers-temporarygroupsonly": "N'afficher que les utilisateurs des groupes d'utilisateurs temporaires",
        "listusers-creationsort": "Trier par date de création",
        "listusers-desc": "Trier par ordre décroissant",
        "usereditcount": "$1 modification{{PLURAL:$1||s}}",
        "apisandbox-dynamic-parameters-add-label": "Ajout du paramètre:",
        "apisandbox-dynamic-parameters-add-placeholder": "Nom du paramètre",
        "apisandbox-dynamic-error-exists": "Un paramètre nommé \"$1\" existe déjà.",
+       "apisandbox-templated-parameter-reason": "Ce [[Special:ApiHelp/main#main/templatedparams|paramètre de modèle]] est offert d’après {{PLURAL:$1|la valeur|les valeurs}} de $2.",
        "apisandbox-deprecated-parameters": "Paramètres désuets",
        "apisandbox-fetch-token": "Auto-remplissage du jeton",
        "apisandbox-add-multi": "Ajouter",
        "whatlinkshere": "Pages liées",
        "whatlinkshere-title": "Pages qui pointent vers « $1 »",
        "whatlinkshere-page": "Page :",
-       "linkshere": "Les pages ci-dessous contiennent un lien vers <strong>[[:$1]]</strong> :",
-       "nolinkshere": "Aucune page ne contient de lien vers <strong>[[:$1]]</strong>.",
-       "nolinkshere-ns": "Aucune page ne contient de lien vers <strong>[[:$1]]</strong> dans l'espace de noms choisi.",
+       "linkshere-2": "Les pages ci-dessous contiennent un lien vers <strong>$1</strong> :",
+       "nolinkshere-2": "Aucune page ne contient de lien vers <strong>$1</strong>.",
+       "nolinkshere-ns-2": "Aucune page ne contient de lien vers <strong>$1</strong> dans l'espace de noms choisi.",
        "isredirect": "page de redirection",
        "istemplate": "inclusion",
        "isimage": "lien vers le fichier",
        "version-specialpages": "Pages spéciales",
        "version-parserhooks": "Greffons de l'analyseur syntaxique",
        "version-variables": "Variables",
-       "version-editors": "Contributeurs",
+       "version-editors": "Éditeurs",
        "version-antispam": "Prévention du pollupostage",
        "version-other": "Divers",
        "version-mediahandlers": "Manipulateurs de médias",
        "pagedata-title": "Données de page",
        "pagedata-text": "Cette page fournit une interface de données aux pages. Veuillez fournir le titre de la page dans l’URL en utilisant la syntaxe de sous-page.\n* La négociation de contenu s’applique d’après l’entête Accept de votre client. Cela veut dire que les données de la page seront fournies dans le format préféré par votre client.",
        "pagedata-not-acceptable": "Aucun format correspondant trouvé. Types MIME pris en charge : $1",
-       "pagedata-bad-title": "Titre non valide : $1."
+       "pagedata-bad-title": "Titre non valide : $1.",
+       "unregistered-user-config": "Pour des raisons de sécurité, les sous-pages utilisateur JavaScript, CSS et JSON ne peuvent pas être chargées pour les utilisateurs non inscrits.",
+       "passwordpolicies": "Règles concernant le mot de passe",
+       "passwordpolicies-summary": "Voici une liste des politiques des mots de passe effectifs pour les groupes d'utilisateurs de ce wiki.",
+       "passwordpolicies-group": "Groupe",
+       "passwordpolicies-policies": "Politiques",
+       "passwordpolicies-policy-minimalpasswordlength": "Les mots de passe doivent avoir au moins $1 caractère{{PLURAL:$1||s}} de long",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Les mots de passe doivent avoir au moins $1 caractère{{PLURAL:$1||s}} de long pour autoriser la connextion",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Le mot de passe ne peut pas être le même que le nom d'utilisateur",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Les mots de passe ne peuvent pas être identiques à ceux qui sont dans la liste noire.",
+       "passwordpolicies-policy-maximalpasswordlength": "Les mots de passe doivent avoir moins de $1 caractère{{PLURAL:$1||s}} de long",
+       "passwordpolicies-policy-passwordcannotbepopular": "Le mot de passe ne peut pas être {{PLURAL:$1|le mot de passe populaire|dans la liste des $1 mots de passe populaires}}"
 }
index 3794fb1..9607106 100644 (file)
        "whatlinkshere": "Pâges liyêes",
        "whatlinkshere-title": "Pâges que pouentont vers « $1 »",
        "whatlinkshere-page": "Pâge :",
-       "linkshere": "Cetes pâges contegnont un lim de vers <strong>[[:$1]]</strong> :",
-       "nolinkshere": "Niona pâge contint de lim de vers <strong>[[:$1]]</strong>.",
-       "nolinkshere-ns": "Niona pâge contint de lim de vers <strong>[[:$1]]</strong> dedens l’èspâço de noms chouèsi.",
+       "linkshere-2": "Cetes pâges contegnont un lim de vers <strong>$1</strong> :",
+       "nolinkshere-2": "Niona pâge contint de lim de vers <strong>$1</strong>.",
+       "nolinkshere-ns-2": "Niona pâge contint de lim de vers <strong>$1</strong> dedens l’èspâço de noms chouèsi.",
        "isredirect": "pâge de redirèccion",
        "istemplate": "transcllusion",
        "isimage": "lim de vers lo fichiér",
        "fileduplicatesearch-noresults": "Nion fichiér apelâ « $1 » est étâ trovâ.",
        "specialpages": "Pâges spèciâles",
        "specialpages-note-top": "Lègenda",
+       "specialpages-note-restricted": "* Pâges spèciâles normales.\n* <span class=\"mw-specialpagerestricted\">Pâges spèciâles rètrentes.</span>",
        "specialpages-group-maintenance": "Rapôrts d’entretin",
        "specialpages-group-other": "Ôtres pâges spèciâles",
        "specialpages-group-login": "Sè branchiér / fâre un comptio",
index 467b8dd..f4b889d 100644 (file)
        "whatlinkshere": "Ferwisangen üüb detdiar sidj",
        "whatlinkshere-title": "Sidjen, diar üüb \"$1\" ferwise",
        "whatlinkshere-page": "Sidj:",
-       "linkshere": "Jodiar sidjen ferwise üüb '''„[[:$1]]“''':",
-       "nolinkshere": "Nian sidj ferwiset üüb [[:$1]]",
-       "nolinkshere-ns": "Nian sidj ferwiset üüb '''„[[:$1]]“''' uun di ütjsoocht nöömrüm.",
+       "linkshere-2": "Jodiar sidjen ferwise üüb '''„$1“''':",
+       "nolinkshere-2": "Nian sidj ferwiset üüb $1",
+       "nolinkshere-ns-2": "Nian sidj ferwiset üüb '''„$1“''' uun di ütjsoocht nöömrüm.",
        "isredirect": "widjerfeerang",
        "istemplate": "iinbünjen föörlaagen",
        "isimage": "Dateilink",
        "fileduplicatesearch-noresults": "Nian datei mä di nööm „$1“ fünjen.",
        "specialpages": "Spezial-sidjen",
        "specialpages-note-top": "Legend",
+       "specialpages-note-restricted": "* Normool spezial-sidjen\n* <span class=\"mw-specialpagerestricted\">Spezial-sidjen mä tugripsrochten</span>",
        "specialpages-group-maintenance": "Werksteedsidjen",
        "specialpages-group-other": "Ööder spezial-sidjen",
        "specialpages-group-login": "Melde di uun of skriiw di iin",
index e0f5aea..92e11bf 100644 (file)
        "whatlinkshere": "Leams a cheste vôs",
        "whatlinkshere-title": "Pagjinis che a son leadis a \"$1\"",
        "whatlinkshere-page": "Pagjine:",
-       "linkshere": "Lis pagjinis ca sot a son leadis a '''[[:$1]]''':",
-       "nolinkshere": "Nissune pagjine e à leams a '''[[:$1]]'''.",
-       "nolinkshere-ns": "No son pagjine leadis a '''[[:$1]]''' intal spazi dai nons sielt.",
+       "linkshere-2": "Lis pagjinis ca sot a son leadis a '''$1''':",
+       "nolinkshere-2": "Nissune pagjine e à leams a '''$1'''.",
+       "nolinkshere-ns-2": "No son pagjine leadis a '''$1''' intal spazi dai nons sielt.",
        "isredirect": "pagjine di reindirizament",
        "istemplate": "includude",
        "isimage": "leam a figure",
        "fileduplicatesearch-filename": "Non dal file:",
        "fileduplicatesearch-submit": "Cîr",
        "specialpages": "Pagjinis speciâls",
+       "specialpages-note-restricted": "* Pagjinis speciâls no riservadis.\n* <strong class=\"mw-specialpagerestricted\">Pagjinis speciâls a ciertis categoriis di utents.</strong>",
        "specialpages-group-maintenance": "Rapuarts di manutenzion",
        "specialpages-group-other": "Altris pagjinis speciâls",
        "specialpages-group-login": "Jentrade / regjistrazion",
index e7fae5e..648cf63 100644 (file)
        "whatlinkshere": "Wat is hjirmei keppele?",
        "whatlinkshere-title": "Siden dy't keppele binne mei \"$1\"",
        "whatlinkshere-page": "Side:",
-       "linkshere": "Dizze siden binne keppele oan '''[[:$1]]''':",
-       "nolinkshere": "Der binne gjin siden oan '''[[:$1]]''' keppele.",
-       "nolinkshere-ns": "Gjin siden yn de keazen nammeromte keppelje nei '''[[:$1]]'''.",
+       "linkshere-2": "Dizze siden binne keppele oan '''$1''':",
+       "nolinkshere-2": "Der binne gjin siden oan '''$1''' keppele.",
+       "nolinkshere-ns-2": "Gjin siden yn de keazen nammeromte keppelje nei '''$1'''.",
        "isredirect": "synonym",
        "istemplate": "opnaam",
        "isimage": "triemkeppeling",
        "fileduplicatesearch-result-n": "De triem \"$1\" hat {{PLURAL:$2|1 duplikaat|$2 duplikaten}}.",
        "specialpages": "Bysûndere siden",
        "specialpages-note-top": "Leginda",
+       "specialpages-note-restricted": "* Normale bysûndere siden.\n* <strong class=\"mw-specialpagerestricted\">Beheinde bysûndere siden.</strong>",
        "specialpages-group-maintenance": "Underhâld siden",
        "specialpages-group-other": "Oare bysûndere siden",
        "specialpages-group-login": "Oanmelde / registrearje",
index ea20a63..f59930b 100644 (file)
        "whatlinkshere": "Naisc leis an lch seo",
        "whatlinkshere-title": "Naisc le $1",
        "whatlinkshere-page": "Leathanach:",
-       "linkshere": "Tá nasc chuig '''[[:$1]]''' ar na leathanaigh seo a leanas:",
-       "nolinkshere": "Níl leathanach ar bith ann a bhfuil nasc chuig '''[[:$1]]''' air.",
-       "nolinkshere-ns": "Níl leathanach ar bith ann san ainmspás roghnaithe a bhfuil nasc chuig '''[[:$1]]''' air.",
+       "linkshere-2": "Tá nasc chuig '''$1''' ar na leathanaigh seo a leanas:",
+       "nolinkshere-2": "Níl leathanach ar bith ann a bhfuil nasc chuig '''$1''' air.",
+       "nolinkshere-ns-2": "Níl leathanach ar bith ann san ainmspás roghnaithe a bhfuil nasc chuig '''$1''' air.",
        "isredirect": "Leathanach athsheolaidh",
        "istemplate": "iniamh",
        "isimage": "nasc comhad",
index 2998314..00bf854 100644 (file)
        "whatlinkshere": "Baalantılar sayfaa",
        "whatlinkshere-title": "$1 baalantısı olan sayfalar",
        "whatlinkshere-page": "Yaprak:",
-       "linkshere": "Buraya baalantısı var olan sayfalar '''[[:$1]]''':",
-       "nolinkshere": "Yok buraya baalanan sayfa '''[[:$1]]'''.",
+       "linkshere-2": "Buraya baalantısı var olan sayfalar '''$1''':",
+       "nolinkshere-2": "Yok buraya baalanan sayfa '''$1'''.",
        "isredirect": "yönnendirmäk sayfası",
        "istemplate": "eklemää",
        "isimage": "fayl baalantısı",
index 86c5fa0..64ddae7 100644 (file)
        "whatlinkshere": "有什哩连到个首",
        "whatlinkshere-title": "连到 $1 𠮶页面",
        "whatlinkshere-page": "页面:",
-       "linkshere": "下底𠮶页面链接到[[:$1]]:",
-       "nolinkshere": "冇页面链接到[[:$1]]。",
-       "nolinkshere-ns": "选正𠮶空间名内冇页面链接到[[:$1]]。",
+       "linkshere-2": "下底𠮶页面链接到$1:",
+       "nolinkshere-2": "冇页面链接到$1。",
+       "nolinkshere-ns-2": "选正𠮶空间名内冇页面链接到$1。",
        "isredirect": "重定向页面",
        "istemplate": "含到",
        "isimage": "档案连结",
index 96da964..944d037 100644 (file)
        "whatlinkshere": "有什哩連到箇首",
        "whatlinkshere-title": "連到 $1 嗰頁面",
        "whatlinkshere-page": "頁面:",
-       "linkshere": "下底嗰頁面連結到[[:$1]]:",
-       "nolinkshere": "冇頁面連結到[[:$1]]。",
-       "nolinkshere-ns": "選正嗰空間名內冇頁面連結到[[:$1]]。",
+       "linkshere-2": "下底嗰頁面連結到$1:",
+       "nolinkshere-2": "冇頁面連結到$1。",
+       "nolinkshere-ns-2": "選正嗰空間名內冇頁面連結到$1。",
        "isredirect": "重定向頁",
        "istemplate": "含到",
        "isimage": "檔案連結",
index 584759b..89f046e 100644 (file)
        "pagecategories": "{{PLURAL:$1|Katégori}}",
        "category_header": "Paj andan katégori-a « $1 »",
        "subcategories": "Soukatégori",
-       "category-media-header": "Médya andan katégori-a « $1 »",
+       "category-media-header": "Médja annan katégori « $1 »",
        "category-empty": "<em>Sa katégori pa ka kontni atchwèlman pyès paj ni fiché miltimédya.</em>",
        "hidden-categories": "{{PLURAL:$1|Katégori kaché}}",
        "hidden-category-category": "Katégori kaché",
        "unprotect": "Chanjé protèksyon-an",
        "newpage": "Nouvèl paj",
        "talkpagelinktext": "diskisyon",
-       "specialpage": "Paj spésyal",
+       "specialpage": "Paj èspésyal",
        "personaltools": "Zouti pèrsonèl",
        "talk": "Diskisyon",
        "views": "Afichaj",
        "nstab-main": "Paj",
        "nstab-user": "Paj di {{GENDER:{{ROOTPAGENAME}}|itilizatò|itilizatris}}",
        "nstab-media": "Médja",
-       "nstab-special": "Paj spésyal",
+       "nstab-special": "Paj èspésyal",
        "nstab-project": "À propo",
        "nstab-image": "Fiché",
        "nstab-mediawiki": "Mésaj",
        "mainpage-nstab": "Paj prensipal",
        "nosuchaction": "Aksyon enkonèt",
        "nosuchactiontext": "Aksyon-an spésifyé andan URL-a sa envalid.\nZòt pitèt mal antré URL-a ou swivi roun lyen éroné.\nLi pé égalman endiké oun anomali andan logisyèl itilizé pa {{SITENAME}}.",
-       "nosuchspecialpage": "Paj spésyal inègzistant",
-       "nospecialpagetext": "<strong>Zòt doumandé oun paj spésyal ki pa ka ègzisté.</strong>\n\nOun lis dé paj spésyal valid ka trouvé so kò asou [[Special:SpecialPages|{{int:specialpages}}]].",
+       "nosuchspecialpage": "Paj èspésyal inègzistant",
+       "nospecialpagetext": "<strong>Zòt doumandé oun paj èspésyal ki pa ka ègzisté.</strong>\n\nOun lis dé paj èspésyal valid ka trouvé so kò asou [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "Érò",
        "databaseerror": "Érò di baz di doné",
        "databaseerror-text": "Oun érò di rékèt di baz di doné aparèt.\nSala pé provini di roun anomali annan lojisyèl-a.",
        "mycustomjsprotected": "Zòt pa gen drwè di modifyé sa paj JavaScript.",
        "myprivateinfoprotected": "Zòt pa gen drwè di modifyé zòt enfòrmasyon pèrsonèl.",
        "mypreferencesprotected": "Zòt pa gen drwè di modifyé zòt préférans.",
-       "ns-specialprotected": "Paj spésyal-ya pa pouvé sa modifyé.",
+       "ns-specialprotected": "Paj èspésyal-ya pa pouvé fika modifyé.",
        "titleprotected": "Sa tit té protéjé kont tout kréyasyon pa [[User:$1|$1]].\nMotif fourni sa <em>$2</em>.",
        "filereadonlyerror": "Enposib di modifyé fiché-a « $1 » pas répèrtwar-a di fiché « $2 » sa an lèktir sèl.\n\nAdministratò sistèm ki li vérouyé té fourni sa motif : « $3 ».",
        "invalidtitle-knownnamespace": "Tit pa valid ké lèspas di non « $2 » é entitilé-a « $3 »",
        "nowiki_sample": "Antré tèks ki pa formaté isi",
        "nowiki_tip": "Ignoré sentaks wiki-a",
        "image_tip": "Fiché enséré",
-       "media_tip": "Lyen vèr roun fiché médya",
+       "media_tip": "Lyen bò'd roun fiché médja",
        "sig_tip": "Zòt signatir ké dat",
        "hr_tip": "Lign orizontal (pa an abizé)",
        "summary": "Rézimé :",
        "showpreview": "Prévizwalizé",
        "showdiff": "Wè modifikasyon-yan",
        "anoneditwarning": "<strong>Panga :</strong> zòt pa konèkté. Zòt adrès IP ké sa vizib di tout moun si zòt ka fè dé modifikasyon. Si zòt <strong>[$1 ka konèkté zòt kò]</strong> ou <strong>[$2 kréyé roun kont]</strong>, zòt modifikasyon ké sq atribwé à zòt pròp non di itilizatò(ris) é zòt ké gen dé ròt avantaj.",
-       "blockedtext": "<strong>Zòt kont itilizatò ou zòt adrès IP bloké.</strong>\n\nBlokaj té éfèktchwé pa $1.\nRézon-an évoké sa swivant : <em>$2</em>.\n\n* Koumansman di blokaj : $8\n* Èkspirasyon di blokaj : $6\n* Kont bloké : $7.\n\nZòt pé kontakté $1 ou rounòt [[{{MediaWiki:Grouppage-sysop}}|administratò]] pou an diskité.\nZòt pa pé itilizé fonksyon-an « {{int:emailuser}} » sèlman si oun adrès di kouryé valid sa spésifyé andan zòt [[Special:Preferences|préférans]] é sèlman si sa fonksyonalité pa bloké.\nZòt adrèd IP atchwèl sa $3 é zòt idantifyan di blokaj sa $5.\nSouplé, enkli tout détay-ya lasou'l annan chakin dé rékèt ki zòt ké fè.",
+       "blockedtext": "<strong>Zòt kont itilizatò oben zòt adrès IP bloké.</strong>\n\nBlokaj té éfèktchwé pa $1.\nRézon-an évoké sa swivant : <em>$2</em>.\n\n* Koumansman di blokaj : $8\n* Èspirasyon di blokaj : $6\n* Kont bloké : $7.\n\nZòt pé kontakté $1 oben rounòt [[{{MediaWiki:Grouppage-sysop}}|administratò]] pou an diskité.\nZòt pa pouvé itilizé fonksyon-an « {{int:emailuser}} » rounso si oun adrès di kouryé valid sa èspésifyé andan zòt [[Special:Preferences|préférans]] é rounso si sa fonksyonalité pa bloké.\nZòt adrès IP atchwèl sa $3 é zòt idantifyan di blokaj sa $5.\nSouplé, enkli tout détay-ya lasou'l annan chakin dé rékèt ki zòt ké fè.",
        "loginreqlink": "konèkté so kò",
        "newarticletext": "Zòt té ka swiv roun lyen vèr roun paj ki pa ka ègzisté òkò. \nAtò di kréyé sa paj, antré zòt tèks annan bwat ki aprè (zòt pé konsilté [$1 paj d'èd-a] pou plis enfòrmasyon).\nSi zòt pa rivé{{GENDER:|}} isi pa éròr, kliké asou bouton <strong>Routour</strong> di zòt navigatò.",
        "anontalkpagetext": "----\n<em>Zòt asou paj di diskisyon di oun itilizatò anonim ki pa òkò kréyé di kont ou ki pa ka an itilizé</em>.\nPou sa rézon, nou divèt itilizé so adrès IP pou idantifyé li.\nOun adrès IP pé sa partajé pa plizyò itilizatò.\nSi zòt roun itiliza{{GENDER:|ò|ris}} anonim é si zòt ka kontasté ki dé koumantèr ki pa ka konsèrné zòt sa adrèsé à zòt, zòt pé [[Special:CreateAccount|kréyé roun kont]] ou [[Special:UserLogin|konèkté zòt kò]] atò di évité tout konfizyon fitir ké ròt kontribitò anonim.",
        "recentchangeslinked-feed": "Swivi dé paj lyé",
        "recentchangeslinked-toolbox": "Swivi dé paj lyé",
        "recentchangeslinked-title": "Swivi dé paj asosyé à « $1 »",
-       "recentchangeslinked-summary": "Antré roun non di paj pou wè modifikasyon-yan ki fè résaman asou dé paj lyé dipi ou vèr sa paj (pou wè manm-yan di oun katégori, antré Katégori:Non di katégori). Modifikasyon-yan dé paj di [[Special:Watchlist|zòt lis di swivi]] sa <strong>an gra</strong>.",
+       "recentchangeslinked-summary": "Antré roun non di paj pou wè modifikasyon-yan ki fè résaman asou dé paj lyé dipi oben bò'd sa paj (pou wè manm-yan di oun katégori, antré {{ns:category}}:Non di katégori). Modifikasyon-yan dé paj di [[Special:Watchlist|zòt lis di swivi]] sa <strong>an gra</strong>.",
        "recentchangeslinked-page": "Non di paj :",
        "recentchangeslinked-to": "Afiché modifikasyon-yan dé paj ki ka konpòrté roun lyen vèr paj ki bay plito ki envèrs",
        "upload": "Enpòrté roun fiché",
        "sharedupload-desc-here": "Sa fiché ka provini di $1. Li pé sa itilizé pa dé ròt projè.\nSo dèskripsyon asou so [$2 paj di dèskripsyon] sa afiché anba.",
        "filepage-nofile": "Pyès fiché di sa non ka ègzisté.",
        "upload-disallowed-here": "Zòt pa pé ranplasé sa fiché.",
-       "randompage": "Paj o azar",
+       "randompage": "Paj o azò",
        "statistics": "Statistik",
        "double-redirect-fixer": "Korèktò di roudirèksyon",
        "nbytes": "$1 {{PLURAL:$1|òktè}}",
        "tooltip-namespace_association": "Koché sa kaz pou enklir égalman lèspas di non di diskisyon ou di sijè, asosyé à lèspas di non sélèksyoné",
        "blanknamespace": "(Prensipal)",
        "contributions": "Kontribisyon di {{GENDER:$1|itilizatò|itilizatris}}",
-       "contributions-title": "Lis kontribisyon-yan di itiliza{{GENDER:$1|ò|ris}} $1",
+       "contributions-title": "Lis di kontribisyon-yan di itiliza{{GENDER:$1|ò|ris}}-a $1",
        "mycontris": "Kontribisyon",
        "anoncontribs": "Kontribisyon",
        "contribsub2": "Pou {{GENDER:$3|$1}} ($2)",
        "whatlinkshere": "Paj lyé",
        "whatlinkshere-title": "Paj ki ka pwenté bò'd « $1 »",
        "whatlinkshere-page": "Paj :",
-       "linkshere": "Paj-ya ki anba ka kontni roun lyen vèr <strong>[[:$1]]</strong> :",
-       "nolinkshere": "Pyès paj pa gen kontni dé lyen vèr <strong>[[:$1]]</strong>.",
+       "linkshere-2": "Paj-ya ki anba ka kontni roun lyen vèr <strong>$1</strong> :",
+       "nolinkshere-2": "Pyès paj pa gen kontni dé lyen vèr <strong>$1</strong>.",
        "isredirect": "paj di roudirèksyon",
        "istemplate": "enklizyon",
        "isimage": "Lyen vèr fiché-a",
        "tooltip-n-portal": "À propo di projè, sa ki zòt pé fè, koté trouvé enfòrmasyon-yan",
        "tooltip-n-currentevents": "Trouvé plis d'enfòrmasyon asou atchwalité an kour",
        "tooltip-n-recentchanges": "Lis di modifikasyon résant asou wiki-a",
-       "tooltip-n-randompage": "Afiché roun paj o azar",
+       "tooltip-n-randompage": "Afiché roun paj o azò",
        "tooltip-n-help": "Aksè à lèd",
        "tooltip-t-whatlinkshere": "Lis di paj lyé ki ka pwenté asou sala",
        "tooltip-t-recentchangeslinked": "Lis di modifikasyon résant liyé à sa paj",
        "tooltip-t-contributions": "Wè lis dé kontribisyon di {{GENDER:$1|sa itilizatò|sa itilizatris}}",
        "tooltip-t-emailuser": "Voyé roun kouryé à {{GENDER:$1|sa itilizatò|sa itilizatris}}",
        "tooltip-t-upload": "Télévèrsé dé fiché",
-       "tooltip-t-specialpages": "Lis di tout paj spésyal",
+       "tooltip-t-specialpages": "Lis di tout paj èspésyal",
        "tooltip-t-print": "Vèrsyon enprimab di sa paj",
        "tooltip-t-permalink": "Adrès pèrmanant di sa vèrsyon di paj-a",
        "tooltip-ca-nstab-main": "Wè kontni di paj-a",
        "tooltip-ca-nstab-user": "Wè paj di itilizatò",
-       "tooltip-ca-nstab-special": "A roun paj spésyal, é li pa pé sa modifyé.",
+       "tooltip-ca-nstab-special": "A roun paj èspésyal, é li pa pouvé fika modifyé.",
        "tooltip-ca-nstab-project": "Wè paj-a di projè",
        "tooltip-ca-nstab-image": "Wè paj-a di fiché",
        "tooltip-ca-nstab-mediawiki": "Wè mésaj sistèm-a",
        "watchlisttools-raw": "Modifyé lis di swivi an mòd brout",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|diskisyon]])",
        "redirect": "Roudirijé pa ID di fiché, itilizatò, paj, révizyon ou journal",
-       "redirect-summary": "Sa paj spésyal ka roudirijé vèr roun fiché (non di fiché fourni), oun paj (ID di révizyon ou di paj fourni), oun paj di itilizatò (idantifyan nimérik di itilizatò fourni), ou roun antré di journal (ID di journal fourni). Itilizasyon : [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], ou [[{{#Special:Redirect}}/logid/186]].",
+       "redirect-summary": "Sa paj èspésyal ka roudirijé bò'd roun fiché (non di fiché fourni), oun paj (ID di révizyon oben di paj fourni), oun paj di itilizatò (idantifyan nimérik di itilizatò fourni), oben roun antré di journal (ID di journal fourni). Itilizasyon : [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], oben [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "Validé",
        "redirect-lookup": "Sasé :",
        "redirect-value": "Valò :",
        "redirect-page": "ID di paj",
        "redirect-revision": "Révizyon di paj-a",
        "redirect-file": "Non di fiché",
-       "specialpages": "Paj spésyal",
+       "specialpages": "Paj èspésyal",
        "tag-filter": "Filtré [[Special:Tags|baliz]] :",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Baliz}}]] : $2)",
        "tags-active-yes": "Wi",
index 8d345f0..e5a0161 100644 (file)
        "whatlinkshere": "Na tha a' ceangal a-nall an-seo",
        "whatlinkshere-title": "Duilleagan a tha a' ceangal ri \"$1\"",
        "whatlinkshere-page": "Duilleag:",
-       "linkshere": "Tha na duilleagan a leanas a' ceangal ri <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Chan eil ceangal air duilleag sam bith a tha a' dol gu <strong>[[:$1]]</strong>.",
-       "nolinkshere-ns": "Chan eil ceangal gu <strong>[[:$1]]</strong> ann an duilleag sam bith san ainm-spàs a thagh thu.",
+       "linkshere-2": "Tha na duilleagan a leanas a' ceangal ri <strong>$1</strong>:",
+       "nolinkshere-2": "Chan eil ceangal air duilleag sam bith a tha a' dol gu <strong>$1</strong>.",
+       "nolinkshere-ns-2": "Chan eil ceangal gu <strong>$1</strong> ann an duilleag sam bith san ainm-spàs a thagh thu.",
        "isredirect": "duilleag ath-sheòlaidh",
        "istemplate": "transclusion",
        "isimage": "ceangal faidhle",
        "fileduplicatesearch-noresults": "Cha deach faidhle air a bheil \"$1\" a lorg.",
        "specialpages": "Duilleagan sònraichte",
        "specialpages-note-top": "Treòir",
+       "specialpages-note-restricted": "* Duilleagan sònraichte coitcheann.\n* <span class=\"mw-specialpagerestricted\">Duilleagan sònraichte cuingichte.</span>",
        "specialpages-group-maintenance": "Aithrisean na h-obrach-glèidhidh",
        "specialpages-group-other": "Duilleagan sònraichte eile",
        "specialpages-group-login": "Log a-steach / cruthaich cunntas",
index 633d84d..f584af6 100644 (file)
@@ -26,7 +26,8 @@
                        "Luan",
                        "Hamilton Abreu",
                        "Athena in Wonderland",
-                       "Navhy"
+                       "Navhy",
+                       "PokéDex Nacional"
                ]
        },
        "tog-underline": "Subliñar as ligazóns:",
@@ -63,7 +64,7 @@
        "tog-watchlisthideminor": "Agochar as edicións pequenas na lista de vixilancia",
        "tog-watchlisthideliu": "Agochar as edicións dos usuarios rexistrados na lista de vixilancia",
        "tog-watchlistreloadautomatically": "Recargar a lista de vixilancia automaticamente cando se produza un cambio nun filtro (necesítase JavaScript)",
-       "tog-watchlistunwatchlinks": "Engadir ligazóns directos para vixiar ou deixar de vixiar as entradas da lista de páxinas vixiadas (é necesario JavaScript para activar a funcionalidade)",
+       "tog-watchlistunwatchlinks": "Engadir ligazóns directos para vixiar ou deixar de vixiar ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) as entradas da lista de páxinas vixiadas (é preciso JavaScript para activar a funcionalidade)",
        "tog-watchlisthideanons": "Agochar as edicións dos usuarios anónimos na lista de vixilancia",
        "tog-watchlisthidepatrolled": "Agochar as edicións patrulladas na lista de vixilancia",
        "tog-watchlisthidecategorization": "Agochar a categorización das páxinas",
        "botpasswords-existing": "Contrasinais de bots existentes",
        "botpasswords-createnew": "Crear un novo contrasinal de bot",
        "botpasswords-editexisting": "Editar un contrasinal de bot xa existente",
+       "botpasswords-label-needsreset": "(o contrasinal precisa ser redefinido)",
        "botpasswords-label-appid": "Nome do bot:",
        "botpasswords-label-create": "Crear",
        "botpasswords-label-update": "Actualizar",
        "whatlinkshere": "Páxinas que ligan con esta",
        "whatlinkshere-title": "Páxinas que ligan con \"$1\"",
        "whatlinkshere-page": "Páxina:",
-       "linkshere": "As seguintes páxinas ligan con \"'''[[:$1]]'''\":",
-       "nolinkshere": "Ningunha páxina liga con \"'''[[:$1]]'''\".",
-       "nolinkshere-ns": "Ningunha páxina liga con \"'''[[:$1]]'''\" no espazo de nomes elixido.",
+       "linkshere-2": "As seguintes páxinas ligan con \"'''$1'''\":",
+       "nolinkshere-2": "Ningunha páxina liga con \"'''$1'''\".",
+       "nolinkshere-ns-2": "Ningunha páxina liga con \"'''$1'''\" no espazo de nomes elixido.",
        "isredirect": "páxina redirixida",
        "istemplate": "inclusión",
        "isimage": "ligazón ao ficheiro",
index 1981d76..f65948d 100644 (file)
        "whatlinkshere": "هرچي خال ببؤ ائره",
        "whatlinkshere-title": "ولگؤني گه «$1»ˇ أمرأ خال دأنن",
        "whatlinkshere-page": "ولگ:",
-       "linkshere": "جيري ولگؤن '''[[:$1]]'''ˇ أمرأ خال دأنن:",
+       "linkshere-2": "جيري ولگؤن '''$1'''ˇ أمرأ خال دأنن:",
        "isredirect": "تغييرمسيرˇ ولگ",
        "isimage": "فاىلˇ خال",
        "whatlinkshere-prev": "{{PLURAL:$1|قبلي|$1 قبلي مؤرد}}",
index beecd23..8b89f81 100644 (file)
        "whatlinkshere": "हाका कितें जुळटा",
        "whatlinkshere-title": " \"$1\" हाका जोडणी आशिल्लीं पानां",
        "whatlinkshere-page": "पान:",
-       "linkshere": "मुखावेली पानां '''[[:$1]]''': हाका जोडणी करतात",
-       "nolinkshere": "$1हाका खंयच्याच पानाची जोडणी ना",
+       "linkshere-2": "मुखावेली पानां '''$1''': हाका जोडणी करतात",
+       "nolinkshere-2": "$1हाका खंयच्याच पानाची जोडणी ना",
        "isredirect": "पुनर्निर्देशन पान",
        "istemplate": "$1 दूसरात-समावेस",
        "isimage": "फायलीचो दुवो",
index 976847b..ff45698 100644 (file)
        "whatlinkshere": "Hanga kitem zoddta",
        "whatlinkshere-title": "\"$1\" haka zoddlelim panam",
        "whatlinkshere-page": "Pan:",
-       "linkshere": "Sokoilim panam <strong>[[:$1]]</strong> ak zoddtat:",
-       "nolinkshere": "Khoincheim pan '''[[:$1]]''' ak zoddna.",
+       "linkshere-2": "Sokoilim panam <strong>$1</strong> ak zoddtat:",
+       "nolinkshere-2": "Khoincheim pan '''$1''' ak zoddna.",
        "isredirect": "punornirdexon pan",
        "istemplate": "Durasth-somaves",
        "isimage": "failichem zoddop",
index 26a1a0d..e69303e 100644 (file)
        "whatlinkshere": "Wumbuta",
        "whatlinkshere-title": "Halaman botiye o wumbuta ode \"$1\"",
        "whatlinkshere-page": "Halaman",
-       "linkshere": "Halaman botiye woluwo wumbuta ode <strong>[[:$1]]<strong>:",
-       "nolinkshere": "Diya'a halaman wumbuta ode <strong>[[:$1]]</strong>",
+       "linkshere-2": "Halaman botiye woluwo wumbuta ode <strong>$1<strong>:",
+       "nolinkshere-2": "Diya'a halaman wumbuta ode <strong>$1</strong>",
        "isredirect": "halaman pilobaleyalo",
        "istemplate": "tranklusi",
        "isimage": "wumbuta lo berkas",
index 7ec44a0..d1d4424 100644 (file)
        "whatlinkshere": "𐌰𐌻𐌻𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃 𐌸𐌰𐌹𐌴𐌹 𐌱𐍂𐌹𐌲𐌲𐌰𐌽𐌳 𐌸𐌿𐌺 𐌷𐌹𐌳𐍂𐌴",
        "whatlinkshere-title": "𐌻𐌰𐌿𐌱𐍉𐍃 𐌸𐌰𐌹𐌴𐌹 𐍄𐌰𐌹𐌺𐌽𐌾𐌰𐌽𐌳 𐌳𐌿 \"$1\"",
        "whatlinkshere-page": "𐌻𐌰𐌿𐍆𐍃:",
-       "linkshere": "𐌹𐍆𐍄𐌿𐌼𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃 𐌱𐍂𐌹𐌲𐌲𐌰𐌽𐌳 𐌸𐌿𐌺  <strong>[[:$1]]</strong>:",
+       "linkshere-2": "𐌹𐍆𐍄𐌿𐌼𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃 𐌱𐍂𐌹𐌲𐌲𐌰𐌽𐌳 𐌸𐌿𐌺  <strong>$1</strong>:",
        "isredirect": "𐌰𐌻𐌾𐌰𐍂 𐌱𐍂𐌹𐌲𐌲𐌰𐌽𐌳𐍃 𐌻𐌰𐌿𐍆𐍃",
        "istemplate": "𐍄𐍂𐌰𐌽𐍃𐌺𐌻𐌿𐍃𐌾𐍉",
        "whatlinkshere-prev": "{{PLURAL:$1|𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐌰|𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐌰𐌽𐍃 $1}}",
index fe9f276..1bd6255 100644 (file)
        "whatlinkshere": "Τὰ ἐνθάδε ἄγοντα",
        "whatlinkshere-title": "Δέλτοι συνεζευγμέναι μετὰ τοῦ \"$1\"",
        "whatlinkshere-page": "Δέλτος:",
-       "linkshere": "Τάδε ἄγουσι πρὸς '''[[:$1]]''':",
-       "nolinkshere": "Οὐδένα ἄγουσι πρὸς '''[[:$1]]'''.",
-       "nolinkshere-ns": "Οὐδεμία δέλτος συνδέεται τῇ '''[[:$1]]''' ἐν τῷ ἐπιλεγμένῳ ὀνοματείῳ.",
+       "linkshere-2": "Τάδε ἄγουσι πρὸς '''$1''':",
+       "nolinkshere-2": "Οὐδένα ἄγουσι πρὸς '''$1'''.",
+       "nolinkshere-ns-2": "Οὐδεμία δέλτος συνδέεται τῇ '''$1''' ἐν τῷ ἐπιλεγμένῳ ὀνοματείῳ.",
        "isredirect": "ἀναδιευθύνειν δέλτον",
        "istemplate": "περίκλεισις",
        "isimage": "σύνδεσμος ἀρχείου",
        "fileduplicatesearch-result-1": "Τὸ ἀρχεῖον \"$1\" οὐκ ἔχει ταυτοτικὴν διπλοτυπίαν.",
        "fileduplicatesearch-result-n": "Τὸ ἀρχεῖον \"$1\" ἔχει {{PLURAL:$2|1 ταυτοτικὴν διπλοτυπίαν|$2 ταυτοτικὰς διπλοτυπίας}}.",
        "specialpages": "Εἰδικαὶ δέλτοι",
+       "specialpages-note-restricted": "* Κανονικαὶ εἰδικαὶ δέλτοι.\n* <strong class=\"mw-specialpagerestricted\">Περιωρισμέναι εἰδικαὶ δἐλτοι.</strong>\n* <span class=\"mw-specialpagecached\">Μόναι δέλτοι ἀποτεταμιευμέναι.</span>",
        "specialpages-group-maintenance": "Ἀναφοραὶ συντηρήσεως",
        "specialpages-group-other": "Ἕτεραι εἰδικαὶ δέλτοι",
        "specialpages-group-login": "Συνδεῖσθαι/λογισμὸν ποιεῖν",
index 1a09c5a..924d5f8 100644 (file)
        "whatlinkshere": "Was verwyst do druff?",
        "whatlinkshere-title": "Sytene, wo uf „$1“ verlinke",
        "whatlinkshere-page": "Syte:",
-       "linkshere": "Die Sytene hen e Link, wu zu '''„[[:$1]]“''' fiere:",
-       "nolinkshere": "Kei Artikel verwyyst uf '''„[[:$1]]“'''.",
-       "nolinkshere-ns": "Kei Syte verwyyst uf '''„[[:$1]]“''' im gwehlte Namensruum.",
+       "linkshere-2": "Die Sytene hen e Link, wu zu '''„$1“''' fiere:",
+       "nolinkshere-2": "Kei Artikel verwyyst uf '''„$1“'''.",
+       "nolinkshere-ns-2": "Kei Syte verwyyst uf '''„$1“''' im gwehlte Namensruum.",
        "isredirect": "Wyterleitigssyte",
        "istemplate": "Vorlageybindig",
        "isimage": "Dateigleich",
        "fileduplicatesearch-noresults": "S isch kei Datei mit em Name „$1“ gfunde wore.",
        "specialpages": "Spezialsytene",
        "specialpages-note-top": "Zeichenerklärig:",
+       "specialpages-note-restricted": "* Normali Spezialsyte.\n* <span class=\"mw-specialpagerestricted\">Spezialsyte mit bschränktem Zuegang.</span>",
        "specialpages-group-maintenance": "Wartigslischte",
        "specialpages-group-other": "Andri Spezialsyte",
        "specialpages-group-login": "Aamälde/Konto aalege",
index 38217d3..5a66693 100644 (file)
        "index-category": "અનુક્રમણિકા બનાવેલા પાનાં",
        "noindex-category": "અનુક્રમણિકા નહીં બનાવેલા પાનાં",
        "broken-file-category": "ફાઇલોની ત્રૂટક કડીઓવાળાં પાનાં",
+       "categoryviewer-pagedlinks": "($1) ($2)",
+       "category-header-numerals": "$1–$2",
        "about": "વિષે",
        "article": "લેખનું પાનું",
        "newwindow": "(નવા પાનામાં ખુલશે)",
        "versionrequired": "મીડીયાવિકિનું $1 સંસ્કરણ જરૂરી",
        "versionrequiredtext": "આ પાનાના વપરાશ માટે મીડિયાવિકિનું $1 સંસ્કરણ જરૂરી.\n\nજુઓ [[Special:Version|સંસ્કરણ પાનું]].",
        "ok": "મંજૂર",
+       "pagetitle": "$1 - {{SITENAME}}",
+       "pagetitle-view-mainpage": "{{SITENAME}}",
+       "backlinksubtitle": "← $1",
        "retrievedfrom": "\"$1\" થી મેળવેલ",
        "youhavenewmessages": "{{PLURAL:$3|તમારી પાસે}} $1 ($2).",
        "youhavenewmessagesfromusers": "{{PLURAL:$4|આપ}}ને માટે {{PLURAL:$3|અન્ય સભ્ય|$3 અન્ય સભ્યો}} તરફથી $1 છે. ($2).",
        "site-atom-feed": "$1 એટમ ફીડ",
        "page-rss-feed": "\"$1\" RSS ફીડ",
        "page-atom-feed": "\"$1\" એટમ ફીડ",
+       "feed-atom": "ઍટમ",
+       "feed-rss": "RSS",
        "red-link-title": "$1 (પાનું અસ્તિત્વમાં નથી)",
        "sort-descending": "ઉતરતા ક્રમમાં ગોઠવો",
        "sort-ascending": "ચડતા ક્રમમાં ગોઠવો",
        "nosuchusershort": "\"$1\" નામનો કોઇ સભ્ય નથી, તમારી જોડણી તપાસો.",
        "nouserspecified": "તમારે સભ્ય નામ દર્શાવવાની જરૂર છે.",
        "login-userblocked": "આ યુઝર પ્રતિબંધિત છે. પ્રવેશ વર્જીત.",
-       "wrongpassword": "તમà«\87 àª²àª\96à«\87લà«\80 àª\97à«\81પà«\8dત àª¸àª\82àª\9cà«\8dàª\9eા àª\96à«\8bàª\9fà«\80 છે.\nફરીથી પ્રયત્ન કરો.",
+       "wrongpassword": "àª\96à«\8bàª\9fà«\81àª\82 àª¸àª­à«\8dયનામ àª\85થવા àª\97à«\81પà«\8dત àª¸àª\82àª\9cà«\8dàª\9eા (પાસવરà«\8dડâ\80\8c) àª¦àª¾àª\96લ àª\95રà«\87 છે.\nફરીથી પ્રયત્ન કરો.",
        "wrongpasswordempty": "તમે ગુપ્ત સંજ્ઞા લખવાનું ભુલી ગયા લાગો છો.\nફરીથી પ્રયત્ન કરો.",
        "passwordtooshort": "ગુપ્ત સંજ્ઞામાં ઓછામાં {{PLURAL:$1|ઓછો એક અક્ષર હોવો |ઓછા $1 અક્ષર હોવા}} જોઇએ.",
+       "passwordtoolong": "ગુપ્ત સંજ્ઞા (પાસવર્ડ) {{PLURAL:$1|1 અક્ષર|$1 અક્ષરો}} કરતા લાંબો રાખી શકાતો નથી.",
        "password-name-match": "તમારી ગુપ્તસંજ્ઞા તમારા સભ્યનામ કરતાં અલગ જ હોવી જોઇએ.",
        "password-login-forbidden": "આ સભ્યનામ અને ગુપ્તસંજ્ઞા વાપરવા પર પ્રતિબંધ છે.",
        "mailmypassword": "પાસવર્ડ ફરી ગોઠવો",
        "ancientpages": "સૌથી જૂનાં પાનાં",
        "move": "નામ બદલો",
        "movethispage": "આ પાનું ખસેડો",
-       "unusedimagestext": "નà«\80àª\9aà«\87નà«\80 àª«àª¾àª\87લà«\8b àª\85સà«\8dતિતà«\8dવમાàª\82 àª¤à«\8b àª\9bà«\87 àªªàª£ àª\95à«\8bàª\87 àªªàª¾àª¨àª¾ àªªàª° àª¤à«\87નà«\8b àª\89પયà«\8bàª\97 àª¥àª¯à«\87લ àª¨àª¥à«\80.\nàª\95à«\8dરà«\8dપયા àª¨à«\8bàª\82ધ àª²à«\87àª\96à«\8b àª\95à«\87 àª\86 àª«àª¾àª\87લનà«\87 àª\85નà«\8dય àªµà«\87બસાàª\87àª\9fà«\8b àª¸à«\80ધા URL àª¨àª¾ àª®àª¾àª§à«\8dયમ àª¦à«\8dવારા àªµàª¾àªªàª°à«\80 àª¶àª\95à«\87 àª\9bà«\87 àª\85નà«\87 àª\95à«\8bàª\87 àªªàª£ àª\89પયà«\8bàª\97 àª¸àª¿àªµàª¾àª¯ àª\98ણà«\80 àª«àª¾àª\87લà«\8b àª\85હà«\80àª\82 àª¯àª¾àª¦àª¿માં હોઇ શકે.",
+       "unusedimagestext": "નà«\80àª\9aà«\87નà«\80 àª«àª¾àª\87લà«\8b àª\85સà«\8dતિતà«\8dવમાàª\82 àª\9bà«\87 àªªàª°àª\82તà«\81 àª\95à«\8bàª\87 àªªàª¾àª¨àª¾àª\82 àªªàª° àª¤à«\87નà«\8b àª\89પયà«\8bàª\97 àª¥àª¯à«\87લ àª¨àª¥à«\80.\nàª\95à«\83પા àª\95રà«\80 àª¨à«\8bàª\82ધ àª²à«\87શà«\8b àª\95à«\87 àª\86 àª«àª¾àª\87લનà«\87 àª\85નà«\8dય àªµà«\87બસાàª\87àª\9fà«\8b àª¸à«\80ધા URLના àª®àª¾àª§à«\8dયમ àª¦à«\8dવારા àªµàª¾àªªàª°à«\80 àª¶àª\95à«\87 àª\9bà«\87 àª\85નà«\87 àª\95à«\8bàª\87 àªªàª£ àª\89પયà«\8bàª\97 àª¸àª¿àªµàª¾àª¯ àª\98ણà«\80 àª«àª¾àª\87લà«\8b àª\85હà«\80àª\82 àª¯àª¾àª¦à«\80માં હોઇ શકે.",
        "unusedcategoriestext": "નીચેના શ્રેણી પાના છે પણા કોઈ લેખ આનો ઉપયોગ કરતાં નથી",
        "notargettitle": "કોઇ લક્ષ્ય નથી",
        "notargettext": "આ ક્રિયા જેના પર કરવાની છે તે સભ્ય કે પાનાની માહિતી તમે પૂરી પાડી નથી",
        "whatlinkshere": "અહી શું જોડાય છે",
        "whatlinkshere-title": "\"$1\" ને જોડતા પાનાં",
        "whatlinkshere-page": "પાનું:",
-       "linkshere": "નીચેના પાનાઓ '''[[:$1]]''' સાથે જોડાય છે:",
-       "nolinkshere": "'''[[:$1]]'''ની સાથે કોઇ પાના જોડાતા નથી.",
-       "nolinkshere-ns": "પસંદ કરેલ નામ સ્થળમાં કોઇ પાના '''[[:$1]]'''  સાથે જોડાયેલ નથી.",
+       "linkshere-2": "નીચેના પાનાઓ '''$1''' સાથે જોડાય છે:",
+       "nolinkshere-2": "'''$1'''ની સાથે કોઇ પાના જોડાતા નથી.",
+       "nolinkshere-ns-2": "પસંદ કરેલ નામ સ્થળમાં કોઇ પાના '''$1'''  સાથે જોડાયેલ નથી.",
        "isredirect": "દિશાનિર્દેશ કરેલ પાનું",
        "istemplate": "સમાવેશ",
        "isimage": "ફાઇલની કડી",
        "fileduplicatesearch-result-n": "\"$1\" ફાઇલની તેની સમાન {{PLURAL:$2|1 નકલ |$2 નકલો }} છે.",
        "fileduplicatesearch-noresults": " \"$1\" નામ ધરાવતી કોઇ ફાઇલ ન મળી",
        "specialpages": "ખાસ પાનાંઓ",
+       "specialpages-note-restricted": "* નિયમિત ખાસ પાનાં.\n* <span class=\"mw-specialpagerestricted\">પ્રતિબંધિત ખાસ પાનાં.</span>",
        "specialpages-group-maintenance": "સમારકામ અહેવાલ",
        "specialpages-group-other": "અન્ય ખાસ પાનાઓ",
        "specialpages-group-login": "પ્રવેશ / ખાતુ બનાવો",
index c80216e..701507a 100644 (file)
        "whatlinkshere": "Cre ta kiangley rish shoh",
        "whatlinkshere-title": "Duillagyn ta kianglt rish $1",
        "whatlinkshere-page": "Duillag:",
-       "linkshere": "Ta ny duillagyn shoh kianglt rish '''[[:$1]]''':",
-       "nolinkshere": "Cha nel duillag erbee kianglt rish '''[[:$1]]'''.",
+       "linkshere-2": "Ta ny duillagyn shoh kianglt rish '''$1''':",
+       "nolinkshere-2": "Cha nel duillag erbee kianglt rish '''$1'''.",
        "isredirect": "duillag aa-enmyssit",
        "istemplate": "goaill stiagh",
        "isimage": "kiangley coadan",
index 408d8c9..5ca721e 100644 (file)
        "whatlinkshere": "Mahaɗan wannan shafi",
        "whatlinkshere-title": "Shafuna masu mahaɗi da \"$1\"",
        "whatlinkshere-page": "Shafi:",
-       "linkshere": "Waɗannan shafuna sun haɗu da '''[[:$1]]''':",
+       "linkshere-2": "Waɗannan shafuna sun haɗu da '''$1''':",
        "isredirect": "shafin turawa",
        "istemplate": "gami",
        "isimage": "majigi shigagge",
index 26e605d..1ad9597 100644 (file)
@@ -15,7 +15,8 @@
                        "LNDDYL",
                        "唐吉訶德的侍從",
                        "飞舞回堂前",
-                       "Macofe"
+                       "Macofe",
+                       "Ruthven"
                ]
        },
        "tog-underline": "Lièn-chiap kâ-tái sien:",
        "whatlinkshere": "Nâi-têu lièn to liá-têu",
        "whatlinkshere-title": "Lièn-chiap to \"$1\" ke ya̍p-mien",
        "whatlinkshere-page": "Ya̍p-mien:",
-       "linkshere": "Hâ-poi ya̍p-mien lièn-chiap to <strong>[[:$1]]</strong>:",
-       "nolinkshere": "無頁面鏈接到'''[[:$1]]'''。",
-       "nolinkshere-ns": "Chhai só-sién ke miàng-sṳ khûng-kiên tú mò ya̍p-mien lièn-chiap to [[:$1]].",
+       "linkshere-2": "Hâ-poi ya̍p-mien lièn-chiap to <strong>$1</strong>:",
+       "nolinkshere-2": "無頁面鏈接到'''$1'''。",
+       "nolinkshere-ns-2": "Chhai só-sién ke miàng-sṳ khûng-kiên tú mò ya̍p-mien lièn-chiap to $1.",
        "isredirect": "chhùng-thin-hiong ya̍p",
        "istemplate": "pâu-hàm",
        "isimage": "vùn-khien lièn-chiap",
index b0d1643..bc55341 100644 (file)
        "whatlinkshere": "He aha ka mea e loulou iho ai",
        "whatlinkshere-title": "Nā ʻAoʻao e loulou iā \"$1\"",
        "whatlinkshere-page": "‘Ao‘ao:",
-       "linkshere": "Loulou kēia mau ʻaoʻao iā <strong>[[:$1]]</strong>:",
-       "nolinkshere": "ʻAʻohe ‘ao‘ao e loulou iā '''[[:$1]]'''.",
+       "linkshere-2": "Loulou kēia mau ʻaoʻao iā <strong>$1</strong>:",
+       "nolinkshere-2": "ʻAʻohe ‘ao‘ao e loulou iā '''$1'''.",
        "isredirect": "ʻaoʻao kia hou",
        "istemplate": "kumo",
        "isimage": "loulou waihona",
index 0946de2..7e6cf6e 100644 (file)
        "noemail": "לא רשומה כתובת דואר אלקטרוני עבור ה{{GENDER:$1|משתמש|משתמשת}} \"$1\".",
        "noemailcreate": "יש לספק כתובת דואר אלקטרוני תקינה.",
        "passwordsent": "סיסמה חדשה נשלחה לכתובת הדואר האלקטרוני הרשומה עבור \"$1\".\nאנא היכנסו חזרה לאתר אחרי שתקבלו אותה.",
-       "blocked-mailpassword": "×\9bת×\95×\91ת ×\94Ö¾IP ×©×\9c×\9a × ×\97ס×\9e×\94 ×\9eער×\99×\9b×\94. ×\9b×\93×\99 ×\9c×\9e× ×\95×¢ × ×\99צ×\95×\9c ×\9cרע×\94, ×\90×\99× ×\9a ×\9e×\95רש×\94 להשתמש באפשרות שחזור הסיסמה.",
+       "blocked-mailpassword": "×\9bת×\95×\91ת ×\94Ö¾IP ×©×\9c×\9a × ×\97ס×\9e×\94 ×\9eער×\99×\9b×\94. ×\9b×\93×\99 ×\9c×\9e× ×\95×¢ × ×\99צ×\95×\9c ×\9cרע×\94, ×\90×\99×\9f ×\91×\90פשר×\95ת×\9a להשתמש באפשרות שחזור הסיסמה.",
        "eauthentsent": "דוא\"ל אימות נשלח לכתובת הדוא\"ל שצוינה.\nלפני שדברי דוא\"ל אחרים יישלחו לחשבון הזה, יהיה {{GENDER:|עליך|עלייך}} לפעול לפי ההוראות בדוא\"ל, כדי לאשר שהחשבון אכן שייך לך.",
        "throttled-mailpassword": "כבר נשלח דוא\"ל לאיפוס הסיסמה ב{{PLURAL:$1|שעה האחרונה|שעתיים האחרונות|־$1 השעות האחרונות}}.\nכדי למנוע ניצול לרעה, יכול להישלח רק דוא\"ל אחד כזה בכל {{PLURAL:$1|שעה|שעתיים|$1 שעות}}.",
        "mailerror": "שגיאה בשליחת דוא\"ל: $1",
        "subject-preview": "תצוגה מקדימה של הנושא:",
        "previewerrortext": "אירעה שגיאה בעת הניסיון להציג תצוגה מקדימה של השינויים שלך.",
        "blockedtitle": "המשתמש חסום",
-       "blockedtext": "<strong>שם המשתמש או כתובת ה־IP שלך נחסמו.</strong>\n\nהחסימה בוצעה על ידי $1.\nהסיבה שניתנה לכך היא <em>$2</em>.\n\n* תחילת החסימה: $8\n* פקיעת החסימה: $6\n* החסימה שבוצעה: $7\n\nבאפשרותך ליצור קשר עם $1 או עם כל אחד מ[[{{MediaWiki:Grouppage-sysop}}|מפעילי המערכת]] האחרים כדי לדון בחסימה.\nאין באפשרותך להשתמש בתכונת \"שליחת דואר אלקטרוני למשתמש זה\" אם לא ציינת כתובת דוא\"ל תקפה ב[[Special:Preferences|העדפות המשתמש שלך]] או אם נחסמת משליחת דוא\"ל.\nכתובת ה־IP הנוכחית שלך היא $3, ומספר החסימה שלך הוא #$5.\nיש לציין את כל הפרטים הללו בכל פנייה לבירור החסימה.",
-       "autoblockedtext": "×\9bת×\95×\91ת ×\94Ö¾IP ×©×\9c×\9a × ×\97ס×\9e×\94 ×\91×\90×\95פ×\9f ×\90×\95×\98×\95×\9e×\98×\99 ×\9b×\99×\95×\95×\9f ×©×\9eשת×\9eש ×\90×\97ר, ×©× ×\97ס×\9d ×¢×\9cÖ¾×\99×\93×\99 $1, ×\94שת×\9eש ×\91×\94.\n×\94ס×\99×\91×\94 ×©× ×\99תנ×\94 ×\9c×\97ס×\99×\9e×\94 ×\94×\99×\90:\n\n:<em>$2</em>\n\n* ×ª×\97×\99×\9cת ×\94×\97ס×\99×\9e×\94: $8\n* ×¤×§×\99עת ×\94×\97ס×\99×\9e×\94: $6\n* ×\94×\97ס×\99×\9e×\94 ×©×\91×\95צע×\94: $7\n\n×\91×\90פשר×\95ת×\9a ×\9c×\99צ×\95ר ×§×©×¨ ×¢×\9d $1 ×\90×\95 ×¢×\9d ×\9b×\9c ×\90×\97×\93 ×\9e[[{{MediaWiki:Grouppage-sysop}}|×\9eפע×\99×\9c×\99 ×\94×\9eער×\9bת]] ×\94×\90×\97ר×\99×\9d ×\9b×\93×\99 ×\9c×\93×\95×\9f ×\91×\97ס×\99×\9e×\94.\n\n×\90×\99×\9f ×\91×\90פשר×\95ת×\9a ×\9c×\94שת×\9eש ×\91ת×\9b×\95נת \"ש×\9c×\99×\97ת ×\93×\95×\90ר ×\90×\9cק×\98ר×\95× ×\99 ×\9c×\9eשת×\9eש ×\96×\94\" אם לא ציינת כתובת דוא\"ל תקפה ב[[Special:Preferences|העדפות המשתמש שלך]] או אם נחסמת משליחת דוא\"ל.\n\nכתובת ה־IP הנוכחית שלך היא $3, ומספר החסימה שלך הוא #$5.\nיש לציין את כל הפרטים הללו בכל פנייה לבירור החסימה.",
+       "blockedtext": "<strong>שם המשתמש או כתובת ה־IP שלך נחסמו.</strong>\n\nהחסימה בוצעה על־ידי $1.\nהסיבה שניתנה לכך היא <em>$2</em>.\n\n* תחילת החסימה: $8\n* פקיעת החסימה: $6\n* החסימה שבוצעה: $7\n\nבאפשרותך ליצור קשר עם $1 או עם כל אחד מ[[{{MediaWiki:Grouppage-sysop}}|מפעילי המערכת]] האחרים כדי לדון בחסימה.\nכמו־כן, באפשרותך להשתמש בתכונת \"{{int:emailuser}}\", אלא אם לא ציינת כתובת דוא\"ל תקפה ב[[Special:Preferences|העדפות המשתמש שלך]] או אם נחסמת משליחת דוא\"ל.\nכתובת ה־IP הנוכחית שלך היא $3, ומספר החסימה שלך הוא #$5.\nיש לציין את כל הפרטים הללו בכל פנייה לבירור החסימה.",
+       "autoblockedtext": "×\9bת×\95×\91ת ×\94Ö¾IP ×©×\9c×\9a × ×\97ס×\9e×\94 ×\91×\90×\95פ×\9f ×\90×\95×\98×\95×\9e×\98×\99 ×\9b×\99×\95×\95×\9f ×©×\9eשת×\9eש ×\90×\97ר, ×©× ×\97ס×\9d ×¢×\9cÖ¾×\99×\93×\99 $1, ×\94שת×\9eש ×\91×\94.\n×\94ס×\99×\91×\94 ×©× ×\99תנ×\94 ×\9c×\97ס×\99×\9e×\94 ×\94×\99×\90:\n\n:<em>$2</em>\n\n* ×ª×\97×\99×\9cת ×\94×\97ס×\99×\9e×\94: $8\n* ×¤×§×\99עת ×\94×\97ס×\99×\9e×\94: $6\n* ×\94×\97ס×\99×\9e×\94 ×©×\91×\95צע×\94: $7\n\n×\91×\90פשר×\95ת×\9a ×\9c×\99צ×\95ר ×§×©×¨ ×¢×\9d $1 ×\90×\95 ×¢×\9d ×\9b×\9c ×\90×\97×\93 ×\9e[[{{MediaWiki:Grouppage-sysop}}|×\9eפע×\99×\9c×\99 ×\94×\9eער×\9bת]] ×\94×\90×\97ר×\99×\9d ×\9b×\93×\99 ×\9c×\93×\95×\9f ×\91×\97ס×\99×\9e×\94.\n\n×\9b×\9e×\95Ö¾×\9b×\9f, ×\91×\90פשר×\95ת×\9a ×\9c×\94שת×\9eש ×\91ת×\9b×\95נת \"{{int:emailuser}}\", ×\90×\9c×\90 אם לא ציינת כתובת דוא\"ל תקפה ב[[Special:Preferences|העדפות המשתמש שלך]] או אם נחסמת משליחת דוא\"ל.\n\nכתובת ה־IP הנוכחית שלך היא $3, ומספר החסימה שלך הוא #$5.\nיש לציין את כל הפרטים הללו בכל פנייה לבירור החסימה.",
        "systemblockedtext": "שם המשתמש או כתובת ה־IP שלך נחסמו באופן אוטומטי על־ידי תוכנת מדיה־ויקי.\nהסיבה שניתנה לחסימה היא:\n\n:<em>$2</em>\n\n* תחילת החסימה: $8\n* פקיעת החסימה: $6\n* החסימה שבוצעה: $7\n\nכתובת ה־IP הנוכחית שלך היא $3.\nיש לציין את כל הפרטים הללו בכל פנייה לבירור החסימה.",
        "blockednoreason": "לא ניתנה סיבה",
        "whitelistedittext": "נדרשת $1 כדי לערוך דפים.",
        "right-sendemail": "שליחת דואר אלקטרוני למשתמשים אחרים",
        "right-managechangetags": "יצירה, הפעלה וביטול של [[Special:Tags|תגיות]]",
        "right-applychangetags": "החלת [[Special:Tags|תגיות]] יחד עם שינויים",
-       "right-changetags": "×\94×\95ספ×\94 ×\95×\94סר×\94 ×©×\9c [[Special:Tags|ת×\92×\99×\95ת]] ×\9c×\92רס×\90×\95ת ×\95×\9cרש×\95×\9e×\95ת ×\99×\95×\9eן",
+       "right-changetags": "×\94×\95ספת [[Special:Tags|ת×\92×\99×\95ת]] ×\9c×\92רס×\90×\95ת ×\95×\9cרש×\95×\9e×\95ת ×\99×\95×\9e×\9f ×\90×\95 ×\94סרת ×ª×\92×\99×\95ת ×\9e×\94ן",
        "right-deletechangetags": "מחיקת [[Special:Tags|תגיות]] מבסיס הנתונים",
        "grant-generic": "חבילת ההרשאות \"$1\"",
        "grant-group-page-interaction": "אינטראקציה עם דפים",
        "zip-wrong-format": "הקובץ שצוין אינו קובץ ZIP.",
        "zip-bad": "הקובץ הוא קובץ ZIP פגום או בלתי קריא מסיבה אחרת.\nלא ניתן לבצע עליו בדיקת אבטחה כנדרש.",
        "zip-unsupported": "קובץ זה הוא קובץ ZIP המשתמש בתכונות ZIP שאינן נתמכות על ידי מדיה־ויקי.\nלא ניתן לבצע עליו בדיקת אבטחה כנדרש.",
-       "uploadstash": "ס×\9c×\99ק העלאות",
+       "uploadstash": "×\9e×\90×\92ר העלאות",
        "uploadstash-summary": "דף זה מאפשר גישה לקבצים שהועלו (או נמצאים בתהליך העלאה), אך טרם פורסמו באתר הוויקי. קבצים אלה אינם גלויים לאיש מלבד המשתמש שהעלה אותם.",
-       "uploadstash-clear": "×\9e×\97×\99קת ×\94ק×\91צ×\99×\9d ×\91ס×\9c×\99ק",
-       "uploadstash-nofiles": "×\90×\99×\9f ×\9c×\9a ×§×\91צ×\99×\9d ×\91ס×\9c×\99ק.",
+       "uploadstash-clear": "×\9e×\97×\99קת ×\94ק×\91צ×\99×\9d ×\91×\9e×\90×\92ר",
+       "uploadstash-nofiles": "×\90×\99×\9f ×\9c×\9a ×§×\91צ×\99×\9d ×\91×\9e×\90×\92ר.",
        "uploadstash-badtoken": "ביצוע הפעולה נכשל, אולי בגלל פקיעת תוקפו של אסימון העריכה שלך. נא לנסות שוב.",
        "uploadstash-errclear": "מחיקת הקבצים נכשלה.",
        "uploadstash-refresh": "רענון רשימת הקבצים",
        "uploadstash-thumbnail": "הצגת תמונה ממוזערת",
-       "uploadstash-exception": "×\9c×\90 × ×\99ת×\9f ×\9c×\90×\97ס×\9f ×\90ת ×\94×\94×¢×\9c×\90×\94 ×\91ס×\9c×\99ק ($1): \"$2\".",
+       "uploadstash-exception": "×\9c×\90 × ×\99ת×\9f ×\9c×\90×\97ס×\9f ×\90ת ×\94×\94×¢×\9c×\90×\94 ×\91×\9e×\90×\92ר ($1): \"$2\".",
        "uploadstash-bad-path": "הנתיב אינו קיים.",
        "uploadstash-bad-path-invalid": "הנתיב אינו תקין.",
        "uploadstash-bad-path-unknown-type": "הסוג \"$1\" אינו מוכר.",
        "uploadstash-bad-path-unrecognized-thumb-name": "שם הקובץ הממוזער אינו מוכר.",
        "uploadstash-bad-path-no-handler": "לא נמצא רכיב המטפל ב־MIME מסוג $1 המתאים לקובץ $2.",
        "uploadstash-bad-path-bad-format": "המפתח \"$1\" אינו בפורמט המתאים.",
-       "uploadstash-file-not-found": "×\94×\9eפת×\97 \"$1\" ×\9c×\90 × ×\9eצ×\90 ×\91ס×\9c×\99ק הקבצים.",
+       "uploadstash-file-not-found": "×\94×\9eפת×\97 \"$1\" ×\9c×\90 × ×\9eצ×\90 ×\91×\9e×\90×\92ר הקבצים.",
        "uploadstash-file-not-found-no-thumb": "לא ניתן לייצר קובץ ממוזער.",
        "uploadstash-file-not-found-no-local-path": "אין נתיב מקומי לפריט בגודל שונה.",
        "uploadstash-file-not-found-no-object": "לא ניתן היה לייצר אובייקט של קובץ מקומי עבור הקובץ הממוזער.",
        "listduplicatedfiles-summary": "זוהי רשימה של קבצים שהגרסה החדשה ביותר שלהם זהה לגרסה החדשה ביותר של קובץ אחר כלשהו. רק קבצים מקומיים נבדקים לצורך זה.",
        "listduplicatedfiles-entry": "לקובץ [[:File:$1|$1]] יש [[$3|{{PLURAL:$2|עותק זהה|$2 עותקים זהים}}]].",
        "unusedtemplates": "תבניות שאינן בשימוש",
-       "unusedtemplatestext": "דף זה מכיל רשימה של כל הדפים במרחב השם {{ns:template}} שאינם נכללים בדף אחר. אנא זכרו לבדוק את הקישורים האחרים לתבניות לפני שתמחקו אותן.",
+       "unusedtemplatestext": "דף זה מכיל רשימה של כל הדפים במרחב השם \"{{ns:template}}\" שאינם נכללים בדף אחר.\nיש לזכור לבדוק את הקישורים האחרים לתבניות לפני מחיקתן.",
        "unusedtemplateswlh": "קישורים אחרים",
        "randompage": "דף אקראי",
        "randompage-nopages": "אין דפים {{PLURAL:$2|במרחב השם הבא|במרחבי השם הבאים}}: $1.",
        "brokenredirects-edit": "עריכה",
        "brokenredirects-delete": "מחיקה",
        "withoutinterwiki": "דפים ללא קישורי שפה",
-       "withoutinterwiki-summary": "הדפים הבאים אינם מקשרים לגרסאות שלהם בשפות אחרות:",
+       "withoutinterwiki-summary": "הדפים הבאים אינם מקשרים לגרסאות שלהם בשפות אחרות.",
        "withoutinterwiki-legend": "תחילית",
        "withoutinterwiki-submit": "הצגה",
        "fewestrevisions": "הדפים בעלי מספר העריכות הנמוך ביותר",
        "nbytes": "{{PLURAL:$1|בית אחד|$1 בתים}}",
        "ncategories": "{{PLURAL:$1|קטגוריה אחת|$1 קטגוריות}}",
-       "ninterwikis": "{{PLURAL:$1|ק×\99ש×\95ר ×\91×\99× ×\95×\95×\99ק×\99 ×§חד|$1 קישורי בינוויקי}}",
+       "ninterwikis": "{{PLURAL:$1|ק×\99ש×\95ר ×\91×\99× ×\95×\95×\99ק×\99 ×\90חד|$1 קישורי בינוויקי}}",
        "nlinks": "{{PLURAL:$1|קישור אחד|$1 קישורים}}",
        "nmembers": "{{PLURAL:$1|דף אחד|$1 דפים}}",
        "nmemberschanged": "$1 ← {{PLURAL:$2|חבר אחד|$2 חברים}}",
        "nrevisions": "{{PLURAL:$1|גרסה אחת|$1 גרסאות}}",
        "nimagelinks": "בשימוש {{PLURAL:$1|בדף אחד|ב־$1 דפים}}",
        "ntransclusions": "בשימוש {{PLURAL:$1|בדף אחד|ב־$1 דפים}}",
-       "specialpage-empty": "אין תוצאות.",
+       "specialpage-empty": "אין תוצאות בדיווח התחזוקה הזה.",
        "lonelypages": "דפים יתומים",
-       "lonelypagestext": "×\94×\93פ×\99×\9d ×\94×\91×\90×\99×\9d ×\90×\99× ×\9d ×\9eק×\95שר×\99×\9d ×\95×\90×\99× ×\9d ×\9e×\95×\9b×\9c×\9c×\99×\9d ×\91×\93פ×\99×\9d ×\90×\97ר×\99×\9d ×\91×\90תר {{SITENAME}}.",
+       "lonelypagestext": "×\94×\93פ×\99×\9d ×\94×\91×\90×\99×\9d ×\90×\99× ×\9d ×\9eק×\95שר×\99×\9d ×\9e×\93פ×\99×\9d ×\90×\97ר×\99×\9d ×\91{{GRAMMAR:ת×\97×\99×\9c×\99ת|{{SITENAME}}}} ×\95×\90×\99× ×\9d ×\9e×\95×\9b×\9c×\9c×\99×\9d ×\91×\94×\9d.",
        "uncategorizedpages": "דפים חסרי קטגוריה",
        "uncategorizedcategories": "קטגוריות חסרות קטגוריה",
        "uncategorizedimages": "קבצים חסרי קטגוריה",
        "unusedimages": "קבצים שאינם בשימוש",
        "wantedcategories": "קטגוריות מבוקשות",
        "wantedpages": "דפים מבוקשים",
-       "wantedpages-summary": "רש×\99×\9eת ×\93פ×\99×\9d ×\9c×\90 ×§×\99×\99×\9e×\99×\9d ×©×\9eספר ×\94ק×\99ש×\95ר×\99×\9d ×\90×\9c×\99×\94×\9d ×\94×\95×\90 ×\94×\92×\93×\95×\9c ×\91×\99×\95תר, ×\9c×\9e×¢×\98 ×\93פ×\99×\9d ×©×¨×§ ×\94פנ×\99×\95ת ×\9eקשר×\95ת ×\90×\9c×\99×\94×\9d. ×\9cרש×\99×\9eת ×\93פ×\99×\9d ×\9c×\90 ×§×\99×\99×\9e×\99×\9d ×©×\99ש ×\94פנ×\99×\95ת ×\94×\9eקשר×\95ת ×\90×\9c×\99×\94×\9d, ×¨' [[{{#special:BrokenRedirects}}|רשימת ההפניות הבלתי־תקינות]].",
+       "wantedpages-summary": "רש×\99×\9eת ×\93פ×\99×\9d ×\9c×\90 ×§×\99×\99×\9e×\99×\9d ×©×\9eספר ×\94ק×\99ש×\95ר×\99×\9d ×\90×\9c×\99×\94×\9d ×\94×\95×\90 ×\94×\92×\93×\95×\9c ×\91×\99×\95תר, ×\9c×\9e×¢×\98 ×\93פ×\99×\9d ×©×¨×§ ×\94פנ×\99×\95ת ×\9eקשר×\95ת ×\90×\9c×\99×\94×\9d. ×\9cרש×\99×\9eת ×\93פ×\99×\9d ×\9c×\90 ×§×\99×\99×\9e×\99×\9d ×©×\99ש ×\94פנ×\99×\95ת ×\94×\9eקשר×\95ת ×\90×\9c×\99×\94×\9d, × ×\99ת×\9f ×\9c×¢×\99×\99×\9f ×\91[[{{#special:BrokenRedirects}}|רשימת ההפניות הבלתי־תקינות]].",
        "wantedpages-badtitle": "כותרת בלתי תקינה ברשימת התוצאות: $1",
        "wantedfiles": "קבצים מבוקשים",
        "wantedfiletext-cat": "הקבצים הבאים נמצאים בשימוש, אך אינם קיימים. ייתכן שקבצים ממאגרים חיצוניים יהיו רשומים אף על פי שהם קיימים, אך שגיאות כאלה יהיו <del>מחוקות</del>. בנוסף, דפים שמטביעים קבצים שאינם קיימים רשומים בדף [[:$1]].",
-       "wantedfiletext-cat-noforeign": "×\94ק×\91צ×\99×\9d ×\94×\91×\90×\99×\9d × ×\9eצ×\90×\99×\9d ×\91ש×\99×\9e×\95ש, ×\90×\91×\9c ×\90×\99× ×\9d ×§×\99×\99×\9e×\99×\9d. ×\9b×\9e×\95Ö¾×\9b×\9f, ×\93פ×\99×\9d ×©×\9eשת×\9eש×\99×\9d ×\91קבצים שאינם קיימים רשומים בדף [[:$1]].",
+       "wantedfiletext-cat-noforeign": "×\94ק×\91צ×\99×\9d ×\94×\91×\90×\99×\9d × ×\9eצ×\90×\99×\9d ×\91ש×\99×\9e×\95ש, ×\90×\91×\9c ×\90×\99× ×\9d ×§×\99×\99×\9e×\99×\9d. ×\9b×\9e×\95Ö¾×\9b×\9f, ×\93פ×\99×\9d ×©×\9e×\98×\91×\99×¢×\99×\9d קבצים שאינם קיימים רשומים בדף [[:$1]].",
        "wantedfiletext-nocat": "הקבצים הבאים נמצאים בשימוש, אך אינם קיימים. ייתכן שקבצים ממאגרים חיצוניים יהיו רשומים אף על פי שהם קיימים, אך שגיאות כאלה יהיו <del>מחוקות</del>.",
        "wantedfiletext-nocat-noforeign": "הקבצים הבאים נמצאים בשימוש, אבל אינם קיימים.",
        "wantedtemplates": "תבניות מבוקשות",
        "mostinterwikis": "הדפים עם המספר הרב ביותר של קישורי בינוויקי",
        "mostrevisions": "הדפים עם מספר העריכות הגבוה ביותר",
        "prefixindex": "כל הדפים עם התחילית",
-       "prefixindex-namespace": "כל הדפים עם התחילית (במרחב השם $1)",
+       "prefixindex-namespace": "כל הדפים עם התחילית (במרחב השם \"$1\")",
        "prefixindex-submit": "הצגה",
        "prefixindex-strip": "הסתרת התחילית ברשימה",
        "shortpages": "דפים קצרים",
        "deadendpages": "דפים ללא קישורים",
        "deadendpagestext": "הדפים הבאים אינם מקשרים לדפים אחרים באתר {{SITENAME}}.",
        "protectedpages": "דפים מוגנים",
-       "protectedpages-filters": "×\9eסננ×\99×\9d:",
+       "protectedpages-filters": "ס×\99× ×\95×\9f:",
        "protectedpages-indef": "הגנות ללא הגבלת זמן בלבד",
-       "protectedpages-summary": "×\91×\93×£ ×\96×\94 ×¨×©×\95×\9e×\99×\9d ×\94×\93פ×\99×\9d ×\94ק×\99×\99×\9e×\99×\9d ×©×\9e×\95×\92× ×\99×\9d ×\9bר×\92×¢. ×\9cרש×\99×\9eת ×\94×\9b×\95תר×\95ת ×©×\9e×\95×\92× ×\95ת ×\9eפנ×\99 ×\99צ×\99ר×\94, ×¨×\90×\95 [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
+       "protectedpages-summary": "×\91×\93×£ ×\96×\94 ×¨×©×\95×\9e×\99×\9d ×\94×\93פ×\99×\9d ×\94ק×\99×\99×\9e×\99×\9d ×©×\9e×\95×\92× ×\99×\9d ×\9bר×\92×¢. ×¨×©×\99×\9eת ×\94×\9b×\95תר×\95ת ×©×\9e×\95×\92× ×\95ת ×\9eפנ×\99 ×\99צ×\99ר×\94 ×\9e×\95פ×\99×¢×\94 ×\91×\93×£ [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "הגנות מדורגות בלבד",
        "protectedpages-noredirect": "הסתרת הפניות",
        "protectedpagesempty": "אין כרגע דפים מוגנים עם הפרמטרים הללו.",
        "protectedpages-unknown-timestamp": "לא ידוע",
        "protectedpages-unknown-performer": "משתמש לא ידוע",
        "protectedtitles": "כותרות מוגנות",
-       "protectedtitles-summary": "×\91×\93×£ ×\96×\94 ×¨×©×\95×\9e×\95ת ×\94×\9b×\95תר×\95ת ×©×\9c ×\94×\93פ×\99×\9d ×©×\9e×\95×\92× ×\99×\9d ×\9bעת ×\9eפנ×\99 ×\99צ×\99ר×\94. ×\9cרש×\99×\9eת ×\94×\93פ×\99×\9d ×\94ק×\99×\99×\9e×\99×\9d ×©×\9e×\95×\92× ×\99×\9d, {{GENDER:|ר×\90×\94|ר×\90×\99|ר×\90×\95}} [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
+       "protectedtitles-summary": "×\91×\93×£ ×\96×\94 ×¨×©×\95×\9e×\95ת ×\94×\9b×\95תר×\95ת ×©×\9c ×\94×\93פ×\99×\9d ×©×\9e×\95×\92× ×\99×\9d ×\9bעת ×\9eפנ×\99 ×\99צ×\99ר×\94. ×¨×©×\99×\9eת ×\94×\93פ×\99×\9d ×\94ק×\99×\99×\9e×\99×\9d ×©×\9e×\95×\92× ×\99×\9d ×\9e×\95פ×\99×¢×\94 ×\91×\93×£ [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "אין כרגע כותרות מוגנות עם הפרמטרים האלה.",
        "protectedtitles-submit": "הצגת הדפים",
        "listusers": "רשימת משתמשים",
        "listusers-editsonly": "הצגת משתמשים עם עריכות בלבד",
+       "listusers-temporarygroupsonly": "הצגת משתמשים בקבוצות משתמש זמניות בלבד",
        "listusers-creationsort": "מיון לפי תאריך היצירה של החשבון",
        "listusers-desc": "מיון בסדר יורד",
        "usereditcount": "{{PLURAL:$1|עריכה אחת|$1 עריכות}}",
        "ancientpages": "דפים מוזנחים",
        "move": "העברה",
        "movethispage": "העברת דף זה",
-       "unusedimagestext": "הקבצים הבאים קיימים אך אינם מוטבעים בשום דף.\nשימו לב שאתרי אינטרנט אחרים עשויים לקשר לקובץ באמצעות כתובת URL ישירה, ולכן הוא עלול להופיע כאן למרות היותו בשימוש פעיל.",
+       "unusedimagestext": "הקבצים הבאים קיימים, אך אינם מוטבעים בשום דף.\nיש לשים לב לכך שאתרי אינטרנט אחרים עשויים לקשר לקובץ באמצעות כתובת URL ישירה, ולכן הוא עלול להופיע כאן למרות היותו בשימוש פעיל.",
        "unusedcategoriestext": "הקטגוריות הבאות קיימות, אבל לא נעשה שימוש בהן בשום דף או קטגוריה.",
        "notargettitle": "אין דף מטרה",
        "notargettext": "לא ציינת דף מטרה או משתמש לגביו תבוצע פעולה זו.",
        "nopagetext": "דף המטרה שציינת אינו קיים.",
        "pager-newer-n": "{{PLURAL:$1|הבאה|$1 הבאות}}",
        "pager-older-n": "{{PLURAL:$1|הקודמת|$1 הקודמות}}",
-       "suppress": "×\94סתרה",
+       "suppress": "×\94×¢×\9c×\9eה",
        "querypage-disabled": "דף מיוחד זה מבוטל עקב בעיות ביצועים.",
        "apihelp": "עזרה עבור ה־API",
        "apihelp-no-such-module": "המודול \"$1\" לא נמצא.",
        "apisandbox": "ארגז החול של ה־API",
        "apisandbox-jsonly": "דרוש JavaScript כדי להשתמש בארגז החול של ה־API.",
        "apisandbox-api-disabled": "API אינו פעיל באתר הזה.",
-       "apisandbox-intro": "×\94שת×\9eש×\95 ×\91×\93×£ ×\94×\96×\94 ×\9b×\93×\99 ×\9c×\94תנס×\95ת ×\91ש×\99×\9e×\95ש ×\91<strong>ש×\99ר×\95ת ×\94Ö¾API ×\94×\9e×\91×\95סס Web ×©×\9c ×\9e×\93×\99×\94Ö¾×\95×\99ק×\99</strong>.\n×¢×\99×\99× ×\95 ×\91[[mw:API:Main page|ת×\99×¢×\95×\93 ×©×\9c ×\94Ö¾API]] (×\91×\90× ×\92×\9c×\99ת) ×\9c×\9e×\99×\93×¢ × ×\95סף ×©×\9c ×©×\99×\9e×\95ש ×\91Ö¾API. ×\9c×\9eש×\9c: [https://www.mediawiki.org/wiki/API#A_simple_example ×\90×\99×\9a ×\9cק×\91×\9c ×\90ת ×\94ת×\95×\9b×\9f ×©×\9c ×\94×¢×\9e×\95×\93 ×\94ר×\90ש×\99]. ×\91×\97ר×\95 ×\91×\90×\97ת ×\94פע×\95×\9c×\95ת (actions) ×\9c×\93×\95×\92×\9e×\90×\95ת × ×\95ספ×\95ת.\n\nש×\99×\9e×\95 ×\9c×\91 ×©×\90×£ שמדובר ב\"ארגז חול\", פעולות שנעשות כאן עשויות לשנות את התוכן של אתר הוויקי.",
+       "apisandbox-intro": "× ×\99ת×\9f ×\9c×\94שת×\9eש ×\91×\93×£ ×\94×\96×\94 ×\9b×\93×\99 ×\9c×\94תנס×\95ת ×\91ש×\99×\9e×\95ש ×\91<strong>ש×\99ר×\95ת ×\94Ö¾API ×\94×\9e×\91×\95סס Web ×©×\9c ×\9e×\93×\99×\94Ö¾×\95×\99ק×\99</strong>.\n×\90פשר ×\9c×¢×\99×\99×\9f ×\91[[mw:API:Main page|ת×\99×¢×\95×\93 ×©×\9c ×\94Ö¾API]] (×\91×\90× ×\92×\9c×\99ת) ×\9c×\9e×\99×\93×¢ × ×\95סף ×¢×\9c ×©×\99×\9e×\95ש ×\91Ö¾API. ×\9c×\9eש×\9c: [https://www.mediawiki.org/wiki/API#A_simple_example ×\90×\99×\9a ×\9cק×\91×\9c ×\90ת ×\94ת×\95×\9b×\9f ×©×\9c ×\94×¢×\9e×\95×\93 ×\94ר×\90ש×\99]. ×\99ש ×\9c×\91×\97×\95ר ×\91×\90×\97ת ×\94פע×\95×\9c×\95ת (actions) ×\9c×\93×\95×\92×\9e×\90×\95ת × ×\95ספ×\95ת.\n\n×\9cתש×\95×\9eת ×\9c×\91×\9a: ×\90×£ ×¢×\9c ×¤×\99 שמדובר ב\"ארגז חול\", פעולות שנעשות כאן עשויות לשנות את התוכן של אתר הוויקי.",
        "apisandbox-submit": "ביצוע הבקשה",
        "apisandbox-reset": "ניקוי",
        "apisandbox-retry": "ניסיון נוסף",
        "apisandbox-dynamic-parameters-add-label": "הוספת פרמטר:",
        "apisandbox-dynamic-parameters-add-placeholder": "שם הפרמטר",
        "apisandbox-dynamic-error-exists": "פרמטר בשם \"$1\" כבר קיים.",
+       "apisandbox-templated-parameter-reason": "[[Special:ApiHelp/main#main/templatedparams|פרמטר התבנית]] הזה מוצע בהתבסס על {{PLURAL:$1|הערך של השדה|הערכים של השדות}} $2.",
        "apisandbox-deprecated-parameters": "פרמטרים מיושנים",
        "apisandbox-fetch-token": "מילוי אוטומטי של האסימון",
        "apisandbox-add-multi": "הוספה",
        "apisandbox-submit-invalid-fields-title": "חלק מהשדות אינם תקינים",
-       "apisandbox-submit-invalid-fields-message": "×\90× ×\90 ×ª×§× ×\95 ×\90ת ×\94ש×\93×\95ת ×\94×\9eס×\95×\9e× ×\99×\9d ×\95נס×\95 שוב.",
+       "apisandbox-submit-invalid-fields-message": "× ×\90 ×\9cתק×\9f ×\90ת ×\94ש×\93×\95ת ×\94×\9eס×\95×\9e× ×\99×\9d ×\95×\9cנס×\95ת שוב.",
        "apisandbox-results": "תוצאות",
        "apisandbox-sending-request": "בקשת ה־API בשליחה...",
        "apisandbox-loading-results": "תוצאות ה־API בתהליך קבלה...",
        "apisandbox-request-url-label": "כתובת ה־URL של הבקשה:",
        "apisandbox-request-json-label": "ייצוג הבקשה כ־JSON:",
        "apisandbox-request-time": "זמן הבקשה: {{PLURAL:$1|מילישנייה אחת|$1 מילישניות}}",
-       "apisandbox-results-fixtoken": "×\90× ×\90 ×ª×§× ×\95 ×\90ת ×\94×\90ס×\99×\9e×\95×\9f ×\95ש×\9c×\97×\95 שוב",
+       "apisandbox-results-fixtoken": "×\99ש ×\9cתק×\9f ×\90ת ×\94×\90ס×\99×\9e×\95×\9f ×\95×\9cש×\9c×\95×\97 שוב",
        "apisandbox-results-fixtoken-fail": "קבלת האסימון \"$1\" נכשלה.",
        "apisandbox-alert-page": "שדות בדף זה אינם תקינים.",
        "apisandbox-alert-field": "הערך של שדה זה אינו תקין.",
        "booksources-search-legend": "חיפוש משאבי ספרות חיצוניים",
        "booksources-isbn": "מסת\"ב (ISBN):",
        "booksources-search": "חיפוש",
-       "booksources-text": "×\9c×\94×\9c×\9f ×¨×©×\99×\9eת ×§×\99ש×\95ר×\99×\9d ×\9c×\90תר×\99×\9d ×\90×\97ר×\99×\9d ×\94×\9e×\95×\9bר×\99×\9d ×¡×¤×¨×\99×\9d ×\97×\93ש×\99×\9d ×\95×\99×\93־שנ×\99×\99×\94, ×\95ש×\91×\94×\9d ×¢×©×\95×\99 ×\9c×\94×\99×\95ת ×\9e×\99×\93×¢ × ×\95סף ×\9c×\92×\91×\99 ×¡×¤×¨×\99×\9d ×©×\90ת×\9d ×\9e×\97פש×\99×\9d:",
-       "booksources-invalid-isbn": "×\94×\9eסת\"×\91 ×©× ×\99ת×\9f ×\9bנר×\90×\94 ×\90×\99× ×\95 ×ª×§×\99×\9f; ×\90× ×\90 ×\91×\93ק×\95 ×\90×\9d ×\91×\99צעת×\9d טעויות בהעתקה מהמידע המקורי.",
+       "booksources-text": "×\9c×\94×\9c×\9f ×¨×©×\99×\9eת ×§×\99ש×\95ר×\99×\9d ×\9c×\90תר×\99×\9d ×\90×\97ר×\99×\9d ×\94×\9e×\95×\9bר×\99×\9d ×¡×¤×¨×\99×\9d ×\97×\93ש×\99×\9d ×\95×\99×\93־שנ×\99×\99×\94, ×\95ש×\91×\94×\9d ×¢×©×\95×\99 ×\9c×\94×\99×\95ת ×\9e×\99×\93×¢ × ×\95סף ×\9c×\92×\91×\99 ×¡×¤×¨×\99×\9d ×©×\9e×¢× ×\99×\99× ×\99×\9d ×\90×\95ת×\9a:",
+       "booksources-invalid-isbn": "×\94×\9eסת\"×\91 ×©× ×\99ת×\9f ×\9bנר×\90×\94 ×\90×\99× ×\95 ×ª×§×\99×\9f; ×\99ש ×\9c×\91×\93×\95ק ×\90×\9d × ×¢×©×\95 טעויות בהעתקה מהמידע המקורי.",
        "magiclink-tracking-rfc": "דפים שמשתמשים בקישורי קסם ל־RFC",
        "magiclink-tracking-rfc-desc": "דף זה משתמש בקישורי קסם ל־RFC. באתר [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] מוסבר כיצד יש לשנותם.",
        "magiclink-tracking-pmid": "דפים שמשתמשים בקישורי קסם ל־PMID",
        "allpagesfrom": "הצגת דפים החל מ:",
        "allpagesto": "הצגת דפים עד:",
        "allarticles": "כל הדפים",
-       "allinnamespace": "×\9b×\9c ×\94×\93פ×\99×\9d (×\9eר×\97×\91 ×\94ש×\9d $1)",
+       "allinnamespace": "×\9b×\9c ×\94×\93פ×\99×\9d (×\91×\9eר×\97×\91 ×\94ש×\9d \"$1\")",
        "allpagessubmit": "הצגה",
-       "allpagesprefix": "הדפים ששמם מתחיל ב־:",
-       "allpagesbadtitle": "×\9b×\95תרת ×\94×\93×£ ×©× ×\99תנ×\94 ×\94×\99×\99ת×\94 ×\91×\9cת×\99־תק×\99× ×\94 ×\90×\95 ×©×\94×\99×\99ת×\94 ×\91×\94 ×§×\99×\93×\95×\9eת ×©×\9c ×§×\99ש×\95ר ×\9cשפ×\94 ×\90×\97רת ×\90×\95 ×\9c×\95ויקי אחר.\nייתכן שהיא מכילה תו אחד או יותר האסורים לשימוש בכותרות.",
+       "allpagesprefix": "×\94צ×\92ת ×\93פ×\99×\9d ×©×©×\9e×\9d ×\9eת×\97×\99×\9c ×\91Ö¾:",
+       "allpagesbadtitle": "×\9b×\95תרת ×\94×\93×£ ×©× ×\99תנ×\94 ×\94×\99×\99ת×\94 ×\91×\9cת×\99־תק×\99× ×\94 ×\90×\95 ×©×\94×\99×\99ת×\94 ×\91×\94 ×§×\99×\93×\95×\9eת ×©×\9c ×§×\99ש×\95ר ×\9cשפ×\94 ×\90×\97רת ×\90×\95 ×\9c×\90תר ויקי אחר.\nייתכן שהיא מכילה תו אחד או יותר האסורים לשימוש בכותרות.",
        "allpages-bad-ns": "מרחב השם \"$1\" לא קיים ב{{grammar:תחילית|{{SITENAME}}}}.",
        "allpages-hide-redirects": "הסתרת הפניות",
        "cachedspecial-viewing-cached-ttl": "זוהי גרסה שמורה בזיכרון המטמון של דף זה, שעשויה להיות בת $1.",
        "cachedspecial-refresh-now": "צפייה באחרון.",
        "categories": "קטגוריות",
        "categories-submit": "הצגה",
-       "categoriespagetext": "{{PLURAL:$1|×\94ק×\98×\92×\95ר×\99×\94 ×\94×\91×\90×\94 ×\9b×\95×\9c×\9cת|×\94ק×\98×\92×\95ר×\99×\95ת ×\94×\91×\90×\95ת ×\9b×\95×\9c×\9c×\95ת}} ×\93פ×\99×\9d ×\90×\95 ×§×\95×\91צ×\99 ×\9e×\93×\99×\94.\n[[Special:UnusedCategories|ק×\98×\92×\95ר×\99×\95ת ×©×\90×\99× ×\9f ×\91ש×\99×\9e×\95ש]] ×\90×\99× ×\9f ×\9e×\95צ×\92×\95ת ×\9b×\90×\9f.\nר×\90×\95 ×\92×\9d ×\90ת [[Special:WantedCategories|רשימת הקטגוריות המבוקשות]].",
+       "categoriespagetext": "{{PLURAL:$1|×\94ק×\98×\92×\95ר×\99×\94 ×\94×\91×\90×\94 ×\9b×\95×\9c×\9cת|×\94ק×\98×\92×\95ר×\99×\95ת ×\94×\91×\90×\95ת ×\9b×\95×\9c×\9c×\95ת}} ×\93פ×\99×\9d ×\90×\95 ×§×\95×\91צ×\99 ×\9e×\93×\99×\94.\n[[Special:UnusedCategories|ק×\98×\92×\95ר×\99×\95ת ×©×\90×\99× ×\9f ×\91ש×\99×\9e×\95ש]] ×\9c×\90 ×\9e×\95צ×\92×\95ת ×\9b×\90×\9f.\n× ×\99ת×\9f ×\9c×¢×\99×\99×\9f ×\92×\9d ×\91[[Special:WantedCategories|רשימת הקטגוריות המבוקשות]].",
        "categoriesfrom": "הצגת קטגוריות החל מ:",
        "deletedcontributions": "תרומות משתמש מחוקות",
        "deletedcontributions-title": "תרומות משתמש מחוקות",
        "listgrouprights-helppage": "Help:הרשאות",
        "listgrouprights-members": "(רשימת חברים)",
        "listgrouprights-right-display": "<span class=\"listgrouprights-granted\">$1 <code dir=\"ltr\">($2)</code></span>",
+       "listgrouprights-right-revoked": "<span class=\"listgrouprights-revoked\">$1 <code dir=\"ltr\">($2)</code></span>",
        "listgrouprights-addgroup": "הוספת משתמשים ל{{PLURAL:$2|קבוצה|קבוצות}}: $1",
        "listgrouprights-removegroup": "הסרת משתמשים מה{{PLURAL:$2|קבוצה|קבוצות}}: $1",
        "listgrouprights-addgroup-all": "הוספת משתמשים לכל הקבוצות",
        "trackingcategories-desc": "הקריטריון להכללה בקטגוריה",
        "restricted-displaytitle-ignored": "דפים שכותרת התצוגה שלהם אינה מופעלת",
        "restricted-displaytitle-ignored-desc": "בדף הזה מוגדרת כותרת תצוגה (<code><nowiki>{{DISPLAYTITLE}}</nowiki></code>) שאינה מופעלת, כי היא אינה תואמת לכותרת האמיתית של הדף.",
-       "noindex-category-desc": "×\94×\93×£ ×\90×\99× ×\95 ×\9e×\90×\95× ×\93קס ×¢×\9câ\80\8fâ\80\8fÖ¾×\99×\93×\99 ×¨×\95×\91×\95×\98×\99×\9d ×\9b×\99×\95×\95×\9f ×©×\94×\95×\90 ×\9b×\95×\9c×\9c ×\90ת ×\9e×\99×\9cת ×\94קס×\9d <code><nowiki>__NOINDEX__</nowiki></code> והוא במרחב שם שבו דגל כזה מותר לשימוש.",
-       "index-category-desc": "הדף כולל את מילת הקסם <code><nowiki>__INDEX__</nowiki></code> (והוא במרחב שם שבו דגל כזה מותר לשימוש), ולכן הוא מאונדקס על‏‏֫־ידי רובוטים אף שכברירת מחדל הוא לא היה מאונדקס על ידם.",
-       "post-expand-template-inclusion-category-desc": "גודל הדף גדול מ‏‏־<code>$wgMaxArticleSize</code> לאחר הרחבת כל התבניות, ולכן כמה תבניות לא הורחבו.",
-       "post-expand-template-argument-category-desc": "הדף גדול מ־<code>$wgMaxArticleSize</code> לאחר הרחבת ארגומנט של תבנית (משהו בסוגריים משולשים, כגון <code>{{{Foo}}})</code>).",
-       "expensive-parserfunction-category-desc": "הדף משתמש ביותר מדי פונקציות מפענח יקרות לשימוש (כגון #קיים). ראו [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit].",
+       "noindex-category-desc": "×\94×\93×£ ×\90×\99× ×\95 ×\9e×\9e×\95פת×\97 ×¢×\9câ\80\8fâ\80\8fÖ¾×\99×\93×\99 ×¨×\95×\91×\95×\98×\99×\9d ×\9b×\99×\95×\95×\9f ×©×\94×\95×\90 ×\9b×\95×\9c×\9c ×\90ת ×\9e×\99×\9cת ×\94קס×\9d <code><nowiki>__×\9c×\90\9c×\97×\99פ×\95ש__</nowiki></code> (×\90×\95 <code><nowiki>__NOINDEX__</nowiki></code>) והוא במרחב שם שבו דגל כזה מותר לשימוש.",
+       "index-category-desc": "הדף כולל את מילת הקסם <code><nowiki>__לחיפוש__</nowiki></code> (או <code><nowiki>__INDEX__</nowiki></code>) (והוא במרחב שם שבו דגל כזה מותר לשימוש), ולכן הוא ממופתח על־ידי רובוטים אף שכברירת מחדל הוא לא היה ממפותח על־ידיהם.",
+       "post-expand-template-inclusion-category-desc": "גודל הדף גדול מ‏‏־<code dir=\"ltr\">$wgMaxArticleSize</code> לאחר הרחבת כל התבניות, ולכן כמה תבניות לא הורחבו.",
+       "post-expand-template-argument-category-desc": "הדף גדול מ־<code dir=\"ltr\">$wgMaxArticleSize</code> לאחר הרחבת פרמטר של תבנית (משהו בסוגריים משולשים, כגון <code>{{{Foo}}}</code>).",
+       "expensive-parserfunction-category-desc": "הדף משתמש ביותר מדי פונקציות מפענח יקרות לשימוש (כגון <code>#קיים</code> או <code dir=\"ltr\">#ifexist</code>). מידע נוסף: [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit].",
        "broken-file-category-desc": "הדף כולל קישור שבור לקובץ (קישור להטבעת קובץ כאשר הקובץ אינו קיים).",
-       "hidden-category-category-desc": "הקטגוריה כוללת את הטקסט <code><nowiki>__קטגוריה_מוסתרת__</nowiki></code> בתוכן הדף שלה, ולכן היא לא מופיעה בתיבת קישורי הקטגוריות בדפים כברירת מחדל.",
+       "hidden-category-category-desc": "הקטגוריה כוללת את הטקסט <code><nowiki>__קטגוריה_מוסתרת__</nowiki></code> (או <code><nowiki>__HIDDENCAT__</nowiki></code>) בתוכן הדף שלה, ולכן היא לא מופיעה בתיבת קישורי הקטגוריות בדפים כברירת מחדל.",
        "trackingcategories-nodesc": "התיאור אינו זמין.",
        "trackingcategories-disabled": "הקטגוריה מבוטלת",
        "mailnologin": "אין כתובת לשליחה",
        "emailpagetext": "ניתן להשתמש בטופס שלהלן כדי לשלוח הודעת דואר אלקטרוני {{GENDER:$1|למשתמש זה|למשתמשת זו}}.\nכתובת הדואר האלקטרוני שהזנת ב[[Special:Preferences|העדפות המשתמש שלך]] תופיע ככתובת שההודעה נשלחה ממנה, כדי לאפשר תגובה ישירה.",
        "defemailsubject": "דוא\"ל מ{{GRAMMAR:תחילית|{{SITENAME}}}} מה{{GENDER:$1|משתמש|משתמשת}} \"$1\"",
        "usermaildisabled": "שליחת דוא\"ל למשתמשים מבוטלת",
-       "usermaildisabledtext": "×\90×\99× ×\9b×\9d ×\9e×\95רש×\99×\9d לשלוח דואר אלקטרוני למשתמשים אחרים באתר זה",
+       "usermaildisabledtext": "×\90×\99×\9f ×\91×\90פשר×\95ת×\9a לשלוח דואר אלקטרוני למשתמשים אחרים באתר זה",
        "noemailtitle": "אין כתובת דואר אלקטרוני",
        "noemailtext": "משתמש זה לא הזין כתובת דואר אלקטרוני תקינה.",
        "nowikiemailtext": "משתמש זה בחר שלא לקבל דואר אלקטרוני ממשתמשים אחרים.",
        "emailsubject": "נושא:",
        "emailmessage": "הודעה:",
        "emailsend": "שליחה",
-       "emailccme": "שִלחו לי העתק של ההודעה שלי.",
+       "emailccme": "שלחו לי העתק של ההודעה שלי.",
        "emailccsubject": "העתק של הודעתך למשתמש $1: $2",
        "emailsent": "הדואר נשלח",
        "emailsenttext": "הודעת הדואר האלקטרוני שלך נשלחה.",
        "watchlist": "רשימת המעקב",
        "mywatchlist": "רשימת המעקב",
        "watchlistfor2": "עבור $1 $2",
-       "nowatchlist": "אין דפים ברשימת המעקב.",
+       "nowatchlist": "אין דפים ברשימת המעקב שלך.",
        "watchlistanontext": "נדרשת כניסה לחשבון כדי לצפות או לערוך פריטים ברשימת המעקב.",
        "watchnologin": "לא נכנסת לחשבון",
        "addwatch": "הוספה לרשימת המעקב",
        "addedwatchtext": "הדף \"[[:$1]]\" ודף השיחה שלו נוספו ל[[Special:Watchlist|רשימת המעקב]] שלך.",
        "addedwatchtext-talk": "הדף \"[[:$1]]\" ודף התוכן המשויך אליו נוספו ל[[Special:Watchlist|רשימת המעקב]] שלך.",
-       "addedwatchtext-short": "הדף \"$1\" נוסף לרשימת המעקב.",
+       "addedwatchtext-short": "הדף \"$1\" נוסף לרשימת המעקב שלך.",
        "removewatch": "הסרה מרשימת המעקב",
        "removedwatchtext": "הדף \"[[:$1]]\" ודף השיחה שלו הוסרו מ[[Special:Watchlist|רשימת המעקב]] שלך.",
        "removedwatchtext-talk": "הדף \"[[:$1]]\" ודף התוכן המשויך אליו הוסרו מ[[Special:Watchlist|רשימת המעקב]] שלך.",
-       "removedwatchtext-short": "הדף \"$1\" הוסר מרשימת המעקב.",
+       "removedwatchtext-short": "הדף \"$1\" הוסר מרשימת המעקב שלך.",
        "watch": "מעקב",
        "watchthispage": "מעקב אחרי דף זה",
        "unwatch": "הפסקת מעקב",
        "unwatchthispage": "הפסקת המעקב אחרי דף זה",
        "notanarticle": "זהו אינו דף תוכן",
        "notvisiblerev": "הגרסה האחרונה שנוצרה על־ידי משתמש אחר נמחקה",
-       "watchlist-details": "ברשימת המעקב שלך יש {{PLURAL:$1|דף אחד|$1 דפים}} (ובנוסף להם, דפי שיחה).",
+       "watchlist-details": "ברשימת המעקב שלך יש {{PLURAL:$1|דף אחד|$1 דפים}} (ובנוסף {{PLURAL:$1|אליו, דף|להם, דפי}} שיחה).",
        "wlheader-enotif": "הודעות דוא\"ל מאופשרות.",
-       "wlheader-showupdated": "דפים שהשתנו מאז ביקורך האחרון בהם מוצגים ב'''הדגשה'''.",
+       "wlheader-showupdated": "דפים שהשתנו מאז ביקורך האחרון בהם מוצגים ב<strong>הדגשה</strong>.",
        "wlnote": "להלן {{PLURAL:$1|השינוי האחרון|<strong>$1</strong> השינויים האחרונים}} {{PLURAL:$2|בשעה האחרונה|בשעתיים האחרונות|ב־<strong>$2</strong> השעות האחרונות}}, עד $4, $3.",
        "wlshowlast": "הצגת $1 שעות אחרונות $2 ימים אחרונים",
        "watchlist-hide": "הסתרת",
        "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": "×\94×\93×£ \"$1\" ×\91×\90תר {{SITENAME}} × ×\9e×\97ק ×\91Ö¾$PAGEEDITDATE ×¢×\9cÖ¾×\99×\93×\99 $2; ×¨×\90×\95 $3.",
-       "enotif_body_intro_created": "×\94×\93×£ \"$1\" ×\91×\90תר {{SITENAME}} × ×\95צר ×\91Ö¾$PAGEEDITDATE ×¢×\9cÖ¾×\99×\93×\99 $2; ×¨×\90×\95 $3 ×\9c×\92רס×\94 ×\94× ×\95×\9b×\97×\99ת ×©×\9c ×\94×\93×£.",
-       "enotif_body_intro_moved": "×\94×\93×£ \"$1\" ×\91×\90תר {{SITENAME}} ×\94×\95×¢×\91ר ×\91Ö¾$PAGEEDITDATE ×¢×\9cÖ¾×\99×\93×\99 $2; ×¨×\90×\95 $3 ×\9c×\92רס×\94 ×\94× ×\95×\9b×\97×\99ת ×©×\9c ×\94×\93×£.",
-       "enotif_body_intro_restored": "×\94×\93×£ \"$1\" ×\91×\90תר {{SITENAME}} ×©×\95×\97×\96ר ×\91Ö¾$PAGEEDITDATE ×¢×\9cÖ¾×\99×\93×\99 $2; ×¨×\90×\95 $3 ×\9c×\92רס×\94 ×\94× ×\95×\9b×\97×\99ת ×©×\9c ×\94×\93×£.",
-       "enotif_body_intro_changed": "×\94×\93×£ \"$1\" ×\91×\90תר {{SITENAME}} ×©×\95Ö¼× ×\94 ×\91Ö¾$PAGEEDITDATE ×¢×\9cÖ¾×\99×\93×\99 $2; ×¨×\90×\95 $3 ×\9c×\92רס×\94 ×\94× ×\95×\9b×\97×\99ת ×©×\9c ×\94×\93×£.",
-       "enotif_lastvisited": "×\9c×\9b×\9c ×\94ש×\99× ×\95×\99×\99×\9d ×\9e×\90×\96 ×\91×\99ק×\95ר×\9b×\9d האחרון בדף, ר' $1",
+       "enotif_body_intro_deleted": "×\94×\93×£ \"$1\" ×\91×\90תר {{SITENAME}} × ×\9e×\97ק ×\91Ö¾$PAGEEDITDATE ×¢×\9cÖ¾×\99×\93×\99 $2; ×\9c×\94×\9c×\9f ×\94ק×\99ש×\95ר ×\9c×\93×£: $3.",
+       "enotif_body_intro_created": "×\94×\93×£ \"$1\" ×\91×\90תר {{SITENAME}} × ×\95צר ×\91Ö¾$PAGEEDITDATE ×¢×\9cÖ¾×\99×\93×\99 $2; ×\9c×\94×\9c×\9f ×§×\99ש×\95ר ×\9c×\92רס×\94 ×\94× ×\95×\9b×\97×\99ת ×©×\9c ×\94×\93×£: $3.",
+       "enotif_body_intro_moved": "×\94×\93×£ \"$1\" ×\91×\90תר {{SITENAME}} ×\94×\95×¢×\91ר ×\91Ö¾$PAGEEDITDATE ×¢×\9cÖ¾×\99×\93×\99 $2; ×\9c×\94×\9c×\9f ×§×\99ש×\95ר ×\9c×\92רס×\94 ×\94× ×\95×\9b×\97×\99ת ×©×\9c ×\94×\93×£: $3.",
+       "enotif_body_intro_restored": "×\94×\93×£ \"$1\" ×\91×\90תר {{SITENAME}} ×©×\95×\97×\96ר ×\91Ö¾$PAGEEDITDATE ×¢×\9cÖ¾×\99×\93×\99 $2; ×\9c×\94×\9c×\9f ×§×\99ש×\95ר ×\9c×\92רס×\94 ×\94× ×\95×\9b×\97×\99ת ×©×\9c ×\94×\93×£: $3.",
+       "enotif_body_intro_changed": "×\94×\93×£ \"$1\" ×\91×\90תר {{SITENAME}} ×©×\95Ö¼× ×\94 ×\91Ö¾$PAGEEDITDATE ×¢×\9cÖ¾×\99×\93×\99 $2; ×\9c×\94×\9c×\9f ×§×\99ש×\95ר ×\9c×\92רס×\94 ×\94× ×\95×\9b×\97×\99ת ×©×\9c ×\94×\93×£: $3.",
+       "enotif_lastvisited": "×\9cצפ×\99×\99×\94 ×\91×\9b×\9c ×\94ש×\99× ×\95×\99×\99×\9d ×\9e×\90×\96 ×\91×\99ק×\95ר×\9a האחרון בדף, ר' $1",
        "enotif_lastdiff": "לצפייה בשינוי זה, ר' $1",
        "enotif_anon_editor": "משתמש אנונימי $1",
-       "enotif_body": "×\9c×\9b×\91×\95×\93 $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nתקצ×\99ר ×\94ער×\99×\9b×\94: $PAGESUMMARY $PAGEMINOREDIT\n\n×\91×\90פשר×\95ת×\9b×\9d ×\9c×\99צ×\95ר ×§×©×¨ ×¢×\9d ×\94×¢×\95ר×\9a:\n×\91×\93×\95×\90ר ×\90×\9cק×\98ר×\95× ×\99: $PAGEEDITOR_EMAIL\n×\91×\90תר: $PAGEEDITOR_WIKI\n\n×\9c×\90 ×ª×§×\91×\9c×\95 ×\94×\95×\93×¢×\95ת ×¢×\9c ×¤×¢×\95×\9c×\95ת × ×\95ספ×\95ת ×¢×\93 ×©×ª×\91קר×\95 ×\91×\93×£ ×\94×\96×\94 ×\9bש×\90ת×\9d ×\9e×\97×\95×\91ר×\99×\9d ×\9c×\97ש×\91×\95×\9f. ×\91×\90פשר×\95ת×\9b×\9d ×\92×\9d ×\9c×\90פס ×\90ת ×\93×\92×\9c×\99 ×\94×\94×\95×\93×¢×\95ת ×¢×\91×\95ר ×\9b×\9c ×\94×\93פ×\99×\9d ×©×\91רש×\99×\9eת ×\94×\9eעק×\91 ×©×\9c×\9b×\9d.\n\n×\91×\91ר×\9b×\94, ×\9eער×\9bת ×\94×\94×\95×\93×¢×\95ת ×©×\9c {{SITENAME}}.\n\n--\n×\9b×\93×\99 ×\9cשנ×\95ת ×\90ת ×\94×\94×\92×\93ר×\95ת ×©×\9c ×\94×\95×\93×¢×\95ת ×\94×\93×\95×\90\"×\9c ×\94נש×\9c×\97×\95ת ×\90×\9c×\99×\9b×\9d, ×\91קר×\95 ×\91×\93×£:\n{{canonicalurl:{{#special:Preferences}}}}\n\n×\9b×\93×\99 ×\9cשנ×\95ת ×\90ת ×\94×\94×\92×\93ר×\95ת ×©×\9c ×¨×©×\99×\9eת ×\94×\9eעק×\91 ×©×\9c×\9b×\9d, ×\91קר×\95 ×\91×\93×£:\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\n×\9b×\93×\99 ×\9c×\94ס×\99ר ×\90ת ×\94×\93×£ ×\94×\96×\94 ×\9eרש×\99×\9eת ×\94×\9eעק×\91 ×©×\9c×\9b×\9d, ×\91קר×\95 בדף:\n$UNWATCHURL\n\nלמשוב ולעזרה נוספת:\n$HELPPAGE",
+       "enotif_body": "×\9c×\9b×\91×\95×\93 $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nתקצ×\99ר ×\94ער×\99×\9b×\94: $PAGESUMMARY $PAGEMINOREDIT\n\n×\91×\90פשר×\95ת×\9a ×\9c×\99צ×\95ר ×§×©×¨ ×¢×\9d ×\94×¢×\95ר×\9a:\n×\91×\93×\95×\90ר ×\90×\9cק×\98ר×\95× ×\99: $PAGEEDITOR_EMAIL\n×\91×\90תר: $PAGEEDITOR_WIKI\n\n×\9c×\90 ×ª×\94×\99×\99× ×\94 ×\94×\95×\93×¢×\95ת ×¢×\9c ×¤×¢×\95×\9c×\95ת × ×\95ספ×\95ת ×¢×\93 ×\9c×\91×\99ק×\95ר×\9a ×\91×\93×£ ×\94×\96×\94 ×\9e×\94×\97ש×\91×\95×\9f ×©×\9c×\9a. ×\91×\90פשר×\95ת×\9a ×\92×\9d ×\9c×\90פס ×\90ת ×\93×\92×\9c×\99 ×\94×\94×\95×\93×¢×\95ת ×¢×\91×\95ר ×\9b×\9c ×\94×\93פ×\99×\9d ×©×\91רש×\99×\9eת ×\94×\9eעק×\91 ×©×\9c×\9a.\n\n×\91×\91ר×\9b×\94, ×\9eער×\9bת ×\94×\94×\95×\93×¢×\95ת ×©×\9c {{SITENAME}}.\n\n--\n×\9b×\93×\99 ×\9cשנ×\95ת ×\90ת ×\94×\94×\92×\93ר×\95ת ×©×\9c ×\94×\95×\93×¢×\95ת ×\94×\93×\95×\90\"×\9c, ×\91×\90פשר×\95ת×\9a ×\9c×\91קר ×\91×\93×£:\n{{canonicalurl:{{#special:Preferences}}}}\n\n×\9b×\93×\99 ×\9cשנ×\95ת ×\90ת ×\94×\94×\92×\93ר×\95ת ×©×\9c ×¨×©×\99×\9eת ×\94×\9eעק×\91 ×©×\9c×\9a, ×\91×\90פשר×\95ת×\9a ×\9c×\91קר ×\91×\93×£:\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\n×\9b×\93×\99 ×\9c×\94ס×\99ר ×\90ת ×\94×\93×£ ×\94×\96×\94 ×\9eרש×\99×\9eת ×\94×\9eעק×\91 ×©×\9c×\9a, ×\91×\90פשר×\95ת×\9a ×\9c×\91קר בדף:\n$UNWATCHURL\n\nלמשוב ולעזרה נוספת:\n$HELPPAGE",
        "enotif_minoredit": "זוהי עריכה משנית",
        "created": "נוצר",
        "changed": "שוּנה",
        "exbeforeblank": "התוכן לפני שרוקן היה: \"$1\"",
        "delete-confirm": "מחיקת הדף \"$1\"",
        "delete-legend": "מחיקה",
-       "historywarning": "<strong>אזהרה:</strong> לדף ש{{GENDER:|אתה עומד|את עומדת|אתם עומדים}} למחוק יש היסטוריית שינויים של {{PLURAL:$1|גרסה אחת|$1 גרסאות}}:",
+       "historywarning": "<strong>אזהרה:</strong> לדף שעומד להימחק יש היסטוריית שינויים של {{PLURAL:$1|גרסה אחת|$1 גרסאות}}:",
        "historyaction-submit": "הצגה",
-       "confirmdeletetext": "×\90ת×\9d ×¢×\95×\9e×\93×\99×\9d ×\9c×\9e×\97×\95ק ×\93×£ ×\99×\97×\93 ×¢×\9d ×\9b×\9c ×\94×\94×\99ס×\98×\95ר×\99×\94 ×©×\9c×\95.\n\n×\90× ×\90 ×\90שר×\95 ×©×\96×\94 ×\90×\9b×\9f ×\9e×\94 ×©×\90ת×\9d ×\9eת×\9b×\95×\95× ×\99×\9d ×\9cעש×\95ת, ×©×\90ת×\9d ×\9e×\91×\99× ×\99×\9d ×\90ת ×\94ת×\95צ×\90×\95ת ×©×\9c ×\9eעש×\94 ×\9b×\96×\94, ושהמעשה מבוצע בהתאם ל[[{{MediaWiki:Policy-url}}|נוהלי האתר]].",
+       "confirmdeletetext": "× ×\99ת×\9f ×\9c×\94שת×\9eש ×\91×\98×\95פס ×©×\9c×\94×\9c×\9f ×\9b×\93×\99 ×\9c×\9e×\97×\95ק ×\93×£ ×\99×\97×\93 ×¢×\9d ×\9b×\9c ×\94×\94×\99ס×\98×\95ר×\99×\94 ×©×\9c×\95.\n× ×\90 ×\9c×\90שר ×©×\96×\94 ×\90×\9b×\9f ×\9e×\94 ×©×\94ת×\9b×\95×\95נת ×\9cעש×\95ת, ×©×\94ת×\95צ×\90×\95ת ×©×\9c ×\94פע×\95×\9c×\94 ×\94×\96×\95 ×\99×\93×\95×¢×\95ת ×\9c×\9a, ושהמעשה מבוצע בהתאם ל[[{{MediaWiki:Policy-url}}|נוהלי האתר]].",
        "actioncomplete": "הפעולה בוצעה",
        "actionfailed": "הפעולה נכשלה",
-       "deletedtext": "\"$1\" נמחק.\nראו $2 לרשימת המחיקות האחרונות.",
+       "deletedtext": "הדף \"$1\" נמחק.\nרשימת המחיקות האחרונות מופיעה ב$2.",
        "dellogpage": "יומן מחיקות",
        "dellogpagetext": "להלן רשימה של המחיקות האחרונות שבוצעו.",
-       "deletionlog": "יומן מחיקות",
+       "deletionlog": "×\99×\95×\9e×\9f ×\94×\9e×\97×\99ק×\95ת",
        "reverted": "שוחזר לגרסה קודמת",
        "deletecomment": "סיבה:",
        "deleteotherreason": "סיבה אחרת/נוספת:",
        "deletereason-dropdown": "* סיבות מחיקה נפוצות\n** ספאם\n** השחתה\n** הפרת זכויות יוצרים\n** לבקשת הכותב\n** הפניה שבורה",
        "delete-edit-reasonlist": "עריכת סיבות המחיקה",
        "delete-toobig": "לדף זה יש היסטוריית עריכות גדולה, שמכילה יותר {{PLURAL:$1|מגרסה אחת|מ־$1 גרסאות}}.\nמחיקת דפים כאלה הוגבלה כדי למנוע בעיות בתפקוד של {{SITENAME}}.",
-       "delete-warning-toobig": "דף זה כולל מעל {{PLURAL:$1|גרסה אחת|$1 גרסאות}} בהיסטוריית העריכות שלו. מחיקה שלו עלולה להפריע לפעולות בבסיס הנתונים; אנא שקלו שנית את המחיקה.",
+       "delete-warning-toobig": "דף זה כולל מעל {{PLURAL:$1|גרסה אחת|$1 גרסאות}} בהיסטוריית העריכות שלו.\nמחיקה שלו עלולה להפריע לפעולות בבסיס הנתונים של {{SITENAME}};\nנא לשקול שנית את המחיקה.",
        "deleteprotected": "אין באפשרותך למחוק את הדף כי הוא מוגן.",
-       "deleting-backlinks-warning": "<strong>×\90×\96×\94ר×\94:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|×\93פ×\99×\9d ×\90×\97ר×\99×\9d]] ×\9eקשר×\99×\9d ×\9c×\93×£ ×©{{GENDER:|×\90ת×\94 ×¢×\95×\9e×\93\90ת ×¢×\95×\9e×\93ת|×\90ת×\9d ×¢×\95×\9e×\93×\99×\9d}} ×\9c×\9e×\97×\95ק או מכלילים אותו.",
-       "deleting-subpages-warning": "<strong>אזהרה:</strong> לדף ש{{GENDER:|אתה עומד|את עומדת|אתם עומדים}} למחוק יש [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|דף משנה|$1 דפי משנה|51=יותר מ־50 דפי משנה}}]].",
+       "deleting-backlinks-warning": "<strong>×\90×\96×\94ר×\94:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|×\93פ×\99×\9d ×\90×\97ר×\99×\9d]] ×\9eקשר×\99×\9d ×\9c×\93×£ ×\96×\94 (שע×\95×\9e×\93 ×\9c×\94×\99×\9e×\97ק) או מכלילים אותו.",
+       "deleting-subpages-warning": "<strong>אזהרה:</strong> לדף שעומד להימחק יש [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|דף משנה|$1 דפי משנה|51=יותר מ־50 דפי משנה}}]].",
        "rollback": "שחזור עריכות",
        "rollbacklink": "שחזור",
        "rollbacklinkcount": "שחזור {{PLURAL:$1|עריכה אחת|$1 עריכות}}",
        "rollback-missingparam": "חסרים פרמטרים נדרשים להגשת הבקשה.",
        "rollback-missingrevision": "לא ניתן לטעון את המידע על הגרסה.",
        "cantrollback": "לא ניתן לשחזר את העריכה;\nהתורם האחרון הוא היחיד שכתב בדף זה.",
-       "alreadyrolled": "לא ניתן לשחזר את העריכה של [[User:$2|$2]] ([[User talk:$2|שיחה]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) בדף [[:$1]]; הדף כבר נערך או שוחזר.\n\nהעריכה האחרונה הייתה של [[User:$3|$3]] ([[User talk:$3|שיחה]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
+       "alreadyrolled": "לא ניתן לשחזר את העריכה של [[User:$2|$2]] ([[User talk:$2|שיחה]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) בדף [[:$1]];\nהדף כבר נערך או שוחזר.\n\nהעריכה האחרונה הייתה של [[User:$3|$3]] ([[User talk:$3|שיחה]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "תקציר העריכה היה: <em>$1</em>.",
        "revertpage": "שוחזר מעריכות של [[Special:Contributions/$2|$2]] ([[User talk:$2|שיחה]]) לעריכה האחרונה של [[User:$1|$1]]",
        "revertpage-nouser": "שוחזר מעריכות של משתמש מוסתר לעריכה האחרונה של {{GENDER:$1|[[User:$1|$1]]}}",
-       "rollback-success": "שוחזר מעריכות של {{GENDER:$3|$1}} לעריכה האחרונה של {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "שוחזר מעריכות של $1 לעריכה האחרונה של $2. [$3 הצגת שינויים]",
+       "rollback-success": "שוחזר מעריכות של {{GENDER:$3|$1}}\nלעריכה האחרונה של {{GENDER:$4|$2}}.",
+       "rollback-success-notify": "שוחזר מעריכות של $1\nלעריכה האחרונה של $2. [$3 הצגת שינויים]",
        "sessionfailure-title": "בעיה בחיבור",
        "sessionfailure": "נראה שיש בעיה בחיבור שלך לאתר;\nפעולה זו בוטלה כאמצעי זהירות נגד התחזות לתקשורת ממחשבך.\nנא לשלוח מחדש את הטופס.",
        "changecontentmodel": "שינוי מודל התוכן של דף",
        "log-name-contentmodel": "יומן שינויי מודל תוכן",
        "log-description-contentmodel": "בדף זה מופיעים שינויים במודל התוכן של דפים, וכן דפים שנוצרו עם מודל תוכן שונה מברירת המחדל.",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|יצר|יצרה}} את הדף $3 תוך שימוש במודל התוכן \"$5\" השונה ממודל ברירת המחדל",
-       "logentry-contentmodel-change": "$1 {{GENDER:$2|שינה|שינתה}} את מודל התוכן של הדף $3 מ\"$4\" ל\"$5\"",
+       "logentry-contentmodel-change": "$1 {{GENDER:$2|שינה|שינתה}} את מודל התוכן של הדף $3 מ{{GRAMMAR:תחילית|$4}} ל{{GRAMMAR:תחילית|$5}}",
        "logentry-contentmodel-change-revertlink": "שחזור",
        "logentry-contentmodel-change-revert": "שחזור",
        "protectlogpage": "יומן הגנות",
-       "protectlogtext": "×\9c×\94×\9c×\9f ×¨×©×\99×\9e×\94 ×©×\9c ×©×\99× ×\95×\99×\99 ×\94×\94×\92× ×\94 ×¢×\9c ×\93פ×\99×\9d.\nר×\90×\95 ×\92×\9d ×\90ת [[Special:ProtectedPages|רשימת הדפים המוגנים]] הנוכחית.",
+       "protectlogtext": "×\9c×\94×\9c×\9f ×¨×©×\99×\9e×\94 ×©×\9c ×©×\99× ×\95×\99×\99 ×\94×\94×\92× ×\94 ×¢×\9c ×\93פ×\99×\9d.\n× ×\99ת×\9f ×\9c×¢×\99×\99×\9f ×\92×\9d ×\91[[Special:ProtectedPages|רשימת הדפים המוגנים]] הנוכחית.",
        "protectedarticle": "הופעלה הגנה על הדף \"[[$1]]\"",
        "modifiedarticleprotection": "רמת ההגנה של הדף \"[[$1]]\" שונתה",
        "unprotectedarticle": "ההגנה הוסרה מהדף \"[[$1]]\"",
        "protect_expiry_invalid": "זמן פקיעת ההגנה אינו תקין.",
        "protect_expiry_old": "זמן פקיעת ההגנה כבר עבר.",
        "protect-unchain-permissions": "שינוי אפשרויות הגנה נוספות",
-       "protect-text": "בדף זה אפשר לראות ולשנות את רמת ההגנה של הדף '''$1'''.",
-       "protect-locked-blocked": "×\90×\99× ×\9b×\9d ×\99×\9b×\95×\9c×\99×\9d ×\9cשנ×\95ת ×\90ת ×¨×\9eת ×\94×\94×\92× ×\94 ×©×\9c ×\94×\93×£ ×\91×¢×\95×\93×\9b×\9d ×\97ס×\95×\9e×\99×\9d.\n×\9c×\94×\9c×\9f ×\94×\94×\92×\93ר×\95ת ×\94× ×\95×\9b×\97×\99×\95ת ×¢×\91×\95ר ×\94×\93×£ '''$1''':",
-       "protect-locked-dblock": "×\9c×\90 × ×\99ת×\9f ×\9cשנ×\95ת ×\90ת ×¨×\9eת ×\94×\94×\92× ×\94 ×¢×\9c ×\94×\93×£ ×\9e×\9b×\99×\95×\95×\9f ×©×\91ס×\99ס ×\94נת×\95× ×\99×\9d ×\97ס×\95×\9d ×\91ר×\92×¢ ×\96×\94.\n×\9c×\94×\9c×\9f ×\94×\94×\92×\93ר×\95ת ×\94× ×\95×\9b×\97×\99×\95ת ×¢×\91×\95ר ×\94×\93×£ '''$1''':",
-       "protect-locked-access": "לחשבון המשתמש שלך אין הרשאה לשנות את רמת ההגנה של הדף.\nלהלן ההגדרות הנוכחיות עבור הדף '''$1''':",
+       "protect-text": "בדף זה אפשר לראות ולשנות את רמת ההגנה של הדף <strong>$1</strong>.",
+       "protect-locked-blocked": "×\90×\99×\9f ×\91×\90פשר×\95ת×\9a ×\9cשנ×\95ת ×\90ת ×¨×\9eת ×\94×\94×\92× ×\94 ×©×\9c ×\94×\93×£ ×\9b×\99×\95×\95×\9f ×©× ×\97ס×\9eת.\n×\9c×\94×\9c×\9f ×\94×\94×\92×\93ר×\95ת ×\94× ×\95×\9b×\97×\99×\95ת ×¢×\91×\95ר ×\94×\93×£ <strong>$1</strong>:",
+       "protect-locked-dblock": "×\9c×\90 × ×\99ת×\9f ×\9cשנ×\95ת ×\90ת ×¨×\9eת ×\94×\94×\92× ×\94 ×¢×\9c ×\94×\93×£ ×\9e×\9b×\99×\95×\95×\9f ×©×\91ס×\99ס ×\94נת×\95× ×\99×\9d × ×¢×\95×\9c ×\91ר×\92×¢ ×\96×\94.\n×\9c×\94×\9c×\9f ×\94×\94×\92×\93ר×\95ת ×\94× ×\95×\9b×\97×\99×\95ת ×¢×\91×\95ר ×\94×\93×£ <strong>$1</strong>:",
+       "protect-locked-access": "לחשבון המשתמש שלך אין הרשאה לשנות את רמת ההגנה של הדף.\nלהלן ההגדרות הנוכחיות עבור הדף <strong>$1</strong>:",
        "protect-cascadeon": "דף זה מוגן כרגע כיוון שהוא מוכלל {{PLURAL:$1|בדף הבא, שמופעלת עליו|בדפים הבאים, שמופעלת עליהם}} הגנה מדורגת.\nשינויים ברמת ההגנה על הדף לא ישפיעו על ההגנה המדורגת.",
        "protect-default": "כל המשתמשים מורשים",
        "protect-fallback": "רק משתמשים בעלי הרשאת \"$1\" מורשים",
        "viewdeletedpage": "הצגה של דפים מחוקים",
        "undeletepagetext": "{{PLURAL:$1|הדף שלהלן נמחק, אך הוא עדיין בארכיון וניתן לשחזר אותו|הדפים שלהלן נמחקו, אך הם עדיין בארכיון וניתן לשחזר אותם}}.\nייתכן שהארכיון ינוקה מעת לעת.",
        "undelete-fieldset-title": "שחזור גרסאות",
-       "undeleteextrahelp": "×\9b×\93×\99 ×\9cש×\97×\96ר ×\90ת ×\94×\99ס×\98×\95ר×\99×\99ת ×\94×\92רס×\90×\95ת ×\94×\9e×\9c×\90×\94 ×©×\9c ×\94×\93×£, ×\90×\9c {{GENDER:|תס×\9e×\9f|תס×\9e× ×\99|תס×\9e× ×\95}} ×©×\95×\9d ×ª×\99×\91ת ×¡×\99×\9e×\95×\9f; ×¤×©×\95×\98 {{GENDER:|×\9c×\97×¥|×\9c×\97צ×\99\9c×\97צ×\95}} ×¢×\9c <strong>{{int:undeletebtn}}</strong>.\n×\9b×\93×\99 ×\9cש×\97×\96ר ×\92רס×\90×\95ת ×\9eס×\95×\99×\9e×\95ת ×\91×\9c×\91×\93, {{GENDER:|ס×\9e×\9f|ס×\9e× ×\99|ס×\9e× ×\95}} ×\90ת ×\94×\92רס×\90×\95ת ×©{{GENDER:|×\91רצ×\95× ×\9a\91רצ×\95× ×\9a\91רצ×\95× ×\9b×\9d}} ×\9cש×\97×\96ר ×\95×\9c×\90×\97ר ×\9e×\9b×\9f {{GENDER:|×\9c×\97×¥|×\9c×\97צ×\99\9c×\97צ×\95}} על <strong>{{int:undeletebtn}}</strong>.",
+       "undeleteextrahelp": "×\9b×\93×\99 ×\9cש×\97×\96ר ×\90ת ×\94×\99ס×\98×\95ר×\99×\99ת ×\94×\92רס×\90×\95ת ×\94×\9e×\9c×\90×\94 ×©×\9c ×\94×\93×£, ×\99ש ×\9c×\94ש×\90×\99ר ×\90ת ×\9b×\9c ×ª×\99×\91×\95ת ×\94ס×\99×\9e×\95×\9f ×¨×\99ק×\95ת ×\95×\9c×\9c×\97×\95×¥ ×¢×\9c <strong>{{int:undeletebtn}}</strong>.\n×\9b×\93×\99 ×\9cש×\97×\96ר ×\92רס×\90×\95ת ×\9eס×\95×\99×\9e×\95ת ×\91×\9c×\91×\93, ×\99ש ×\9cס×\9e×\9f ×\90ת ×\94×\92רס×\90×\95ת ×©×ª×©×\95×\97×\96רנ×\94 ×\95×\9c×\90×\97ר ×\9e×\9b×\9f ×\9c×\9c×\97×\95×¥ על <strong>{{int:undeletebtn}}</strong>.",
        "undeleterevisions": "{{PLURAL:$1|גרסה אחת נמחקה|$1 גרסאות נמחקו}}",
-       "undeletehistory": "×\90×\9d {{GENDER:|תש×\97×\96ר|תש×\97×\96ר×\99|תש×\97×\96ר×\95}} ×\90ת ×\94×\93×£, ×\94×\92רס×\90×\95ת ×\99ש×\95×\97×\96ר×\95 ×\9c×\94×\99ס×\98×\95ר×\99×\99ת ×\94ש×\99× ×\95×\99×\99×\9d ×©×\9c×\95.\n×\90×\9d ×\94×\93×£ ×\94×\96×\94 × ×\9e×\97ק ×\91×¢×\91ר ×\95×\9c×\90×\97ר ×\9e×\9b×\9f × ×\95צר ×\9e×\97×\93ש, ×\94×\92רס×\90×\95ת ×©{{GENDER:|תש×\97×\96ר|תש×\97×\96ר×\99|תש×\97×\96ר×\95}} ×\99×\9e×\95×\96×\92×\95 ×\9c×\94×\99ס×\98×\95ר×\99×\99ת ×\94ש×\99× ×\95×\99×\99×\9d ×©×\9c ×\94×\93×£ ×\95×\99×\95פ×\99×¢×\95 ×\91ת×\95ר ×\94×\92רס×\90×\95ת ×\94×\99שנ×\95ת ×\91×\99×\95תר ×©×\9c×\95.",
+       "undeletehistory": "ש×\97×\96×\95ר ×\94×\93×£ ×\99×\92ר×\95×\9d ×\9c×\9b×\9a ×©×\94×\92רס×\90×\95ת ×©×\9c×\95 ×ª×©×\95×\97×\96רנ×\94 ×\95ת×\95פענ×\94 ×\91×\94×\99ס×\98×\95ר×\99×\99ת ×\94ש×\99× ×\95×\99×\99×\9d ×©×\9c ×\94×\93×£.\n×\90×\9d ×\94×\93×£ ×\94×\96×\94 × ×\9e×\97ק ×\91×¢×\91ר ×\95×\9c×\90×\97ר ×\9e×\9b×\9f × ×\95צר ×\9e×\97×\93ש ×\91×\90×\95ת×\95 ×\94ש×\9d, ×\94×\92רס×\90×\95ת ×\94×\9eש×\95×\97×\96ר×\95ת ×ª×\95פענ×\94 ×\91ת×\95ר ×\94×\92רס×\90×\95ת ×\94×\99שנ×\95ת ×\91×\99×\95תר.",
        "undeleterevdel": "השחזור לא יכול להתבצע אם הגרסה האחרונה של הדף מחוקה או מוסתרת.\nבמקרה כזה, יש לבטל קודם את ההסתרה של הגרסה האחרונה.",
        "undeletehistorynoadmin": "דף זה נמחק.\nהסיבה למחיקה מוצגת בתקציר שלמטה, וגם פרטים על המשתמשים שערכו את הדף לפני שהוא נמחק.\nהטקסט של הגרסאות הללו זמין למפעילי מערכת בלבד.",
        "undelete-revision": "גרסה שנמחקה מהדף $1 (מ־$5, $4) מאת $3:",
-       "undeleterevision-missing": "הגרסה שגויה או חסרה. ייתכן שמדובר בקישור שבור, או שהגרסה שוחזרה או הוסרה מהארכיון.",
+       "undeleterevision-missing": "הגרסה שגויה או חסרה.\nייתכן שמדובר בקישור שבור, או שהגרסה שוחזרה או הוסרה מהארכיון.",
        "undeleterevision-duplicate-revid": "לא ניתן היה לשחזר {{PLURAL:$1|גרסה אחת|$1 גרסאות}}, כיוון ששדה <code>rev_id</code> {{PLURAL:$1|שלה|שלהן}} כבר נמצא בשימוש.",
        "undelete-nodiff": "לא נמצאה גרסה קודמת.",
        "undeletebtn": "שחזור",
        "undeleteinvert": "הפיכת הבחירה",
        "undeletecomment": "סיבה:",
        "cannotundelete": "השחזור (או חלק ממנו) נכשל:\n$1",
-       "undeletedpage": "<strong>×\94×\93×£ $1 ×©×\95×\97×\96ר</strong>\n\nר×\90×\95 ×\90ת [[Special:Log/delete|×\99×\95×\9e×\9f ×\94×\9e×\97×\99ק×\95ת]] ×\9cרש×\99×\9e×\94 ×©×\9c ×\94×\9e×\97×\99ק×\95ת ×\95×\94ש×\97×\96×\95ר×\99×\9d ×©×\91×\95צע×\95 ×\9c×\90×\97ר×\95× ×\94.",
-       "undelete-header": "{{GENDER:|ראה|ראי|ראו}} את [[Special:Log/delete|יומן המחיקות]] לרשימה של דפים שנמחקו לאחרונה.",
+       "undeletedpage": "<strong>×\94×\93×£ $1 ×©×\95×\97×\96ר</strong>\n\nרש×\99×\9eת ×\94×\9e×\97×\99ק×\95ת ×\95×\94ש×\97×\96×\95ר×\99×\9d ×©×\91×\95צע×\95 ×\9c×\90×\97ר×\95× ×\94 ×\9e×\95פ×\99×¢×\94 ×\91[[Special:Log/delete|×\99×\95×\9e×\9f ×\94×\9e×\97×\99ק×\95ת]].",
+       "undelete-header": "רשימת הדפים שנמחקו לאחרונה מופיעה ב[[Special:Log/delete|יומן המחיקות]].",
        "undelete-search-title": "חיפוש דפים שנמחקו",
        "undelete-search-box": "חיפוש דפים שנמחקו",
        "undelete-search-prefix": "הצגת דפים החל מ:",
        "undelete-filename-mismatch": "לא ניתן לשחזר את גרסת הקובץ מ־$1: שם הקובץ לא תואם.",
        "undelete-bad-store-key": "לא ניתן לשחזר את גרסת הקובץ מ־$1: הקובץ היה חסר לפני המחיקה.",
        "undelete-cleanup-error": "שגיאת בעת מחיקת קובץ הארכיון \"$1\" שאינו בשימוש.",
-       "undelete-missing-filearchive": "שחזור קובץ הארכיון שמספרו $1 נכשל כיוון שהוא אינו בבסיס הנתונים. ייתכן שהוא כבר שוחזר.",
+       "undelete-missing-filearchive": "שחזור קובץ הארכיון שמספרו $1 נכשל כיוון שהוא אינו בבסיס הנתונים.\nייתכן שהוא כבר שוחזר.",
        "undelete-error": "שגיאה בשחזור דף",
        "undelete-error-short": "שגיאה בשחזור הקובץ: $1",
        "undelete-error-long": "שגיאות שאירעו בעת שחזור הקובץ:\n\n$1",
-       "undelete-show-file-confirm": "×\94×\90×\9d ×\90ת×\9d ×\91×\98×\95×\97×\99×\9d ×©×\91רצ×\95× ×\9b×\9d לצפות בגרסה המחוקה של הקובץ \"<nowiki>$1</nowiki>\" מ־$3, $2?",
+       "undelete-show-file-confirm": "×\94×\90×\9d ×\91רצ×\95× ×\9a לצפות בגרסה המחוקה של הקובץ \"<nowiki>$1</nowiki>\" מ־$3, $2?",
        "undelete-show-file-submit": "כן",
        "namespace": "מרחב שם:",
        "invert": "ללא מרחב זה",
        "tooltip-invert": "יש לסמן תיבה זו כדי להסתיר שינויים בדפים בתוך מרחב השם שנבחר (ובתוך מרחב השם הצמוד, אם הוא סומן)",
-       "tooltip-whatlinkshere-invert": "יש לסמן תיבה זו כדי להסתיר קישורים מדפים בתוך מרחב השם שנבחר",
+       "tooltip-whatlinkshere-invert": "יש לסמן תיבה זו כדי להסתיר קישורים מדפים בתוך מרחב השם שנבחר.",
        "namespace_association": "מרחב שם צמוד",
        "tooltip-namespace_association": "יש לסמן תיבה זו כדי לכלול גם את מרחב דפי השיחה או דפי הנושא המשויכים למרחב השם הנבחר",
        "blanknamespace": "(ראשי)",
        "sp-contributions-newonly": "הצגת עריכות שהן יצירות של דפים בלבד",
        "sp-contributions-hideminor": "הסתרת עריכות משניות",
        "sp-contributions-submit": "חיפוש",
-       "sp-contributions-outofrange": "לא ניתן להציג תוצאות. טווח ה־IP המבוקש גדול יותר ממגבלת ה־CIDR, שהיא /$1.",
+       "sp-contributions-outofrange": "לא ניתן להציג תוצאות. טווח ה־IP המבוקש גדול יותר ממגבלת ה־CIDR, שהיא <span dir=\"ltr\">/$1</span>.",
        "whatlinkshere": "דפים המקושרים לכאן",
        "whatlinkshere-title": "דפים המקשרים לדף \"$1\"",
        "whatlinkshere-page": "דף:",
-       "linkshere": "הדפים שלהלן מקושרים לדף '''[[:$1]]''':",
-       "nolinkshere": "אין דפים המקושרים לדף '''[[:$1]]'''.",
-       "nolinkshere-ns": "אין דפים המקושרים לדף '''[[:$1]]''' במרחב השם שנבחר.",
+       "linkshere-2": "הדפים שלהלן מקשרים לדף <strong>$1</strong>:",
+       "nolinkshere-2": "אין דפים המקשרים לדף <strong>$1</strong>.",
+       "nolinkshere-ns-2": "אין דפים המקשרים לדף <strong>$1</strong> במרחב השם שנבחר.",
        "isredirect": "דף הפניה",
        "istemplate": "הכללה",
        "isimage": "קישור לקובץ",
        "whatlinkshere-hidetrans": "$1 הכללות",
        "whatlinkshere-hidelinks": "$1 קישורים",
        "whatlinkshere-hideimages": "$1 קישורים לקובץ",
-       "whatlinkshere-filters": "×\9eסננ×\99×\9d",
+       "whatlinkshere-filters": "ס×\99× ×\95×\9f",
        "whatlinkshere-submit": "הצגה",
        "autoblockid": "חסימה אוטומטית #$1",
        "block": "חסימת משתמש",
        "unblock": "שחרור חסימה של משתמש",
        "blockip": "חסימת ה{{GENDER:$1|משתמש|משתמשת}}",
-       "blockiptext": "×\94שת×\9eש×\95 ×\91×\98×\95פס ×©×\9c×\94×\9c×\9f ×\9b×\93×\99 ×\9c×\97ס×\95×\9d ×\90ת ×\94רש×\90×\95ת ×\94×\9bת×\99×\91×\94 ×\9e×\9bת×\95×\91ת IP ×\90×\95 ×\9eשת×\9eש ×\9eס×\95×\99×\9e×\99×\9d.\n×\97ס×\99×\9e×\95ת ×\9b×\90×\9c×\94 ×¦×¨×\99×\9b×\95ת ×\9c×\94ת×\91צע ×¨×§ ×\9b×\93×\99 ×\9c×\9e× ×\95×¢ ×\94ש×\97ת×\94, ×\95×\91×\94ת×\90×\9d ×\9c[[{{MediaWiki:Policy-url}}|× ×\94×\9c×\99×\9d]].\n×\90× ×\90 ×\9e×\9c×\90×\95 ×\90ת ×\94ס×\99×\91×\94 ×\94פר×\98× ×\99ת ×\9c×\97ס×\99×\9e×\94 ×\9c×\94×\9c×\9f (×\9c×\93×\95×\92×\9e×\94, ×\91×\90×\9eצע×\95ת ×¦×\99×\95×\9f ×\93פ×\99×\9d ×\9eס×\95×\99×\9e×\99×\9d ×©×\94ש×\97×\99ת ×\94×\9eשת×\9eש).\n×\91×\90פשר×\95ת×\9b×\9d לחסום טווחי כתובות IP באמצעות תחביר [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR]; הטווח הגדול ביותר שניתן לחסום הוא <span dir=\"ltr\">/$1</span> עבור IPv4 ו־<span dir=\"ltr\">/$2</span> עבור IPv6.",
+       "blockiptext": "× ×\99ת×\9f ×\9c×\94שת×\9eש ×\91×\98×\95פס ×©×\9c×\94×\9c×\9f ×\9b×\93×\99 ×\9c×\97ס×\95×\9d ×\90ת ×\94רש×\90×\95ת ×\94×\9bת×\99×\91×\94 ×\9e×\9bת×\95×\91ת IP ×\9eס×\95×\99×\9eת ×\90×\95 ×\9eש×\9d ×\9eשת×\9eש ×\9eס×\95×\99×\9d.\n×\97ס×\99×\9e×\95ת ×\9b×\90×\9c×\94 ×¦×¨×\99×\9b×\95ת ×\9c×\94ת×\91צע ×¨×§ ×\9b×\93×\99 ×\9c×\9e× ×\95×¢ ×\94ש×\97ת×\94, ×\95×\91×\94ת×\90×\9d ×\9c[[{{MediaWiki:Policy-url}}|× ×\94×\9c×\99×\9d]].\n×\99ש ×\9c×\9e×\9c×\90 ×\90ת ×\94ס×\99×\91×\94 ×\94פר×\98× ×\99ת ×\9c×\97ס×\99×\9e×\94 ×\9c×\94×\9c×\9f (×\9c×\93×\95×\92×\9e×\94, ×\91×\90×\9eצע×\95ת ×¦×\99×\95×\9f ×\93פ×\99×\9d ×\9eס×\95×\99×\9e×\99×\9d ×©×\94ש×\97×\99ת ×\94×\9eשת×\9eש).\n×\91×\90פשר×\95ת×\9a לחסום טווחי כתובות IP באמצעות תחביר [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR]; הטווח הגדול ביותר שניתן לחסום הוא <span dir=\"ltr\">/$1</span> עבור IPv4 ו־<span dir=\"ltr\">/$2</span> עבור IPv6.",
        "ipaddressorusername": "כתובת IP או שם משתמש:",
        "ipbexpiry": "פקיעה:",
        "ipbreason": "סיבה:",
        "ipb-disableusertalk": "ביטול האפשרות של המשתמש לערוך את דף השיחה של עצמו בעת החסימה",
        "ipb-change-block": "חסימת המשתמש מחדש עם הגדרות אלה",
        "ipb-confirm": "אישור החסימה",
-       "badipaddress": "×\9eשת×\9eש ×\90×\95 ×\9bת×\95×\91ת IP ×©×\92×\95×\99×\99×\9d.",
+       "badipaddress": "×\9bת×\95×\91ת IP ×©×\92×\95×\99×\94",
        "blockipsuccesssub": "החסימה הושלמה בהצלחה",
-       "blockipsuccesstext": "{{GENDER:$1|המשתמש|המשתמשת}} [[Special:Contributions/$1|$1]] {{GENDER:$1|נחסם|נחסמה}}.\n\nראו את [[Special:BlockList|רשימת החסומים]] כדי לצפות בחסימות.",
+       "blockipsuccesstext": "{{GENDER:$1|המשתמש|המשתמשת}} [[Special:Contributions/$1|$1]] {{GENDER:$1|נחסם|נחסמה}}.<br />\nניתן לעיין ב[[Special:BlockList|רשימת החסומים]] כדי לצפות בחסימות.",
        "ipb-blockingself": "{{GENDER:|אתה עומד|את עומדת|אתם עומדים}} לחסום את {{GENDER:|עצמך|עצמך|עצמכם}}! האם {{GENDER:|אתה בטוח שאתה רוצה|את בטוחה שאת רוצה|אתם בטוחים שאתם רוצים}} לעשות את זה?",
        "ipb-confirmhideuser": "{{GENDER:|אתה עומד|את עומדת|אתם עומדים}} לחסום משתמש עם האפשרות \"הסתרת משתמש\". זה יעלים את שם המשתמש בכל הרשימות ופעולות היומן. האם {{GENDER:|אתה בטוח שברצונך|את בטוחה שברצונך|אתם בטוחים שברצונכם}} לעשות את זה?",
        "ipb-confirmaction": "אם {{GENDER:|אתה בטוח שברצונך|את בטוחה שברצונך|אתם בטוחים שברצונכם}} לעשות זאת, אנא {{GENDER:|סמן|סמני|סמנו}} את השדה \"{{int:ipb-confirm}}\" שמופיע למטה.",
        "sessionprovider-generic": "התחברויות של $1",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "התחברויות המבוססות על עוגיות",
        "sessionprovider-nocookies": "ייתכן שאפשרות השימוש בעוגיות כבויה. יש לוודא שאפשרות השימוש בעוגיות מופעלת ולהתחיל מחדש.",
-       "randomrootpage": "×\93×£ ×©×\95רש אקראי",
+       "randomrootpage": "×\93×£ ×\91ס×\99ס אקראי",
        "log-action-filter-block": "סוג החסימות:",
        "log-action-filter-contentmodel": "סוג השינויים במודל התוכן:",
        "log-action-filter-delete": "סוג המחיקות:",
        "linkaccounts": "קישור חשבונות",
        "linkaccounts-success-text": "החשבון קושר.",
        "linkaccounts-submit": "קישור החשבונות",
-       "unlinkaccounts": "×\91×\99×\98×\95×\9c ×\94ק×\99ש×\95ר ×©×\9c ×\94חשבונות",
+       "unlinkaccounts": "×\91×\99×\98×\95×\9c ×\94ק×\99ש×\95ר ×\91×\99×\9f חשבונות",
        "unlinkaccounts-success": "קישור החשבון בוטל.",
        "authenticationdatachange-ignored": "השינוי בנתוני האימות לא הצליח. ייתכן שלא הוגדר ספק.",
        "userjsispublic": "לתשומת לבך: משתמשים אחרים יכולים לצפות בדפי ה־JavaScript שלך, ולכן אין לכלול בהם מידע סודי.",
        "pagedata-title": "מידע על הדף",
        "pagedata-text": "דף זה מהווה ממשק מידע לדפים. כדי להשתמש בו, כותרת הדף צריכה להופיע בכתובת ה־URL, בעזרת התחביר המתאים לדפי־משנה.\n* דף זה משתמש בשיטת \"ניתוב התוכן\" (Content negotiation) בהתבסס על כותרת ה־Accept ששולח צד הלקוח. פירוש הדבר הוא שהמידע על הדף יישלח בפורמט שצד הלקוח (כגון דפדפן) מעדיף.",
        "pagedata-not-acceptable": "לא נמצא פורמט נתמך. סוגי MIME נתמכים: $1",
-       "pagedata-bad-title": "כותרת בלתי־תקינה: $1."
+       "pagedata-bad-title": "כותרת בלתי־תקינה: $1.",
+       "unregistered-user-config": "מסיבות אבטחה, לא ניתן לטעון דפי JavaScript‏, CSS ו־JSON בדפי משנה של משתמשים שאינם קיימים.",
+       "passwordpolicies": "מדיניות הסיסמאות",
+       "passwordpolicies-summary": "להלן חוקי הסיסמאות שנמצאים בשימוש עבור קבוצות המשתמש באתר זה.",
+       "passwordpolicies-group": "קבוצה",
+       "passwordpolicies-policies": "מדיניות",
+       "passwordpolicies-policy-minimalpasswordlength": "הסיסמה חייבת להיות באורך של {{PLURAL:$1|תו אחד|$1 תווים}} לפחות",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "הסיסמה חייבת להיות באורך של {{PLURAL:$1|תו אחד|$1 תווים}} לפחות כדי שניתן יהיה להיכנס לחשבון",
+       "passwordpolicies-policy-passwordcannotmatchusername": "הסיסמה לא יכולה להיות זהה לשם המשתמש",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "הסיסמה לא יכולה להתאים לסיסמאות מסוימות שנמצאות ברשימה השחורה",
+       "passwordpolicies-policy-maximalpasswordlength": "הסיסמה חייבת להיות קצרה יותר {{PLURAL:$1|מתו אחד|מ־$1 תווים}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "הסיסמה לא יכולה להיות זהה {{PLURAL:$1|לסיסמה נפוצה|לאחת הסיסמאות שנמצאות ברשימה של $1 הסיסמאות הנפוצות}}"
 }
index da053eb..2bf6fc3 100644 (file)
        "whatlinkshere": "यहाँ क्या जुड़ता है",
        "whatlinkshere-title": "$1 से जुड़े हुए पृष्ठ",
        "whatlinkshere-page": "पृष्ठ:",
-       "linkshere": "नीचे दिये हुए पृष्ठ '''[[:$1]]''' से जुडते हैं:",
-       "nolinkshere": "<strong>[[:$1]]</strong> से कोई भी पन्ना नहीं जुड़ा है।",
-       "nolinkshere-ns": "चुने हुए नामस्थानसे '''[[:$1]]''' को जुडने वाले पृष्ठ नहीं हैं।",
+       "linkshere-2": "नीचे दिये हुए पृष्ठ '''$1''' से जुडते हैं:",
+       "nolinkshere-2": "<strong>$1</strong> से कोई भी पन्ना नहीं जुड़ा है।",
+       "nolinkshere-ns-2": "चुने हुए नामस्थानसे '''$1''' को जुडने वाले पृष्ठ नहीं हैं।",
        "isredirect": "पुनर्निर्देशन पृष्ठ",
        "istemplate": "मिलाईयें",
        "isimage": "फ़ाइल प्रयोग",
index 83ce743..b215c80 100644 (file)
        "whatlinkshere": "Hian konchij jurre hae",
        "whatlinkshere-title": "Panna jon ki $1 se jurre hai",
        "whatlinkshere-page": "Panna:",
-       "linkshere": "Niche waala panna '''[[:$1]]''' se jorre hai:",
-       "nolinkshere": "Koi panna '''[[:$1]]''' ke nai jorre hai.",
-       "nolinkshere-ns": "Chuna gais namespace me koi panna '''[[:$1]]''' se nai jiurre hai.",
+       "linkshere-2": "Niche waala panna '''$1''' se jorre hai:",
+       "nolinkshere-2": "Koi panna '''$1''' ke nai jorre hai.",
+       "nolinkshere-ns-2": "Chuna gais namespace me koi panna '''$1''' se nai jiurre hai.",
        "isredirect": "panna ke redirect karo",
        "istemplate": "milao",
        "isimage": "file ke jorr",
index e0eacc7..7de08f0 100644 (file)
        "whatlinkshere": "Ang nagatabid diri",
        "whatlinkshere-title": "Mga pahina nga naga tabid sa $1",
        "whatlinkshere-page": "Pahina:",
-       "linkshere": "Ang mga sumunod nga pahina ay nagatabid sa '''[[:$1]]''':",
-       "nolinkshere": "Waay panid nga nakasugpon sa '''[[:$1]]'''.",
+       "linkshere-2": "Ang mga sumunod nga pahina ay nagatabid sa '''$1''':",
+       "nolinkshere-2": "Waay panid nga nakasugpon sa '''$1'''.",
        "isredirect": "pahina sa ginadirekta liwat",
        "istemplate": "transklusyon",
        "isimage": "Ang sugpon sang file",
index d629156..def7267 100644 (file)
        "whatlinkshere": "Što vodi ovamo",
        "whatlinkshere-title": "Stranice koje vode na »$1«",
        "whatlinkshere-page": "Stranica:",
-       "linkshere": "Sljedeće stranice povezuju ovamo ([[:$1]]):",
-       "nolinkshere": "Nijedna stranica ne vodi ovamo (tj. nema poveznica na stranicu [[:$1]]).",
-       "nolinkshere-ns": "Nijedna stranica ne vodi na '''[[:$1]]''' u odabranom imenskom prostoru.",
+       "linkshere-2": "Sljedeće stranice povezuju ovamo ($1):",
+       "nolinkshere-2": "Nijedna stranica ne vodi ovamo (tj. nema poveznica na stranicu $1).",
+       "nolinkshere-ns-2": "Nijedna stranica ne vodi na '''$1''' u odabranom imenskom prostoru.",
        "isredirect": "stranica za preusmjeravanje",
        "istemplate": "kao predložak",
        "isimage": "poveznica na datoteku",
        "show-big-image": "Vidi sliku u punoj veličini",
        "show-big-image-preview": "Veličina ovog prikaza: $1.",
        "show-big-image-preview-differ": "Veličina ovog $3 prikaza ove $2 datoteke: $1.",
-       "show-big-image-other": "{{PLURAL:$2|Druga rezolucija|Ostale rezolucije}}: $1.",
+       "show-big-image-other": "{{PLURAL:$2|Druga razlučivost|Ostale razlučivosti}}: $1.",
        "show-big-image-size": "$1 × $2 piksela",
        "file-info-gif-looped": "animacija se ponavlja",
        "file-info-gif-frames": "$1 {{PLURAL:$1|okvir|okvira}}",
index 0793174..88774fd 100644 (file)
        "whatlinkshere": "Links uff die Seit",
        "whatlinkshere-title": "Seite, die uff \"$1\" verlinke",
        "whatlinkshere-page": "Seit:",
-       "linkshere": "Die follichende Seite verlinke uff '''\"[[:$1]]\"''':",
-       "nolinkshere": "Ken Seit verlinkt uff '''„[[:$1]]“'''.",
-       "nolinkshere-ns": "Ken Seit verlinkt uff '''\"[[:$1]]\"''' im gewählte Noomeraum.",
+       "linkshere-2": "Die follichende Seite verlinke uff '''\"$1\"''':",
+       "nolinkshere-2": "Ken Seit verlinkt uff '''„$1“'''.",
+       "nolinkshere-ns-2": "Ken Seit verlinkt uff '''\"$1\"''' im gewählte Noomeraum.",
        "isredirect": "Weiterleitungsseit",
        "istemplate": "Voarlooche-einbinnunge (transclusões)",
        "isimage": "Dateilink",
        "fileduplicatesearch-noresults": "Do woarde keh Datei mit dem Noome \"$1\" gefunn.",
        "specialpages": "Spezialseite",
        "specialpages-note-top": "Legende",
+       "specialpages-note-restricted": "* Normal Spezialseite.\n* <span class=\"mw-specialpagerestricted\">Spezialseite mit beschränktem Zugang.</span>",
        "specialpages-group-maintenance": "Woortungsliste",
        "specialpages-group-other": "Annre Spezialseite",
        "specialpages-group-login": "Benutzerkonto",
index 652f58e..735e55e 100644 (file)
        "whatlinkshere": "Što wotkazuje sem",
        "whatlinkshere-title": "Strony, kotrež na „$1“ wotkazuja",
        "whatlinkshere-page": "Strona:",
-       "linkshere": "Sćěhowace strony na stronu '''[[:$1]]''' wotkazuja:",
-       "nolinkshere": "Žane strony na '''[[:$1]]''' njewotkazuja.",
-       "nolinkshere-ns": "Žane strony njewotkazuja na '''[[:$1]]''' we wubranym mjenowym rumje.",
+       "linkshere-2": "Sćěhowace strony na stronu '''$1''' wotkazuja:",
+       "nolinkshere-2": "Žane strony na '''$1''' njewotkazuja.",
+       "nolinkshere-ns-2": "Žane strony njewotkazuja na '''$1''' we wubranym mjenowym rumje.",
        "isredirect": "daleposrědkowanje",
        "istemplate": "zapřijeće předłohi",
        "isimage": "Datajowy wotkaz",
        "fileduplicatesearch-noresults": "Žana dataja z mjenom \"$1\" namakana.",
        "specialpages": "Specialne strony",
        "specialpages-note-top": "Legenda",
+       "specialpages-note-restricted": "* Normalne specialne strony.\n* <span class=\"mw-specialpagerestricted\">Specialne strony z wobmjezowanym přistupom.</span>",
        "specialpages-group-maintenance": "Hladanske lisćiny",
        "specialpages-group-other": "Druhe specialne strony",
        "specialpages-group-login": "Přizjewić/Konto załožić",
index 4ce20c8..04d5473 100644 (file)
        "whatlinkshere": "Paj ki gen lyen vè paj sa a",
        "whatlinkshere-title": "Paj ki genyen lyen ki ap mennen nan \"$1\"",
        "whatlinkshere-page": "Paj :",
-       "linkshere": "Paj yo ki anba ap mene nan <b>[[:$1]]</b> :",
-       "nolinkshere": "Pyès paj genyen lyen pou paj sa a <b>[[:$1]]</b>.",
+       "linkshere-2": "Paj yo ki anba ap mene nan <b>$1</b> :",
+       "nolinkshere-2": "Pyès paj genyen lyen pou paj sa a <b>$1</b>.",
        "isredirect": "paj redireksyon",
        "istemplate": "anndan",
        "isimage": "lyen fichye a",
index f82859f..fb955f6 100644 (file)
        "subject-preview": "Tárgy előnézete:",
        "previewerrortext": "Hiba történt a változások előnézetének megjelenítése során.",
        "blockedtitle": "A szerkesztő blokkolva van",
-       "blockedtext": "<strong>A szerkesztőnevedet vagy az IP-címedet blokkoltuk.</strong>\n\nA blokkolást $1 végezte el.\nAz általa felhozott indok: <em>$2.</em>\n\n* A blokk kezdete: $8\n* A blokk lejárata: $6\n* Blokkolt szerkesztő: $7\n\nKapcsolatba léphetsz $1 szerkesztőnkkel vagy egy másik [[{{MediaWiki:Grouppage-sysop}}|adminisztrátorral]], és megbeszélheted vele a blokkolást.\nAz „E-mail küldése ennek a szerkesztőnek” funkciót csak akkor használhatod, ha érvényes e-mail címet adtál meg [[Special:Preferences|fiókbeállításaidban]], és nem blokkolták a használatát.\nJelenlegi IP-címed: $3, a blokkolás azonosítószáma: #$5.\nKérjük, hogy érdeklődés esetén minden fenti részletet adj meg.",
-       "autoblockedtext": "Az IP-címed automatikusan blokkolva lett, mert korábban egy olyan szerkesztő használta, akit $1 blokkolt, az alábbi indoklással:\n\n:''$2''\n\n*A blokk kezdete: '''$8'''\n*A blokk lejárata: '''$6'''\n*Blokkolt szerkesztő: '''$7'''\n\nKapcsolatba léphetsz $1 szerkesztőnkkel, vagy egy másik [[{{MediaWiki:Grouppage-sysop}}|adminisztrátorral]], és megbeszélheted vele a blokkolást.\n\nAz 'E-mail küldése ennek a szerkesztőnek' funkciót csak akkor használhatod, ha érvényes e-mail címet adtál meg\n[[Special:Preferences|fiókbeállításaidban]], és nem blokkolták a használatát.\n\nJelenlegi IP-címed: $3, a blokkolás azonosítószáma: #$5.\nKérjük, hogy érdeklődés esetén mindkettőt add meg.",
+       "blockedtext": "<strong>A szerkesztőnevedet vagy az IP-címedet blokkoltuk.</strong>\n\nA blokkolást $1 végezte el.\nAz általa felhozott indok: <em>$2.</em>\n\n* A blokk kezdete: $8\n* A blokk lejárata: $6\n* Blokkolt szerkesztő: $7\n\nKapcsolatba léphetsz $1 szerkesztőnkkel vagy egy másik [[{{MediaWiki:Grouppage-sysop}}|adminisztrátorral]], és megbeszélheted vele a blokkolást.\nAz „{{int:emailuser}}” funkciót csak akkor használhatod, ha érvényes e-mail-címet adtál meg [[Special:Preferences|fiókbeállításaidban]], és nem blokkolták a használatát.\nJelenlegi IP-címed: $3, a blokkolás azonosítószáma: #$5.\nKérjük, hogy érdeklődés esetén minden fenti részletet adj meg.",
+       "autoblockedtext": "Az IP-címed automatikusan blokkolva lett, mert korábban egy olyan szerkesztő használta, akit $1 blokkolt, az alábbi indoklással:\n\n:''$2''\n\n*A blokk kezdete: '''$8'''\n*A blokk lejárata: '''$6'''\n*Blokkolt szerkesztő: '''$7'''\n\nKapcsolatba léphetsz $1 szerkesztőnkkel, vagy egy másik [[{{MediaWiki:Grouppage-sysop}}|adminisztrátorral]], és megbeszélheted vele a blokkolást.\n\nAz „{{int:emailuser}}” funkciót csak akkor használhatod, ha érvényes e-mail címet adtál meg\n[[Special:Preferences|fiókbeállításaidban]], és nem blokkolták a használatát.\n\nJelenlegi IP-címed: $3, a blokkolás azonosítószáma: #$5.\nKérjük, hogy érdeklődés esetén mindkettőt add meg.",
        "systemblockedtext": "A felhasználónevedet vagy IP-címedet automatikusan blokkolta a MediaWiki.\nA blokkolás indoka:\n\n:<em>$2</em>\n\n* A blokk kezdete: $8\n* A blokk lejárata: $6\n* Blokkolt szerkesztő: $7\n\nA jelenlegi IP-címed: $3.\nKérjük, hogy érdeklődés esetén minden fenti részletet adj meg.",
        "blockednoreason": "nem adott meg okot",
        "whitelistedittext": "Lapok szerkesztéséhez $1.",
        "longpageerror": "'''HIBA: Az általad beküldött szöveg {{PLURAL:$1|egy kilobájt|$1 kilobájt}} hosszú, ami több az engedélyezett {{PLURAL:$2|egy kilobájtnál|$2 kilobájtnál}}.\nA szerkesztést nem lehet elmenteni.'''",
        "readonlywarning": "<strong>FIGYELMEZTETÉS: A wiki adatbázisát karbantartás miatt zárolták, ezért most nem fogod tudni elmenteni a szerkesztéseidet!</strong>\nA lap szövegét másold egy szövegfájlba, amit később felhasználhatsz!\n\nAz adatbázist lezáró rendszeradminisztrátor az alábbi magyarázatot adta: $1",
        "protectedpagewarning": "<strong>Figyelem: Ez a lap védett, így csak adminisztrátori jogosultságokkal rendelkező szerkesztők módosíthatják.</strong>\nA legutolsó ide vonatkozó naplóbejegyzés alább látható:",
-       "semiprotectedpagewarning": "'''Megjegyzés:''' ez a lap védett, így regisztrálatlan vagy újonnan regisztrált szerkesztők nem módosíthatják.",
+       "semiprotectedpagewarning": "<strong>Megjegyzés:</strong> ez a lap védett, így regisztrálatlan vagy újonnan regisztrált szerkesztők nem módosíthatják.\nA lapra vonatkozó utolsó naplóbejegyzés alább látható:",
        "cascadeprotectedwarning": "<strong>Figyelem:</strong> ez a lap le van zárva, csak [[Special:ListGroupRights|megfelelő jogosultságú]] felhasználók szerkeszthetik, mert a következő kaszkádvédelemmel ellátott {{PLURAL:$1|lapon|lapokon}} be van illesztve:",
        "titleprotectedwarning": "'''Figyelem: Ez a lap le van védve, így csak a [[Special:ListGroupRights|megfelelő jogosultságokkal]] rendelkező szerkesztők hozhatják létre.'''\nA legutolsó ide vonatkozó naplóbejegyzés alább látható:",
        "templatesused": "A lapon használt {{PLURAL:$1|sablon|sablonok}}:",
        "rcfilters-tag-remove": "$1 eltávolítása",
        "rcfilters-legend-heading": "<strong>Rövidítések listája:</strong>",
        "rcfilters-other-review-tools": "Egyéb hasznos hivatkozások",
-       "rcfilters-group-results-by-page": "Csoportosítás eredményei lapok szerint",
+       "rcfilters-group-results-by-page": "Eredmények csoportosítása lapok szerint",
        "rcfilters-activefilters": "Aktív szűrők",
        "rcfilters-advancedfilters": "Haladó szűrők",
        "rcfilters-limit-title": "Megjelenítendő találatok száma",
        "recentchangeslinked-feed": "Kapcsolódó változtatások",
        "recentchangeslinked-toolbox": "Kapcsolódó változtatások",
        "recentchangeslinked-title": "A(z) $1 laphoz kapcsolódó változtatások",
-       "recentchangeslinked-summary": "Alább azon lapoknak a legutóbbi változtatásai láthatóak, amelyekre hivatkozik egy megadott lap. (Ha egy kategória tagjaira vagy kíváncsi, írd be, hogy Kategória:katerógianév.)\nA [[Special:Watchlist|figyelőlistádon]] szereplő lapok '''félkövérrel''' vannak jelölve.",
+       "recentchangeslinked-summary": "Alább azon lapoknak a legutóbbi változtatásai láthatóak, amelyekre hivatkozik egy megadott lap. (Ha egy kategória tagjaira vagy kíváncsi, írd be, hogy {{ns:category}}:katerógianév.)\nA [[Special:Watchlist|figyelőlistádon]] szereplő lapok <strong>félkövérrel</strong> vannak jelölve.",
        "recentchangeslinked-page": "Lap neve:",
        "recentchangeslinked-to": "Inkább az erre linkelő lapok változtatásait mutasd",
        "recentchanges-page-added-to-category": "[[:$1]] hozzáadva a kategóriához",
        "watchlistanontext": "Jelentkezz be a figyelőlistád megtekintéséhez és szerkesztéséhez.",
        "watchnologin": "Nem vagy bejelentkezve",
        "addwatch": "Hozzáadás a figyelőlistához",
-       "addedwatchtext": "A(z) „[[:$1]]” lapot és vitalapját hozzáadtam a [[Special:Watchlist|figyelőlistádhoz]].",
-       "addedwatchtext-talk": "A(z) „[[:$1]]” lapot és a hozzá tartozó tartalmi lapot hozzáadtam a [[Special:Watchlist|figyelőlistádhoz]].",
+       "addedwatchtext": "A(z) „[[:$1]]” lap és vitalapja hozzáadva a [[Special:Watchlist|figyelőlistádhoz]].",
+       "addedwatchtext-talk": "A(z) „[[:$1]]” lap és a hozzá tartozó tartalmi lap hozzáadva a [[Special:Watchlist|figyelőlistádhoz]].",
        "addedwatchtext-short": "Az oldal: \"$1\" hozzá lett adva a figyelőlistádhoz.",
        "removewatch": "Eltávolítás a figyelőlistáról",
-       "removedwatchtext": "A(z) „[[:$1]]” lapot és vitalapját eltávolítottam a [[Special:Watchlist|figyelőlistáról]].",
-       "removedwatchtext-talk": "A(z) „[[:$1]]” lapot és a hozzá tartozó tartalmi lapot eltávolítottam a [[Special:Watchlist|figyelőlistáról]].",
+       "removedwatchtext": "A(z) „[[:$1]]” lap és vitalapja eltávolítva a [[Special:Watchlist|figyelőlistádról]].",
+       "removedwatchtext-talk": "A(z) „[[:$1]]” lap és a hozzá tartozó tartalmi lap eltávolítva a [[Special:Watchlist|figyelőlistádról]].",
        "removedwatchtext-short": "Az oldal: \"$1\" el lett távolítva a figyelőlistádról.",
        "watch": "Lap figyelése",
        "watchthispage": "Lap figyelése",
        "whatlinkshere": "Mi hivatkozik erre",
        "whatlinkshere-title": "A(z) „$1” lapra hivatkozó lapok",
        "whatlinkshere-page": "Lap:",
-       "linkshere": "Az alábbi lapok hivatkoznak erre: [[:$1]]",
-       "nolinkshere": "[[:$1]]: erre a lapra egyetlen más lap sem hivatkozik.",
-       "nolinkshere-ns": "A kiválasztott névtérben egyetlen oldal sem hivatkozik a(z) '''[[:$1]]''' lapra.",
+       "linkshere-2": "Az alábbi lapok hivatkoznak erre: $1",
+       "nolinkshere-2": "$1: erre a lapra egyetlen más lap sem hivatkozik.",
+       "nolinkshere-ns-2": "A kiválasztott névtérben egyetlen oldal sem hivatkozik a(z) '''$1''' lapra.",
        "isredirect": "átirányítás",
        "istemplate": "beillesztve",
        "isimage": "fájlhivatkozás",
        "watchlistedit-normal-legend": "Lapok eltávolítása a figyelőlistáról",
        "watchlistedit-normal-explain": "A figyelőlistádra felvett lapok címei alább láthatóak.\nHa el szeretnél távolítani egy címet, pipáld ki a mellette található jelölőnégyzetet, majd kattints „{{int:Watchlistedit-normal-submit}}” gombra.\nLehetőséged van a [[Special:EditWatchlist/raw|figyelőlista nyers változatának]] szerkesztésére is.",
        "watchlistedit-normal-submit": "A kijelöltek eltávolítása",
-       "watchlistedit-normal-done": "{{PLURAL:$1|A következő|A következő $1}} cikket eltávolítottam a figyelőlistádról:",
+       "watchlistedit-normal-done": "{{PLURAL:$1|A következő|A következő $1}} cikket eltávolítottuk a figyelőlistádról:",
        "watchlistedit-raw-title": "A nyers figyelőlista szerkesztése",
        "watchlistedit-raw-legend": "A nyers figyelőlista szerkesztése",
        "watchlistedit-raw-explain": "A figyelőlistádra felvett lapok az alábbi listában találhatók. A lista szerkeszthető;\nminden egyes sor egy figyelt lap címe. Ha kész vagy, kattints a lista alatt található\n„{{int:Watchlistedit-raw-submit}}” feliratú gombra. Használhatod a [[Special:EditWatchlist|hagyományos listaszerkesztőt]] is.",
        "watchlistedit-raw-titles": "A figyelőlistádon található cikkek:",
        "watchlistedit-raw-submit": "Mentés",
        "watchlistedit-raw-done": "A figyelőlistád változtatásait elmentettem.",
-       "watchlistedit-raw-added": "A {{PLURAL:$1|következő|következő $1}} cikket hozzáadtam a figyelőlistádhoz:",
-       "watchlistedit-raw-removed": "A {{PLURAL:$1|következő|következő $1}} cikket eltávolítottam a figyelőlistádról:",
+       "watchlistedit-raw-added": "A {{PLURAL:$1|következő|következő $1}} cikket hozzáadtuk a figyelőlistádhoz:",
+       "watchlistedit-raw-removed": "A {{PLURAL:$1|következő|következő $1}} cikket eltávolítottuk a figyelőlistádról:",
        "watchlistedit-clear-title": "A figyelőlista kiürítése",
        "watchlistedit-clear-legend": "Figyelőlista kiürítése",
        "watchlistedit-clear-explain": "Minden cím el lesz távolítva a figyelőlistádról",
        "undelete-cantcreate": "Nem állíthatod helyre ezt a lapot, mert nem létezik ilyen című lap, és nincs jogosultságod létrehozni azt.",
        "pagedata-title": "Az oldal adatai",
        "pagedata-not-acceptable": "Nem található megfelelő formátum. Támogatott MIME-típusok: $1",
-       "pagedata-bad-title": "Érvénytelen cím: $1."
+       "pagedata-bad-title": "Érvénytelen cím: $1.",
+       "unregistered-user-config": "Biztonsági okokból JavaScript, CSS és JSON szerkesztői alapok nem töltődnek be regisztrálatlan felhasználóknak.",
+       "passwordpolicies": "Jelszóirányelvek",
+       "passwordpolicies-group": "Csoport",
+       "passwordpolicies-policies": "Irányelvek",
+       "passwordpolicies-policy-minimalpasswordlength": "A jelszónak legalább $1 karakterből kell állnia",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "A jelszónak legalább $1 karakterből kell állnia a bejelentkezéshez",
+       "passwordpolicies-policy-passwordcannotmatchusername": "A jelszó nem lehet azonos a felhasználónévvel",
+       "passwordpolicies-policy-maximalpasswordlength": "A jelszó legfeljebb $1 karakter hosszú lehet"
 }
index 19c20ab..9c2d190 100644 (file)
        "whatlinkshere": "Այստեղ հղվող էջերը",
        "whatlinkshere-title": "Էջեր, որոնք հղում են դեպի «$1»",
        "whatlinkshere-page": "Էջ.",
-       "linkshere": "Հետևյալ էջերը հղում են '''[[:$1]]''' էջին.",
-       "nolinkshere": "Ուրիշ էջերից '''[[:$1]]''' էջին հղումներ չկան։",
-       "nolinkshere-ns": "Ընտրված անվանատարածքում '''[[:$1]]''' էջին հղվող էջեր չկան։",
+       "linkshere-2": "Հետևյալ էջերը հղում են '''$1''' էջին.",
+       "nolinkshere-2": "Ուրիշ էջերից '''$1''' էջին հղումներ չկան։",
+       "nolinkshere-ns-2": "Ընտրված անվանատարածքում '''$1''' էջին հղվող էջեր չկան։",
        "isredirect": "վերահղման էջ",
        "istemplate": "ներառում",
        "isimage": "ֆայլի հղում",
        "fileduplicatesearch-result-n": "$1 նիշքն ունի {{PLURAL:$2|1 նույնական կրկնօրինակ|$2 նույնական կրկնօրինակ}}.",
        "fileduplicatesearch-noresults": "$1 անունով նիշք չի գտնվել",
        "specialpages": "Սպասարկող էջեր",
+       "specialpages-note-restricted": "* Հասարակ հատուկ էջեր։\n* <span class=\"mw-specialpagerestricted\">Սահմանափակված հատուկ էջեր։</span>",
        "specialpages-group-maintenance": "Տեխնիկական սպասարկման տեղեկատուներ",
        "specialpages-group-other": "Այլ հատուկ էջեր",
        "specialpages-group-login": "Մտնել / Գրանցվել",
index 3efb8ca..3ebb9f5 100644 (file)
@@ -54,7 +54,7 @@
        "tog-watchlisthideminor": "Celar modificationes minor in le observatorio",
        "tog-watchlisthideliu": "Celar modificationes de usatores registrate in le observatorio",
        "tog-watchlistreloadautomatically": "Recargar automaticamente le observatorio quando un filtro es cambiate (JavaScript requirite)",
-       "tog-watchlistunwatchlinks": "Adjunger ligamines directe pro disobservar/observar al entratas del observatorio (JavaScript es necessari pro le functionalitate de alternar)",
+       "tog-watchlistunwatchlinks": "Adjunger marcatores directe pro disobservar/observar ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) al paginas sub observation que ha cambiate (JavaScript es necessari pro le functionalitate de alternar)",
        "tog-watchlisthideanons": "Celar modificationes de usatores anonyme in le observatorio",
        "tog-watchlisthidepatrolled": "Celar le modificationes patruliate in le observatorio",
        "tog-watchlisthidecategorization": "Celar le categorisation de paginas",
        "cascadeprotected": "Iste pagina ha essite protegite contra modificationes perque illo es transcludite in le sequente {{PLURAL:$1|pagina, le qual|paginas, le quales}} es protegite usante le option \"cascada\":\n$2",
        "namespaceprotected": "Tu non ha le permission de modificar paginas in le spatio de nomines '''$1'''.",
        "customcssprotected": "Tu non ha le permission de modificar iste pagina de CSS perque illo contine le configuration personal de un altere usator.",
+       "customjsonprotected": "Tu non ha le permission de modificar iste pagina JSON perque illo contine le configuration personal de un altere usator.",
        "customjsprotected": "Tu non ha le permission de modificar iste pagina de JavaScript perque illo contine le configuration personal de un altere usator.",
        "mycustomcssprotected": "Tu non ha le permission de modificar iste pagina de CSS.",
+       "mycustomjsonprotected": "Tu non ha le permission de modificar iste pagina JSON.",
        "mycustomjsprotected": "Tu non ha le permission de modificar iste pagina de JavaScript.",
        "myprivateinfoprotected": "Tu non ha le permission de modificar le proprie information private.",
        "mypreferencesprotected": "Tu non ha le permission de modificar le proprie preferentias.",
        "wrongpasswordempty": "Tu non entrava un contrasigno. Per favor reprova.",
        "passwordtooshort": "Le contrasignos debe continer al minus {{PLURAL:$1|1 character|$1 characteres}}.",
        "passwordtoolong": "Le contrasignos non pote esser plus longe de {{PLURAL:$1|1 character|$1 characteres}}.",
-       "passwordtoopopular": "Contrasignos habitual non pote esser usate. Per favor, elige un contrasigno plus unic.",
+       "passwordtoopopular": "Contrasignos habitual non pote esser usate. Per favor, elige un contrasigno plus difficile a divinar.",
        "password-name-match": "Tu contrasigno debe esser differente de tu nomine de usator.",
        "password-login-forbidden": "Le uso de iste nomine de usator e contrasigno ha essite prohibite.",
        "mailmypassword": "Reinitialisar contrasigno",
        "passwordremindertitle": "Nove contrasigno temporari pro {{SITENAME}}",
-       "passwordremindertext": "Alcuno (probabilemente tu, ab le adresse IP $1) requestava un nove\ncontrasigno pro {{SITENAME}} ($4).\nUn contrasigno temporari pro le usator \"$2\" ha essite create; iste\ncontrasigno es \"$3\". Si isto esseva le intention, tu debe ora\naperir un session e eliger un nove contrasigno. Le contrasigno temporari\nexpirara post {{PLURAL:$5|un die|$5 dies}}.\n\nSi un altere persona ha facite iste requesta, o si tu te ha rememorate\nle contrasigno e non plus vole cambiar lo, tu pote ignorar iste message\ne continuar a usar le contrasigno original.",
+       "passwordremindertext": "Alcuno (ab le adresse IP $1) requestava un nove\ncontrasigno pro {{SITENAME}} ($4).\nUn contrasigno temporari pro le usator \"$2\" ha essite create; iste\ncontrasigno es \"$3\". Si isto esseva le intention, tu debe ora\naperir un session e eliger un nove contrasigno. Le contrasigno temporari\nexpirara post {{PLURAL:$5|un die|$5 dies}}.\n\nSi un altere persona ha facite iste requesta, o si tu te ha rememorate\nle contrasigno e non plus vole cambiar lo, tu pote ignorar iste message\ne continuar a usar le contrasigno original.",
        "noemail": "Il non ha un adresse de e-mail registrate pro le usator \"$1\".",
        "noemailcreate": "Es necessari fornir un adresse de e-mail valide",
        "passwordsent": "Un nove contrasigno ha essite inviate al adresse de e-mail registrate pro \"$1\".\nPer favor aperi session de novo post reciper lo.",
        "botpasswords-existing": "Contrasignos de robot existente",
        "botpasswords-createnew": "Crear un nove contrasigno de robot",
        "botpasswords-editexisting": "Modificar un contrasigno de robot existente",
+       "botpasswords-label-needsreset": "(contrasigno debe esser reinitialisate)",
        "botpasswords-label-appid": "Nomine del robot:",
        "botpasswords-label-create": "Crear",
        "botpasswords-label-update": "Actualisar",
        "botpasswords-restriction-failed": "Session impedite per restrictiones de contrasigno de robot.",
        "botpasswords-invalid-name": "Iste nomine de usator non contine le separator pro contrasigno de robot (\"$1\").",
        "botpasswords-not-exist": "Le usator \"$1\" non ha un contrasigno de robot del nomine \"$2\".",
+       "botpasswords-needs-reset": "Le contrasigno pro le robot \"$2\" del {{GENDER:$1|usator}} \"$1\" debe esser reinitialisate.",
        "resetpass_forbidden": "Le contrasignos non pote esser cambiate",
        "resetpass_forbidden-reason": "Le contrasignos non pote esser cambiate: $1",
        "resetpass-no-info": "Tu debe aperir un session pro poter acceder directemente a iste pagina.",
        "savechanges": "Salveguardar modificationes",
        "publishpage": "Publicar pagina",
        "publishchanges": "Publicar modificationes",
+       "savearticle-start": "Salveguardar pagina…",
+       "savechanges-start": "Salveguardar modificationes…",
+       "publishpage-start": "Publicar pagina…",
+       "publishchanges-start": "Publicar modificationes…",
        "preview": "Previsualisation",
        "showpreview": "Monstrar previsualisation",
        "showdiff": "Detaliar modificationes",
        "subject-preview": "Previsualisation del subjecto:",
        "previewerrortext": "Un error ha occurrite durante le tentativa de previsualisar le cambiamentos.",
        "blockedtitle": "Le usator es blocate",
-       "blockedtext": "'''Tu nomine de usator o adresse IP ha essite blocate.'''\n\nLe blocada esseva facite per $1.\nLe motivo presentate es ''$2''.\n\n* Initio del blocada: $8\n* Expiration del blocada: $6\n* Le blocato intendite: $7\n\nTu pote contactar $1 o un altere [[{{MediaWiki:Grouppage-sysop}}|administrator]] pro discuter le blocada.\nTu non pote usar le function 'inviar e-mail a iste usator' salvo que un adresse de e-mail valide es specificate in le\n[[Special:Preferences|preferentias de tu conto]] e que tu non ha essite blocate de usar lo.\nTu adresse IP actual es $3, e le ID del blocada es #$5.\nPer favor include tote le detalios supra specificate in omne correspondentia.",
-       "autoblockedtext": "Tu adresse de IP ha essite automaticamente blocate proque un altere usator lo usava qui esseva blocate per $1.\nLe motivo presentate es:\n\n:''$2''\n\n* Initio del blocada: $8\n* Expiration del blocada: $6\n* Blocato intendite: $7\n\nTu pote contactar $1 o un del altere [[{{MediaWiki:Grouppage-sysop}}|administratores]] pro discuter le blocada.\n\nNota que tu non pote utilisar le function \"inviar e-mail a iste usator\" salvo que tu ha registrate un adresse de e-mail valide in tu [[Special:Preferences|preferentias de usator]] e que tu non ha essite blocate de usar lo.\n\nTu adresse IP actual es $3, e le ID del blocada es #$5.\nPer favor include tote le detalios supra specificate in omne correspondentia.",
+       "blockedtext": "<strong>Tu nomine de usator o adresse IP ha essite blocate.</strong>\n\nLe blocada esseva facite per $1.\nLe motivo presentate es <em>$2</em>.\n\n* Initio del blocada: $8\n* Expiration del blocada: $6\n* Le blocato intendite: $7\n\nTu pote contactar $1 o un altere [[{{MediaWiki:Grouppage-sysop}}|administrator]] pro discuter le blocada.\nTu pote solmente usar le function \"{{int:emailuser}}\" si un adresse de e-mail valide es specificate in le\n[[Special:Preferences|preferentias de tu conto]] e tu non ha essite blocate de usar lo.\nTu adresse IP actual es $3, e le ID del blocada es #$5.\nPer favor include tote le detalios supra specificate in omne correspondentia.",
+       "autoblockedtext": "Tu adresse IP ha essite automaticamente blocate perque un altere usator lo usava qui esseva blocate per $1.\nLe motivo presentate es:\n\n:<em>$2</em>\n\n* Initio del blocada: $8\n* Expiration del blocada: $6\n* Blocato intendite: $7\n\nTu pote contactar $1 o un del altere [[{{MediaWiki:Grouppage-sysop}}|administratores]] pro discuter le blocada.\n\nNota que tu pote solmente utilisar le function \"{{int:emailuser}}\" si tu ha registrate un adresse de e-mail valide in tu [[Special:Preferences|preferentias de usator]] e tu non ha essite blocate de usar lo.\n\nTu adresse IP actual es $3, e le ID del blocada es #$5.\nPer favor include tote le detalios supra specificate in omne correspondentia.",
        "systemblockedtext": "Tu nomine de usator o adresse IP ha essite blocate automaticamente per MediaWiki.\nLe motivo presentate es:\n\n:<em>$2</em>\n\n* Initio del blocada: $8\n* Expiration del blocada: $6\n* Blocato intendite: $7\n\nTu adresse IP actual es $3.\nPer favor, include tote le detalios enumerate hic supra in omne questiones que tu pone.",
        "blockednoreason": "nulle motivo specificate",
        "whitelistedittext": "Tu debe $1 pro poter modificar paginas.",
        "blocked-notice-logextract": "Iste usator es actualmente blocate.\nLe ultime entrata del registro de blocadas es reproducite ci infra pro information:",
        "clearyourcache": "<strong>Nota:</strong> Post confirmar, il pote esser necessari refrescar le <em>cache</em> de tu navigator pro vider le cambiamentos.\n* <strong>Firefox / Safari:</strong> Tenente <em>Shift</em> clicca <em>Reload (Recargar)</em>, o preme <em>Ctrl-F5</em> o <em>Ctrl-R</em> (<em>⌘-R</em> sur Mac)\n* <strong>Google Chrome:</strong> Preme <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> sur Mac)\n* <strong>Internet Explorer:</strong> Tenente <em>Ctrl</em> clicca <em>Refresh (Refrescar)</em>, o preme <em>Ctrl-F5</em> \n* <strong>Opera:</strong> Vade a <em>Menu → Configurationes</em> (<em>Opera → Preferentias</em> sur un Mac) e alora a <em>Privacy & securitate → Rader datos de navigation → Files e imagines in cache</em>.",
        "usercssyoucanpreview": "'''Consilio:''' Usa le button \"{{int:showpreview}}\" pro testar tu nove CSS ante de salveguardar lo.",
+       "userjsonyoucanpreview": "<strong>Consilio:</strong> Usa le button \"{{int:showpreview}}\" pro testar tu nove JSON ante de salveguardar lo.",
        "userjsyoucanpreview": "'''Consilio:''' Usa le button \"{{int:showpreview}}\" pro testar tu nove JavaScript ante de salveguardar lo.",
        "usercsspreview": "'''Non oblida que isto es solmente un previsualisation de tu CSS personalisate.'''\n'''Le modificationes non ha ancora essite salveguardate!'''",
+       "userjsonpreview": "<strong>Non oblida que isto es solmente un test/previsualisation de tu configuration JSON personal.\nIllo non ha ancora essite salveguardate!</strong>",
        "userjspreview": "'''Non oblida que isto es solmente un test/previsualisation de tu JavaScript personalisate.'''\n'''Illo non ha ancora essite salveguardate!'''",
        "sitecsspreview": "'''Non oblida que isto es solmente un previsualisation de iste CSS.'''\n'''Le modificationes non ha ancora essite salveguardate!'''",
+       "sitejsonpreview": "<strong>Non oblida que isto es solmente un previsualisation de iste configuration JSON.\nIllo non ha ancora essite salveguardate!</strong>",
        "sitejspreview": "'''Non oblida que isto es solmente un previsualisation de iste codice JavaScript.'''\n'''Le modificationes non ha ancora essite salveguardate!'''",
-       "userinvalidconfigtitle": "'''Attention:''' Le apparentia \"$1\" non existe.\nMemora que le paginas .css and .js personalisate usa un titulo in minusculas, p.ex. {{ns:user}}:Foo/vector.css e non {{ns:user}}:Foo/Vector.css.",
+       "userinvalidconfigtitle": "<strong>Attention:</strong> Le apparentia \"$1\" non existe.\nMemora que le paginas .css, .json e .js personalisate usa un titulo in minusculas, p.ex. {{ns:user}}:Foo/vector.css e non {{ns:user}}:Foo/Vector.css.",
        "updated": "(Actualisate)",
        "note": "'''Nota:'''",
        "previewnote": "'''Isto es solmente un previsualisation.'''\nLe modificationes non ha ancora essite publicate!",
        "longpageerror": "'''Error: Le texto que tu submitteva occupa {{PLURAL:$1|un kilobyte|$1 kilobytes}}, excedente le maximo de {{PLURAL:$2|un kilobyte|$2 kilobytes}}.'''\nIllo non pote esser salveguardate.",
        "readonlywarning": "<strong>Attention: Le base de datos ha essite blocate pro mantenentia. Tu non pote salveguardar tu modificationes in iste momento.</strong>\nNos recommenda copiar e collar le texto in un file e salveguardar lo pro plus tarde.\n\nLe administrator de systema 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:",
+       "semiprotectedpagewarning": "<strong>Nota:</strong> Iste pagina ha essite protegite de maniera que solmente usatores autoconfirmate pote modificar lo. Le ultime entrata del registro es fornite hic infra pro referentia:",
        "cascadeprotectedwarning": "<strong>Attention:</strong> Iste pagina ha essite protegite de maniera que solmente usatores con [[Special:ListGroupRights|certe privilegios]] pote modificar lo, perque illo es transcludite in le sequente {{PLURAL:$1|pagina|paginas}} protegite in cascada:",
        "titleprotectedwarning": "'''Attention:  Iste pagina ha essite protegite de maniera que [[Special:ListGroupRights|permissiones specific]] es requirite pro crear lo.''' Le ultime entrata del registro es fornite hic infra pro referentia:",
        "templatesused": "{{PLURAL:$1|Patrono|Patronos}} usate in iste pagina:",
        "postedit-confirmation-created": "Le pagina ha essite create.",
        "postedit-confirmation-restored": "Le pagina ha essite restaurate.",
        "postedit-confirmation-saved": "Tu modification ha essite salveguardate.",
+       "postedit-confirmation-published": "Tu modification ha essite publicate.",
        "edit-already-exists": "Non poteva crear un nove pagina.\nIllo existe ja.",
        "defaultmessagetext": "Texto predefinite del message",
        "content-failed-to-parse": "Impossibile processar le contento $2 pro le modello $1: $3",
        "expansion-depth-exceeded-category": "Paginas in que le profunditate de expansion excede le limite",
        "expansion-depth-exceeded-category-desc": "Le pagina excede le profunditate de expansion maxime.",
        "expansion-depth-exceeded-warning": "Le profunditate de expansion in iste pagina excede le limite",
-       "parser-unstrip-loop-warning": "Bucla de \"unstrip\" detegite",
-       "unstrip-depth-warning": "Limite de recursion de \"unstrip\" excedite ($1)",
+       "parser-unstrip-loop-warning": "Bucla detegite in le function \"unstrip\"",
+       "unstrip-depth-warning": "Limite de profunditate de \"unstrip\" excedite ($1)",
+       "unstrip-depth-category": "Paginas con recursion excessive de \"unstrip\"",
+       "unstrip-size-warning": "Limite de dimension de \"unstrip\" excedite ($1)",
+       "unstrip-size-category": "Paginas con dimension excessive de \"unstrip\"",
        "converter-manual-rule-error": "Error detegite in le regula manual de conversion de lingua",
        "undo-success": "Le modification pote esser disfacite.\nPer favor controla le comparation infra pro verificar que tu vole facer isto, e postea salveguarda le modificationes infra pro assi disfacer le modification.",
        "undo-failure": "Le modification non poteva esser annullate a causa de conflicto con modificationes intermedie.",
        "prefs-watchlist-edits": "Numero maxime de modificationes a monstrar in le observatorio:",
        "prefs-watchlist-edits-max": "Numero maxime: 1000",
        "prefs-watchlist-token": "Indicio pro le observatorio:",
-       "prefs-watchlist-managetokens": "Gerer indicios",
+       "prefs-watchlist-managetokens": "Gerer claves",
        "prefs-misc": "Misc",
        "prefs-resetpass": "Cambiar contrasigno",
        "prefs-changeemail": "Cambiar o remover adresse de e-mail",
        "stub-threshold-disabled": "Disactivate",
        "recentchangesdays": "Numero de dies a monstrar in modificationes recente:",
        "recentchangesdays-max": "(non plus de $1 {{PLURAL:$1|die|dies}})",
-       "recentchangescount": "Numero de modificationes a monstrar per predefinition:",
-       "prefs-help-recentchangescount": "Isto include modificationes recente, historias de paginas, e registros.",
+       "recentchangescount": "Numero predefinite de modificationes a monstrar in le lista de modificationes recente, in le historias de paginas e in le registros:",
+       "prefs-help-recentchangescount": "Numero maxime: 1000",
        "prefs-help-watchlist-token2": "Isto es le clave secrete pro le syndication web de tu observatorio.\nOmne persona qui lo cognosce pote leger tu observatorio, dunque, non divide lo.\nIn caso de necessitate, [[Special:ResetTokens|clicca hic pro reinitialisar lo]].",
        "prefs-help-tokenmanagement": "Tu pote vider e reinitialisar le clave secrete pro tu conto que pote acceder al aggregator Web de tu observatorio. Tote persona que cognosce le clave potera leger tu observatorio, dunque non divulga lo.",
        "savedprefs": "Tu preferentias ha essite confirmate.",
        "default": "predefinite",
        "prefs-files": "Files",
        "prefs-custom-css": "CSS personalisate",
+       "prefs-custom-json": "JSON personalisate",
        "prefs-custom-js": "JS personalisate",
-       "prefs-common-config": "CSS/JS commun a tote le apparentias:",
+       "prefs-common-config": "CSS/JSON/JavaScript commun a tote le apparentias:",
        "prefs-reset-intro": "Iste pagina es pro reinitialisar tu preferentias al valores predefinite del sito.\nLe operation non pote esser disfacite.",
        "prefs-emailconfirm-label": "Confirmation del e-mail:",
        "youremail": "E-mail:",
        "prefs-dateformat": "Formato de data",
        "prefs-timeoffset": "Differentia de tempore",
        "prefs-advancedediting": "Optiones general",
+       "prefs-developertools": "Instrumentos pro disveloppatores",
        "prefs-editor": "Editor",
        "prefs-preview": "Previsualisation",
        "prefs-advancedrc": "Optiones avantiate",
        "right-editcontentmodel": "Modificar le modello de contento de un pagina",
        "right-editinterface": "Modificar le interfacie de usator",
        "right-editusercss": "Modificar le files CSS de altere usatores",
+       "right-edituserjson": "Modificar le files JSON de altere usatores",
        "right-edituserjs": "Modificar le files JS de altere usatores",
        "right-editmyusercss": "Modificar le proprie files CSS de usator",
-       "right-editmyuserjs": "Modificar le proprie files JavaScript de usator",
+       "right-editmyuserjson": "Modificar le files JSON del proprie usator",
+       "right-editmyuserjs": "Modificar le files JavaScript del proprie usator",
        "right-viewmywatchlist": "Vider le proprie observatorio",
        "right-editmywatchlist": "Modificar le proprie observatorio. Remarca que alcun actiones totevia adde paginas mesmo sin iste derecto.",
        "right-viewmyprivateinfo": "Vider le proprie datos private (p.ex. adresse de e-mail, nomine real)",
        "grant-createaccount": "Crear contos",
        "grant-createeditmovepage": "Crear, modificar e renominar paginas",
        "grant-delete": "Deler paginas, versiones e entratas de registro",
-       "grant-editinterface": "Modificar le spatio de nomines MediaWiki e le CSS/JavaScript de usatores",
-       "grant-editmycssjs": "Modificar le CSS/JavaScript del proprie usator",
+       "grant-editinterface": "Modificar le spatio de nomines MediaWiki e le CSS/JSON/JavaScript de usatores",
+       "grant-editmycssjs": "Modificar le CSS/JSON/JavaScript del proprie usator",
        "grant-editmyoptions": "Modificar tu preferentias de usator",
        "grant-editmywatchlist": "Modificar tu observatorio",
        "grant-editpage": "Modificar paginas existente",
        "rcfilters-filter-humans-label": "Persona (non robot)",
        "rcfilters-filter-humans-description": "Modificationes facite per esseres human.",
        "rcfilters-filtergroup-reviewstatus": "Stato de revision",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Modificationes non marcate como patruliate, manual- o automaticamente.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Non patruliate",
+       "rcfilters-filter-reviewstatus-manual-description": "Modificationes manualmente marcate como patruliate.",
+       "rcfilters-filter-reviewstatus-manual-label": "Patruliate manualmente",
+       "rcfilters-filter-reviewstatus-auto-description": "Modificationes per usatores avantiate cuje travalio se marca automaticamente como patruliate.",
+       "rcfilters-filter-reviewstatus-auto-label": "Autopatruliate",
        "rcfilters-filtergroup-significance": "Importantia",
        "rcfilters-filter-minor-label": "Modificationes minor",
        "rcfilters-filter-minor-description": "Modificationes que le autor ha marcate como minor.",
        "recentchangeslinked-feed": "Modificationes ligate",
        "recentchangeslinked-toolbox": "Modificationes ligate",
        "recentchangeslinked-title": "Modificationes associate a \"$1\"",
-       "recentchangeslinked-summary": "Entra le nomine de un pagina pro vider le modificationes facite in paginas ligate ab o verso ille pagina. (Pro vider le membros de un categoria, entra Categoria:Nomine del categoria.)\nLe paginas presente in [[Special:Watchlist|tu observatorio]] appare in litteras <strong>grasse</strong>.",
+       "recentchangeslinked-summary": "Entra le nomine de un pagina pro vider le modificationes facite in paginas ligate ab o verso ille pagina. (Pro vider le membros de un categoria, entra {{ns:category}}:Nomine del categoria.)\nLe paginas presente in [[Special:Watchlist|tu observatorio]] appare in litteras <strong>grasse</strong>.",
        "recentchangeslinked-page": "Nomine del pagina:",
        "recentchangeslinked-to": "Monstrar modificationes in paginas con ligamines al pagina specificate",
        "recentchanges-page-added-to-category": "[[:$1]] addite al categoria",
        "deadendpages": "Paginas sin exito",
        "deadendpagestext": "Le sequente paginas non ha ligamines a altere paginas in {{SITENAME}}.",
        "protectedpages": "Paginas protegite",
+       "protectedpages-filters": "Filtros:",
        "protectedpages-indef": "Solmente protectiones infinite",
        "protectedpages-summary": "Iste pagina lista paginas existente que es actualmente protegite. Pro un lista de titulos protegite contra creation, vide [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Protectiones in cascada solmente",
        "protectedtitles-submit": "Monstrar titulos",
        "listusers": "Lista de usatores",
        "listusers-editsonly": "Monstrar solmente usatores con modificationes",
+       "listusers-temporarygroupsonly": "Monstrar solmente usatores in gruppos temporari",
        "listusers-creationsort": "Ordinar per data de creation",
        "listusers-desc": "Ordinar in senso descendente",
        "usereditcount": "$1 {{PLURAL:$1|modification|modificationes}}",
        "apisandbox-dynamic-parameters-add-label": "Adder parametro:",
        "apisandbox-dynamic-parameters-add-placeholder": "Nomine del parametro",
        "apisandbox-dynamic-error-exists": "Un parametro con le nomine \"$1\" jam existe.",
+       "apisandbox-templated-parameter-reason": "Iste [[Special:ApiHelp/main#main/templatedparams|parametro de patrono]] es offerite a base del {{PLURAL:$1|valor|valores}} of $2.",
        "apisandbox-deprecated-parameters": "Parametros obsolescente",
        "apisandbox-fetch-token": "Auto-reimpler le indicio",
+       "apisandbox-add-multi": "Adder",
        "apisandbox-submit-invalid-fields-title": "Alcun campos non es valide",
        "apisandbox-submit-invalid-fields-message": "Per favor, corrige le campos marcate e reproba.",
        "apisandbox-results": "Resultatos",
        "whatlinkshere": "Paginas ligate a iste",
        "whatlinkshere-title": "Paginas con ligamines verso $1",
        "whatlinkshere-page": "Pagina:",
-       "linkshere": "Le sequente paginas contine ligamines a '''[[:$1]]''':",
-       "nolinkshere": "Nulle pagina contine un ligamine verso '''[[:$1]]'''.",
-       "nolinkshere-ns": "Nulle pagina liga a '''[[:$1]]''' in le spatio de nomines seligite.",
+       "linkshere-2": "Le sequente paginas contine ligamines a <strong>$1</strong>:",
+       "nolinkshere-2": "Nulle pagina contine un ligamine verso <strong>$1</strong>.",
+       "nolinkshere-ns-2": "Nulle pagina liga a <strong>$1</strong>  in le spatio de nomines seligite.",
        "isredirect": "pagina de redirection",
        "istemplate": "transclusion",
        "isimage": "ligamine al file",
        "fix-double-redirects": "Actualisar tote le redirectiones que puncta verso le titulo original",
        "move-leave-redirect": "Lassar un redirection",
        "protectedpagemovewarning": "'''Attention:''' Iste pagina ha essite protegite de sorta que solmente usatores con privilegios de administrator pote renominar lo. Le ultime entrata del registro es fornite hic infra pro referentia:",
-       "semiprotectedpagemovewarning": "'''Nota:''' Iste pagina ha essite protegite de sorta que solmente usatores registrate pote renominar lo. Le ultime entrata del registro es fornite hic infra pro referentia:",
+       "semiprotectedpagemovewarning": "<strong>Nota:</strong> Iste pagina ha essite protegite de sorta que solmente usatores autoconfirmate pote renominar lo. Le ultime entrata del registro es fornite hic infra pro referentia:",
        "move-over-sharedrepo": "[[:$1]] jam existe in un repositorio commun. Si le file es renominate a iste titulo, illo supplantara le file commun.",
        "file-exists-sharedrepo": "Le nomine de file seligite es ja in uso in un repositorio partite.\nPer favor selige un altere nomine.",
        "export": "Exportar paginas",
        "thumbnail_dest_directory": "Impossibile crear directorio de destination",
        "thumbnail_image-type": "typo de imagine non supportate",
        "thumbnail_gd-library": "le configuration del bibliotheca GD es incomplete: manca le function $1",
+       "thumbnail_image-size-zero": "Le dimension del file de imagine pare esser zero.",
        "thumbnail_image-missing": "le file pare mancar: $1",
        "thumbnail_image-failure-limit": "Il ha habite recentemente troppo de tentativas fallite ($1 o plus) de generar iste miniatura. Per favor reproba plus tarde.",
        "import": "Importar paginas",
        "interlanguage-link-title": "$1 (in $2)",
        "common.css": "/* Le CSS placiate hic se applicara a tote le stilos */",
        "print.css": "/* Le CSS placiate hic influentiara le apparentia del paginas imprimite */",
+       "common.json": "/* Omne JSON hic essera cargate pro tote le usatores a cata cargamento de pagina. */",
        "common.js": "/* Omne JavaScript hic se executara pro tote le usatores a cata cargamento de pagina. */",
        "anonymous": "{{PLURAL:$1|Usator|Usatores}} anonyme de {{SITENAME}}",
        "siteuser": "Usator $1 de {{SITENAME}}",
        "watchlistedit-clear-titles": "Titulos:",
        "watchlistedit-clear-submit": "Rader le observatorio (isto es permanente!)",
        "watchlistedit-clear-done": "Tu observatorio ha essite radite.",
+       "watchlistedit-clear-jobqueue": "Tu observatorio es in curso de vacuation. Isto pote prender un certe tempore.",
        "watchlistedit-clear-removed": "{{PLURAL:$1|1 titulo|$1 titulos}} ha essite removite:",
        "watchlistedit-too-many": "Il ha troppo de paginas pro monstrar los hic.",
        "watchlisttools-clear": "Rader le observatorio",
        "version-specialpages": "Paginas special",
        "version-parserhooks": "Uncinos del analysator syntactic",
        "version-variables": "Variabiles",
+       "version-editors": "Editores",
        "version-antispam": "Prevention de spam",
        "version-other": "Altere",
        "version-mediahandlers": "Executores de media",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "limitreport-expansiondepth": "Maxime profunditate de expansion",
        "limitreport-expensivefunctioncount": "Numero de functiones analysator costose",
+       "limitreport-unstrip-depth": "Profunditate de recursion de \"unstrip\"",
+       "limitreport-unstrip-size": "Dimension de \"unstrip\" post expansion",
+       "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "expandtemplates": "Expander patronos",
        "expand_templates_intro": "Iste pagina special prende wikitexto e expande recursivemente tote le patronos in illo.\nIllo expande etiam le functiones del analysator syntactic como\n<code><nowiki>{{</nowiki>#language:…}}</code>, e variabiles como\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>.\nDe facto, illo expande quasi toto inter accolladas duple.",
        "expand_templates_title": "Titulo de contexto, pro {{FULLPAGENAME}} etc.:",
        "unlinkaccounts-success": "Le conto ha essite disligate.",
        "authenticationdatachange-ignored": "Le cambiamento del datos de authentication non ha succedite. Pote esser que nulle fornitor ha essite configurate?",
        "userjsispublic": "Nota ben: Subpaginas JavaScript non debe continer datos confidential perque altere usatores pote vider los.",
+       "userjsonispublic": "Nota ben: Subpaginas JSON non debe continer datos confidential perque altere usatores pote vider los.",
        "usercssispublic": "Nota ben: Subpaginas CSS non debe continer datos confidential perque altere usatores pote vider los.",
        "restrictionsfield-badip": "Adresse o intervallo IP non valide: $1",
        "restrictionsfield-label": "Intervallos IP permittite:",
        "pagedata-title": "Datos de pagina",
        "pagedata-text": "Iste pagina forni un interfacie de datos a paginas. Forni le titulo del pagina in le URL, usante le syntaxe de subpaginas.\n* Le negotiation de contento depende del capite \"Accept\" de tu cliente. Isto significa que le datos del pagina essera fornite in le formato que tu cliente prefere.",
        "pagedata-not-acceptable": "Nulle formato correspondente trovate. Typos MIME supportate: $1",
-       "pagedata-bad-title": "Titulo invalide: $1."
+       "pagedata-bad-title": "Titulo invalide: $1.",
+       "unregistered-user-config": "Pro motivos de securitate, subpaginas de usator con JavaScript, CSS e JSON non pote esser cargate pro usatores non registrate.",
+       "passwordpolicies": "Politicas de contrasigno",
+       "passwordpolicies-summary": "Isto es un lista de politicas de contrasigno in vigor pro le gruppos de usatores definite in iste wiki.",
+       "passwordpolicies-group": "Gruppo",
+       "passwordpolicies-policies": "Politicas",
+       "passwordpolicies-policy-minimalpasswordlength": "Le contrasigno debe continer al minus $1 {{PLURAL:$1|character|characteres}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Le contrasigno debe continer al minus $1 {{PLURAL:$1|character|characteres}} pro poter aperir session",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Le contrasigno non pote esser identic al nomine de usator",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Le contrasigno non pote corresponder a contrasignos in le lista nigre",
+       "passwordpolicies-policy-maximalpasswordlength": "Le contrasigno debe continer minus de $1 {{PLURAL:$1|character|characteres}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "Le contrasigno non pote esser {{PLURAL:$1|le contrasigno le plus popular|in le lista de $1 contrasignos popular}}"
 }
index e886852..631fc26 100644 (file)
        "whatlinkshere": "Pranala balik",
        "whatlinkshere-title": "Halaman yang memiliki pranala ke \"$1\"",
        "whatlinkshere-page": "Halaman:",
-       "linkshere": "Halaman-halaman berikut ini memiliki pranala ke '''[[:$1]]''':",
-       "nolinkshere": "Tidak ada halaman yang memiliki pranala ke '''[[:$1]]'''.",
-       "nolinkshere-ns": "Tidak ada halaman yang memiliki pranala ke '''[[:$1]]''' pada ruang nama yang dipilih.",
+       "linkshere-2": "Halaman-halaman berikut ini memiliki pranala ke '''$1''':",
+       "nolinkshere-2": "Tidak ada halaman yang memiliki pranala ke '''$1'''.",
+       "nolinkshere-ns-2": "Tidak ada halaman yang memiliki pranala ke '''$1''' pada ruang nama yang dipilih.",
        "isredirect": "halaman pengalihan",
        "istemplate": "tranklusi",
        "isimage": "pranala berkas",
index 470dac3..e802ab6 100644 (file)
        "whatlinkshere": "Referenties a ti-ci págine",
        "whatlinkshere-title": "Págines quo liga por \"$1\"",
        "whatlinkshere-page": "Págine:",
-       "linkshere": "Li sequent págines liga por '''[[:$1]]''':",
-       "nolinkshere": "Nequant págine liga por '''[[:$1]]'''.",
+       "linkshere-2": "Li sequent págines liga por '''$1''':",
+       "nolinkshere-2": "Nequant págine liga por '''$1'''.",
        "isredirect": "págine de redirecterion",
        "istemplate": "inclusion",
        "isimage": "referentie a un file",
index d652bd1..d2567cc 100644 (file)
        "november-date": "Ọnwaìrinàotù $1",
        "december-date": "Ọnwaìrinààbụọ",
        "pagecategories": "{{PLURAL:$1|Ụdàkọ}}",
-       "category_header": "Ihü nọr ime ébéonọr \"$1\"",
+       "category_header": "Ihu nà ime ụdàkọ \"$1\"",
        "subcategories": "Ụdàkọòkpurù",
        "category-media-header": "Nka nọr ime ébéonọr \"$1\"",
        "category-empty": "\"Ébéonọr nke enwéghị ihü ma nkà ímé ya.\"",
        "history": "Ịta ihüá",
        "history_short": "Ịta",
        "updatedmarker": "ihe gáráníru ké mgbe m byàrà nga mbu",
-       "printableversion": "Ùdì ǹke mbifụ̀",
+       "printableversion": "Ùdì ǹke mbipụ̀",
        "permalink": "Jikodo ekechịrị",
        "print": "Dotié",
        "view": "Lèzí",
        "logout": "Fwuör",
        "userlogout": "Fwuör",
        "notloggedin": "I bátà bò",
+       "userlogin-joinproject": "Bàkọ {{SITENAME}}",
        "createaccount": "Ké otụ buwa",
        "createaccountmail": "na e-mail",
+       "createacct-benefit-heading": "{{SITENAME}} sì nà aka ndị dị kà gị.",
        "createacct-benefit-body1": "{{PLURAL:$1|ḿmezi}}",
        "badretype": "Mkpurụ okwu ejị a gafẹ é jëghị.",
        "userexists": "Áhè ọ'bànifé tírí di na áká onye ozor.\nBíkó nwèré áhà nke ozor.",
        "revdelete-log": "Mgbághapụtà:",
        "revdel-restore": "gbanwe ọtù ọ gị zí",
        "pagehist": "Ịta ihüá",
-       "deletedhist": "Ákíkó mbu bakashịrị",
+       "deletedhist": "Ị̀ta kachara",
        "revdelete-reasonotherlist": "Mgbághàpụtá ozor",
        "revdelete-edit-reasonlist": "Rüwa mgbághapụtà nkàchafu",
        "revdelete-offender": "Ọde akwukwo nke orübà:",
        "rcshowhideanons": "$1 ndi ọ'bànifé nke amághị",
        "rcshowhideanons-show": "Zi",
        "rcshowhideanons-hide": "Zònarị",
-       "rcshowhidepatr": "$1 orü hä lèrè",
+       "rcshowhidepatr": "ọrụ h'e lèrè $1",
        "rcshowhidemine": "$1 ihe m rürü",
        "rcshowhidemine-show": "Zi",
        "rcshowhidemine-hide": "Zònarị",
        "filehist-datetime": "Èhì/Ogè",
        "filehist-thumb": "Mbọ-aka",
        "filehist-thumbtext": "NvóÁká màkà otù ȯ dị nà $1",
-       "filehist-nothumb": "Nvọáká adịghị",
+       "filehist-nothumb": "Mbọaka adhịghị̀",
        "filehist-user": "Òjìème",
        "filehist-dimensions": "Ógólógó na asaá",
        "filehist-filesize": "Ívù usòrò",
        "allinnamespace": "Ihü níle (ámááhạ $1)",
        "allpagessubmit": "Gá",
        "categories": "Ụdàkọ",
-       "sp-deletedcontributions-contribs": "ihe rürü di mkpa",
+       "sp-deletedcontributions-contribs": "mmètàrà",
        "linksearch": "Òtú jikodo di èzí",
        "linksearch-ns": "Ahàm̀bara:",
        "linksearch-ok": "Tùwe",
        "blanknamespace": "(Ḿkpà)",
        "contributions": "Ihe ọ'bànifé rürü",
        "contributions-title": "Orü ọ'bànifé nà $1",
-       "mycontris": "Ihem mẹtụrụ na orürü",
+       "mycontris": "Ịhem mètàrà",
+       "anoncontribs": "Mmètàrà",
        "contribsub2": "Maka $1 ($2)",
        "uctop": "(dị ùgbu â)",
        "month": "Shi önwa (na nke ndi mbu):",
        "whatlinkshere": "Ihe na bia nga",
        "whatlinkshere-title": "Ihü ná gá \"$1\" shí jikodo",
        "whatlinkshere-page": "Ihü:",
-       "linkshere": "Ihüá na gá '''[[:$1]]''':",
-       "nolinkshere": "Ọ díghị ihü na jikodo gá '''[[:$1]]'''.",
-       "nolinkshere-ns": "Ọ díghị ihü na jikodo gá '''[[:$1]]''' na áhàámá nke Í chọrọ.",
+       "linkshere-2": "Ihüá na gá '''$1''':",
+       "nolinkshere-2": "Ọ díghị ihü na jikodo gá '''$1'''.",
+       "nolinkshere-ns-2": "Ọ díghị ihü na jikodo gá '''$1''' na áhàámá nke Í chọrọ.",
        "isredirect": "ihü nke nkúfù",
        "istemplate": "ọ jè ákwúkwó usòrò",
        "isimage": "jikodo nnunuuche",
        "blocklink": "mèché",
        "unblocklink": "a kwadokwàlà",
        "change-blocklink": "gbanwe ngwùgwù",
-       "contribslink": "ọrụrụ",
+       "contribslink": "mètàrà",
        "blocklogpage": "Ndetù échìchè nke mbàchì",
        "blocklogentry": "kwụchi [[$1]] jí ógè ne $2 $3",
        "unblocklogentry": "àkwáchị gị $1",
        "tooltip-pt-mytalk": "Ihü akíkó gi",
        "tooltip-pt-preferences": "Ndoziri {{GENDER:|gị}}",
        "tooltip-pt-watchlist": "Ndetu ihü Í ne lé màkà ihe gị gbanwe",
-       "tooltip-pt-mycontris": "Ndetù ihe Í rürü",
+       "tooltip-pt-mycontris": "Ndetù màkà ihe {{GENDER:|ị}} mètàrà",
        "tooltip-pt-login": "Anyi si ka Í gbanyé; chetákwá na nsogbu adighi I gbanye ma Í chógị gbànyé",
        "tooltip-pt-logout": "Fwuör",
        "tooltip-ca-talk": "Akíkó maka ihe di na ihü nka",
        "tooltip-ca-nstab-image": "Zi ihü usòrò",
        "tooltip-ca-nstab-template": "Zi mkpurụ ihü",
        "tooltip-ca-nstab-help": "Zi ihü nkwádo",
-       "tooltip-ca-nstab-category": "Zi ihü ébéanọr",
+       "tooltip-ca-nstab-category": "Zi ihu ụdàkọ",
        "tooltip-minoredit": "Ká nke kà orü ntàkírí",
        "tooltip-save": "Domá ihe í gbanwere",
        "tooltip-preview": "Lètú ihe Í gbànwèrè, bíkó búzọr jí ihe á mgbe Í gi dọnyé!",
        "pageinfo-header-edits": "Mèzí ịta",
        "pageinfo-length": "Ogologo ihü (na baitusu)",
        "pageinfo-article-id": "ID Ihü",
+       "pageinfo-toolboxlink": "Nkàta ihu",
        "pageinfo-redirectsto-info": "ọ́márí",
        "pageinfo-contentpage-yes": "Eeh",
        "pageinfo-protect-cascading-yes": "Eeh",
        "confirm-unwatch-button": "Ngwanu",
        "imgmultipageprev": "ihü na àzú",
        "imgmultipagenext": "ihü nke di nso →",
-       "imgmultigo": "Gá!",
+       "imgmultigo": "Gàa!",
        "imgmultigoto": "Gá na ihü $1",
        "ascending_abbrev": "heé élu",
        "descending_abbrev": "ndạtạ",
        "special-characters-group-latin": "Latin",
        "special-characters-group-latinextended": "Latin dọsàrà",
        "special-characters-group-ipa": "IPA",
-       "special-characters-group-symbols": "Nkárí",
+       "special-characters-group-symbols": "Akàrà",
        "special-characters-group-greek": "Greek",
        "special-characters-group-cyrillic": "Cyrillic",
        "special-characters-group-arabic": "Arabiki",
index 10b5e9d..4775c24 100644 (file)
        "whatlinkshere": "Dagiti nakasilpo ditoy",
        "whatlinkshere-title": "Pampanid a nakasilpo iti \"$1\"",
        "whatlinkshere-page": "Panid:",
-       "linkshere": "Dagiti sumaganad a panid ket nakasilpo iti <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Awan ti pampanid a nakasilpo iti <strong>[[:$1]]</strong>.",
-       "nolinkshere-ns": "Awan ti pampanid a nakasilpo iti <strong>[[:$1]]</strong> iti napili a nagan ti espasio.",
+       "linkshere-2": "Dagiti sumaganad a panid ket nakasilpo iti <strong>$1</strong>:",
+       "nolinkshere-2": "Awan ti pampanid a nakasilpo iti <strong>$1</strong>.",
+       "nolinkshere-ns-2": "Awan ti pampanid a nakasilpo iti <strong>$1</strong> iti napili a nagan ti espasio.",
        "isredirect": "baw-ing a panid",
        "istemplate": "mailak-am",
        "isimage": "silpo ti papeles",
index 80cf726..71deca3 100644 (file)
        "tog-hidecategorization": "Къайлаяха оагӀоний оагӀаташ",
        "tog-extendwatchlist": "Хьашеръе зéма хьаязъяьр шедола хувцамаш юкъелоацаш, тIехьара даь хувцамаш хинна ца Iеш.",
        "tog-usenewrc": "Хувцамех тоабаш е керда нийсдарашка а зéма хьаязъяьра чу а",
-       "tog-numberheadings": "Ше-шегIа номераш увттае кепакертошта",
+       "tog-numberheadings": "Ши-шегIа номераш увттае кепакертошта",
        "tog-showtoolbar": "Кечала панель хьахьокха хувцам беча хана",
-       "tog-editondblclick": "Ð\9dиÑ\81Ñ\8aе Ð¾Ð°Ð³Ó\80онаÑ\88 Ñ\88озза IоÑ\82Ó\80аÑ\82оÓ\80аеча (JavaScript)",
-       "tog-editsectiononrightclick": "Ð\9dийÑ\81де Ð´Ã¡ÐºÑ\8aа Ñ\88озза Ð´Ð°Ñ\85ка Ð°Ñ\8cÑ\82Ñ\82еÑ\85Ñ\8cаÑ\80а Ñ\82оIаеÑ\80 Ñ\82Ó\80аÑ\82оÓ\80айиÑ\87а Ð´Ã¡ÐºÑ\8aа Ñ\86IеÑ\80а Ñ\82Iа (JavaScript)",
-       "tog-watchcreations": "Зем беш йола оагIонашта а файлашта а тIатоха аз хьаяь оагIонаши чуяьккха файлаши",
-       "tog-watchdefault": "Зем беш йола оагIонашта а файлашта а тIатоха аз хийца оагIонаши файлай йоазонца сурташ оттадари",
-       "tog-watchmoves": "Зем беш йола оагIонашта а файлашта а тIатоха аз цIи хийца оагIонаши файлаши",
+       "tog-editondblclick": "Тоае Ð¾Ð°Ð³Ó\80онаÑ\88 Ñ\88озза Ñ\82Ó\80аÑ\82оÓ\80айича (JavaScript)",
+       "tog-editsectiononrightclick": "Тоаде Ð¾Ð°Ð³Iон Ð´Ã¡ÐºÑ\8aа Ñ\86Ñ\83н ÐºÐµÐ¿Ð°ÐºÐµÑ\80Ñ\82á Ð´Ð°Ñ\85килга Ð°Ñ\8cÑ\82Ñ\82еÑ\85Ñ\8cаÑ\80а Ñ\82оIаеÑ\80г Ñ\82Ó\80аÑ\82оÓ\80айиÑ\87а (JavaScript)",
+       "tog-watchcreations": "Зем беш йолча оагIонашта а файлашта а тIатоха аз хьаяь оагIонаши чуяьха хинна файлаши",
+       "tog-watchdefault": "Зем беш йолча оагIонашта а файлашта а тIатоха аз хийца оагIонаши файлах лаьцараши",
+       "tog-watchmoves": "Зем беш йолча оагIонашта а файлашта а тIатоха аз цIи хийца оагIонаши файлаши",
        "tog-watchdeletion": "Зем беш йола оагIонашта а файлашта а тIатоха аз дIаяьккха оагIонаши файлаши",
        "tog-minordefault": "Массаза зIамига долаш санна белгалде хувцамаш.",
        "tog-previewontop": "Хьалххе бӀаргтохар хьагойта хувцама кора хьалхашкахь",
        "tog-previewonfirst": "Хувцам бе аьнна дехьаваьлча хьалххе бӀаргтохар хьахьокха",
-       "tog-enotifwatchlistpages": "ЭлекÑ\82Ñ\80онни Ð¿Ð¾Ñ\87Ñ\82е Ð³Iолла Ñ\85оам Ð±Ðµ Ñ\81ога Ð½Ð°Ð³Ð°Ñ\85Ñ\8c аз зем беш йола оагIонаши файлаши цхьанне хийцача",
+       "tog-enotifwatchlistpages": "ЭлекÑ\82Ñ\80онни Ð¿Ð¾Ñ\88Ñ\82е Ð³Iолла Ñ\85оамбе Ñ\81ога аз зем беш йола оагIонаши файлаши цхьанне хийцача",
        "tog-enotifusertalkpages": "Электронни почте гIолла хоам бе сога са дувца оттадара оагIув хийцача",
        "tog-enotifminoredits": "ОагIонаштеи файлаштеи даь хинна хувцамаш геттара зIамига дале а хоам бе сога",
        "tog-enotifrevealaddr": "ДӀабӀаргадайта са поштан цӀай нахá дӀатӀаухача цхьа хӀама хайташ долча хоамаш чу",
        "tog-shownumberswatching": "Ер оагIув шоаш зембеча оагIонашта юкъеяьккха болча доакьошхой таьрахь хьагойта",
-       "tog-oldsig": "Хьа карара кулг яздар:",
-       "tog-fancysig": "Ð\9aÑ\83лг Ñ\8fздаÑ\80а Ñ\88ий Ð¹Ð¾Ð»Ð° Ð²Ð¸ÐºÐ¸-Ñ\80азмеÑ\82ка (авÑ\82омаÑ\82иÑ\87еÑ\81ки Ñ\82IаÑ\85Ñ\8cожаÑ\8fÑ\80г Ð¹оацаш)",
+       "tog-oldsig": "Хьа карара кулг яздар иштта да:",
+       "tog-fancysig": "Ð\9aÑ\83лг Ñ\8fздаÑ\80а Ñ\85Ñ\8cа Ñ\85Ñ\8cай Ð²Ð¸ÐºÐ¸-Ñ\80азмеÑ\82ка (Ñ\88и-Ñ\88егIа Ð±Ð¾Ð»Ð° Ñ\82IаÑ\82овжам Ð±оацаш)",
        "tog-uselivepreview": "Хьахьокха хьалххе бӀаргтохар оагӀув юха хьа а ца елаш",
        "tog-forceeditsummary": "ДIахьалхадаккха, нагахьа санна хувцама йоазонца сурт оттадара моттиг хьалъйизанза яле",
        "tog-watchlisthideown": "Аз даь хувцамаш зéма хьаязъяьра чура къайладаха",
        "tog-watchlisthidebots": "Боташ даь хувцамаш зéма хьаязъяьра чура къайладаха",
        "tog-watchlisthideminor": "ЗIамига хувцамаш зéма хьаязъяьра чура къайладаха",
        "tog-watchlisthideliu": "Ражача чубаьннабоацача доакъошхоша даь хувцамаш къайладаха зема хьаязъяьра чура",
-       "tog-watchlisthideanons": "ЦIийоацача доакъошхоша хувцамаш къайладаха зем бара хьаязъяьр чура",
+       "tog-watchlistreloadautomatically": "Ши-шегIа кердаювлийта зема хьаязъяьр фильтр хувц мел луча хана (JavaScript эша)",
+       "tog-watchlistunwatchlinks": "ТIатоха укх тайпара ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) маркераш зем беш йола оагIонаш зема хьаязъяьрá чуяккха а цу чура араяккха а атта торо хургьйолаш (JavaScript эша)",
+       "tog-watchlisthideanons": "Дагара йоазув доацача доакъошхоша даь хувцамаш къайладаха зема хьаязъяьра чура",
        "tog-watchlisthidepatrolled": "Ха даь дола хувцамаш къайладаха зéма хьаязъяьра чу",
        "tog-watchlisthidecategorization": "ОагӀонашта оагIаташ тохар къайладаккха",
        "tog-ccmeonemails": "Сона хьатIаахийта аз доакъашхошта дIадахийта дола каьхатий кепаш",
-       "tog-diffonly": "Ма гойта оагIон чулоацам ши верси вIашидистара кIал",
+       "tog-diffonly": "Ма гойта оагIон чулоацам ши эрш вIаши юстача хана",
        "tog-showhiddencats": "Гойта къайла оагIаташ",
        "tog-useeditwarning": "Хоамбе хьадаь хувцамаш дӀа а ца яздеш аз болх дӀаберзабеча хана",
        "underline-always": "Даиман",
        "and": "&#32;а",
        "faq": "Каст-кастта телаш дола хаттараш",
        "actions": "Ардамаш",
-       "namespaces": "ЦIеÑ\80ий Ð°Ñ\80енаш",
+       "namespaces": "ЦIеÑ\80ий Ð¼Ð¾Ñ\82Ñ\82игаш",
        "variants": "Эршаш",
        "navigation-heading": "Навигацен меню",
        "errorpagetitle": "ГӀалат",
        "print": "Зарба тоха",
        "view": "Хьажар",
        "view-foreign": "Укх $1 сайта чу хьажа",
-       "edit": "Ð\9dийÑ\81де",
+       "edit": "Тоаде",
        "edit-local": "Хувца локальни йоазонца сурт оттадар",
        "create": "Хьакхолла",
        "create-local": "ТIатоха локальни йоазонца сурт оттадар",
        "newpage": "Керда оагӀув",
        "talkpagelinktext": "дувца оттадар",
        "specialpage": "ГIулакха оагӀув",
-       "personaltools": "Ð\94оакÑ\8aаÑ\88Ñ\85оÑ\87Ñ\83н Ð³Ó\80иÑ\80Ñ\81аш",
-       "talk": "Ð\94Ñ\83вÑ\86а Ð¾Ñ\82Ñ\82адар",
+       "personaltools": "Ð\94оакÑ\8aаÑ\88Ñ\85оÑ\87Ñ\83н ÐºÐµÑ\87алаш",
+       "talk": "ЮвÑ\86ар",
        "views": "Хьажараш",
-       "toolbox": "Ð\93Ó\80иÑ\80Ñ\81аш",
+       "toolbox": "Ð\9aеÑ\87алаш",
        "imagepage": "Файла оагIон бIаргтоха",
        "mediawikipage": "Хьахьокха хоам бара оагIув",
        "templatepage": "Лера оагIон бIаргтоха",
        "viewhelppage": "Новкъостал эцар",
-       "categorypage": "Ð\9aаÑ\82егоÑ\80ен Ð¾Ð°Ð³Iон бIаргтоха",
-       "viewtalkpage": "Дувца оттадара бIаргтоха",
+       "categorypage": "Ð\9eагÓ\80аÑ\82а Ð¾Ð°Ð³Iонга бIаргтоха",
+       "viewtalkpage": "Дувцара оагIонга бIаргтоха",
        "otherlanguages": "Кхыча меттаех",
        "redirectedfrom": "($1 яха оагIув дIа-хьа хьожаяьй укхаза)",
        "redirectpagesub": "ДIа-хьа хьожавара оагIув",
        "newmessageslinkplural": "{{PLURAL:$1|керда хоам}}",
        "newmessagesdifflinkplural": "{{PLURAL:$1|тӀехьара хувцам|999=тӀехьара хувцамаш}}",
        "youhavenewmessagesmulti": "Хьога кхаьчад керда хоамаш $1 чу",
-       "editsection": "нийсде",
+       "editsection": "тоае",
        "editold": "хувца",
        "viewsourceold": "Хьажа дIадолалу ко́дага",
        "editlink": "хувца",
        "nstab-special": "ГIулакха оагӀув",
        "nstab-project": "Проектах лаьца",
        "nstab-image": "Файл",
-       "nstab-mediawiki": "Хоамбар",
+       "nstab-mediawiki": "Хоам",
        "nstab-template": "Ло",
        "nstab-help": "Новкъостал",
        "nstab-category": "ОагӀат",
        "missingarticle-diff": "(башхало: $1, $2)",
        "internalerror": "Чура гӀалат",
        "internalerror_info": "Чура гӀалат: $1",
-       "cannotdelete-title": "Ð\9cегаÑ\88 Ñ\8fÑ\86 Ð´IаÑ\8fккÑ\85а Ð¾Ð°Ð³IÑ\83в \"$1\"",
+       "cannotdelete-title": "Ð\94IаÑ\8fккÑ\85а Ð¹Ð¸Ñ\88 Ñ\8fÑ\86 Â«$1» Ñ\8fÑ\85а Ð¾Ð°Ð³IÑ\83в",
        "badtitle": "Мегаш йоаца цӀи",
        "badtitletext": "Езаш йола оагӀон цӀи нийса яц, яьсса я, е харцахь йоалаяй меттий юкъера цIи е интервики цӀи. Иштта, цӀера юкъе оттаде мегаш доаца хьаракаш нийсаденна хила мегаш да.",
-       "viewsource": "Хьажар",
-       "viewsource-title": "Оагӏон $1 духхьара текстага хьажар",
-       "actionthrottled": "Сухалах доазув дар",
-       "protectedpagetext": "Ð\95Ñ\80 Ð¾Ð°Ð³IÑ\83в Ð»Ð¾Ñ\80аÑ\8fÑ\8c Ñ\8f Ñ\86Ñ\83 Ñ\82Iа Ñ\85Ñ\83вÑ\86амаÑ\88 Ðµ ÐºÑ\85Ñ\8b Ð´Ð¾Ð»Ð° Ð°Ñ\80дамаÑ\88 Ð´ÐµÑ\80гдоаÑ\86аÑ\88.",
-       "viewsourcetext": "Укх оагIон доладалара (чура) текста бIаргатоха а кеп яьккха а йиш я хьа.",
+       "viewsource": "Хьажа",
+       "viewsource-title": "$1 яхача оагӏон чухьнахьарча текстага хьажар",
+       "actionthrottled": "Сухала доазув дар",
+       "protectedpagetext": "Ер оагIув лораяь я цу тIа хувцамаш дергдоацаш.",
+       "viewsourcetext": "Укх оагIон чухьнахьарча текстах бIаргатоха а, цунах кеп яьккха а, йиш я хьа.",
        "virus-unknownscanner": "йовзанза антивирус:",
-       "welcomeuser": "Ð\9cаÑ\8cÑ\80Ñ\88а Ð²Ð¾Ð°Ð³Iалва, Ð´Ð¾Ð°ÐºÑ\8aаÑ\88Ñ\85о $1!",
+       "welcomeuser": "Марша воагIалва, доакъашхо $1!",
        "yourname": "Дагара йоазон цIи:",
        "userlogin-yourname": "Доакъашхочун цӀи",
        "userlogin-yourname-ph": "Iочуязъе хьай дагара йоазон цӀи",
        "createacct-yourpasswordagain": "Бакъйе пароль",
        "createacct-yourpasswordagain-ph": "Кхы цхьаькхаза Ӏочуязъе пароль",
        "userlogin-remembermypassword": "Ражача чувиса",
-       "yourdomainname": "Ð¥Ñ\8cа Ð½Ð°Ð½Ð°-Ñ\86Iа:",
+       "yourdomainname": "Ð¥Ñ\8cа Ð´Ð¾Ð¼ÐµÐ½:",
        "login": "Чувала/яла",
        "nav-login-createaccount": "Шоаш довзийтар / Дагара йоазув кхоллар",
        "logout": "Аравала/яла",
        "createacct-benefit-body3": "ТӀехьарча хана хинна {{PLURAL:$1|доакъашхо|доакъашхой}}",
        "badretype": "Оаша Iочуяьздаь къайладIоагIий цIераш цхьантара яц.",
        "loginerror": "Доакъашхо вовзара гIалат",
-       "mailmypassword": "КъайладIоагIа тIеракхоссар",
-       "mailerror": "Каьхат дIадохьиййташ гӀалат хилар: $1",
-       "emailconfirmlink": "Бакъде хьа электронни пошта адрес",
+       "mailmypassword": "Пароль тIеракхоссар",
+       "mailerror": "Каьхат дIадохьийтача хана гӀалат хилар: $1",
+       "emailauthenticated": "Хьа электронни пошта цIай бакъдаьд (тIатоадаьд) укх хана: $3, $2.",
+       "emailconfirmlink": "Бакъде хьай электронни пошта цIай",
        "loginlanguagelabel": "Мотт: $1",
        "pt-login": "Чувала/яла",
        "pt-login-button": "Чувала/яла",
        "botpasswords-label-create": "Хьакхолла",
        "botpasswords-label-update": "Кердадаккха",
        "botpasswords-label-cancel": "Эшац",
-       "botpasswords-label-delete": "ДIадаккха",
+       "botpasswords-label-delete": "ДIаяккха",
        "botpasswords-label-resetpassword": "Пароль тIеракхоссар",
        "resetpass-submit-loggedin": "КъайладIоагӀа дӀахувца",
        "resetpass-submit-cancel": "Эшац",
        "passwordreset-username": "Доакъашхочун цӀи:",
        "passwordreset-domain": "Домен:",
        "passwordreset-email": "Электронни почта адрес:",
+       "changeemail": "дIахувца е дIаяккха электронни пошт",
        "resettokens-tokens": "Токенаш:",
        "bold_sample": "Сома йоазон текст",
        "bold_tip": "Сома йоазон текст",
        "userpage-userdoesnotexist-view": "«$1» яха дагара йоазув долаш дац.",
        "clearyourcache": "<strong>Теркал де.</strong> Хетаргахьа, оагIув дIаязъяь яьлча шоай браузера кэш IоцIанъе езаргья шун, даь хувцамаш гургдолаш.\n* <strong>Firefox / Safari:</strong> <em>Shift</em> яха лак тоIояь лоаттаеш инструментий цхьа дакъа тIа тоIае <em>Обновить</em> е <em>Ctrl-F5</em> тоIае е <em>Ctrl-R</em> (<em>⌘-R</em> Mac тIа)\n* <strong>Google Chrome:</strong> ТоIае <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> Mac тIа)\n* <strong>Internet Explorer:</strong> <em>Ctrl</em> яха лак тоIояь лоаттаеш, тоIае <em>Обновить</em> е <em>Ctrl-F5</em> тоIае\n* <strong>Opera:</strong> ДехьагIо <em>Menu → Настройки</em> (<em>Opera → Настройки</em> Mac тIа), тIаккха <em>Безопасность → Очистить историю посещений → Кэшированные изображения и файлы</em>",
        "note": "'''Белгалдоахар:'''",
-       "previewnote": "'''Теркам бе, ер хьалххе бIаргтохар мара бац.'''\nХьа хувцамаш хIанза а дIаяздаь дац!",
-       "continue-editing": "Хувцар кхы дIахо де",
+       "previewnote": "'''Теркам бе! Ер хьалххе бIаргтохар мара бац.'''\nХьа хувцамаш хIанзехьа кхы а дIаяздаь дац!",
+       "continue-editing": "Хувцам бергболаш дIахо дехьавáла",
        "editing": "Хувцам: $1",
-       "creating": "«$1» оагIув хьакхоллар",
-       "editingsection": "Хувцам: $1 (оагӀон дáкъа)",
+       "creating": "«$1» яха оагIув хьакхоллар",
+       "editingsection": "Хувцар: $1 (оагӀон дáкъа)",
        "editingcomment": "Хувцам: $1 (оагӀон керда дáкъа)",
        "editconflict": "Хувцама вIашдухьалъоттам: $1",
        "yourtext": "Хьа текст",
        "previousrevision": "← XьалхайоагIа",
        "nextrevision": "ТIехьайоагIа →",
        "currentrevisionlink": "ХIанзара верси",
-       "cur": "хӀанза.",
+       "cur": "карара",
        "next": "тӀехь.",
-       "last": "хьалха.",
+       "last": "хьалхара",
        "page_first": "цхьоаллагIа",
        "page_last": "тӀехьара",
        "histlegend": "Эрший хоржам: хьабелгалъе шун вIаши йиста безам бола оагIон эршаш, тIаккха тоIае '''{{int:compare-submit}}'''.<br />\nКхетавар: '''({{int:cur}})''' — карарча эршаи хержача эршаи юкъе йола башхалонаш; '''({{int:last}})''' — хьалха йоагIача эршаи хержача эршаи юкъе йола башхалонаш; '''{{int:minoreditletter}}''' — зIамига хувцамаш.",
        "mergehistory-reason": "Бахьан:",
        "mergelog": "ВIашагIтеха хиннарий тептар",
        "revertmerge": "Дéкъа",
-       "history-title": "\"$1\" — хувцамай истори",
+       "history-title": "«$1» яхача оагIон хувцамаш",
        "difference-title": "$1 — эршашта юкъе йола башхало",
        "lineno": "МугI $1:",
        "compareselectedversions": "ВIаши йиста хержа версеш",
        "diff-multi-otherusers": "(Укх {{PLURAL:$2|цхьан доакъашхочун|$2 доакъашхой}} \n{{PLURAL:$1|юккъера верси гайтаяц|юккъера версеш гайтаяц}})",
        "searchresults": "Лахар чакхдоалаш корадаьр",
        "searchresults-title": "«$1» лахар",
-       "notextmatches": "Ð\9eагIонай Ñ\82екÑ\81Ñ\82аÑ\88Ñ\82а Ñ\8eкÑ\8aе цхьатара хилар дац",
-       "prevn": "{{PLURAL:$1|1=Ñ\85Ñ\8cалÑ\85айогIаÑ\80\85Ñ\8cалÑ\85айогIаÑ\80аÑ\88}} $1",
-       "nextn": "{{PLURAL:$1|1=Ñ\82IеÑ\85Ñ\8cайоагIаÑ\80\82IеÑ\85Ñ\8cайоагIаÑ\80аÑ\88}} $1",
+       "notextmatches": "Ð\9eагIоний Ñ\82екÑ\81Ñ\82аÑ\88Ñ\82а Ñ\87Ñ\83 цхьатара хилар дац",
+       "prevn": "{{PLURAL:$1|1=Ñ\85Ñ\8cалÑ\85айогIаÑ\87а|Ñ\85Ñ\8cалÑ\85айогIаÑ\87а}} $1-ннега",
+       "nextn": "{{PLURAL:$1|1=Ñ\82IеÑ\85Ñ\8cайоагIаÑ\87а|Ñ\82IеÑ\85Ñ\8cайоагIаÑ\87а}} $1-ннега",
        "prevn-title": "{{PLURAL:$1|ХьалхадоагIа $1 дIаяздар}}",
        "nextn-title": "{{PLURAL:$1|ТIадоагIа $1 яздар|ТIадоагIа $1 яздараш}}",
        "shown-title": "Гойта $1 {{PLURAL:$1|яздаьр|яздаьраш}} укх оáгIон тIа",
        "powersearch-toggleall": "Деррига",
        "powersearch-togglenone": "Цхьаккха",
        "powersearch-remember": "Дагалáца хержар кхы тӀехьагӀа лохача хана накъадаргдолаш",
-       "preferences": "Ð\93IиÑ\80Ñ\81 Ñ\82оаÑ\8fÑ\80аш",
+       "preferences": "Ð\9eÑ\82Ñ\82амаш",
        "mypreferences": "Оттамаш",
+       "prefs-edits": "Тоадарий дукхал:",
        "prefs-skin": "ТIера кийчдара тема",
        "skin-preview": "Хьалххе бIаргтохар",
-       "prefs-personal": "Доакъашхочун дараш",
-       "prefs-rc": "Керда нийсдараш",
-       "prefs-watchlist": "Зéма хьаязъяьр",
+       "prefs-user-pages": "Доакъашхочун оагIонаш",
+       "prefs-personal": "Доакъашхочун хьакъехьа",
+       "prefs-rc": "Дукха ха йоаццаш тоадаьр",
+       "prefs-watchlist": "Зем",
+       "prefs-editwatchlist": "Зема хьаязъяьр хувцар",
+       "prefs-editwatchlist-label": "Шун зема хьаязъяьра чура яздараш хувцар",
+       "prefs-editwatchlist-edit": "Хьа зема хьаязъяьра чура цIерашка хьажар а уж дIаяхар",
+       "prefs-editwatchlist-raw": "Текст санна зема хьаязъяьр хувцар",
+       "prefs-editwatchlist-clear": "IоцIенъе зема хьаязъяьр",
        "prefs-watchlist-days": "Дéной дукхал:",
-       "prefs-resetpass": "Хувца къайладIоагIа",
+       "prefs-watchlist-edits": "Эггара дукхагIа тоадаьрий массал, зема хьаязъяьра чу хьахьокха йиш йола",
+       "prefs-watchlist-edits-max": "Эггара дукхагIа: 1000",
+       "prefs-watchlist-token": "Зема хьаязъяьра токен:",
+       "prefs-resetpass": "ДIахувца пароль",
+       "prefs-changeemail": "дIахувца е дIаяккха электронни пошт",
+       "prefs-email": "Электронни поштан оттамаш",
        "prefs-rendering": "ТIера куц",
        "saveprefs": "ДIаязде",
-       "prefs-editing": "Хувцам",
+       "restoreprefs": "Юхадоаладе юххьанцара хинна оттамаш",
+       "prefs-editing": "Тоадар",
        "searchresultshead": "Лахаp",
+       "stub-threshold": "Кечамий тIатовжамаш хьакийчдар оттадарá доазув ($1):",
+       "stub-threshold-sample-link": "масала",
+       "recentchangesdays": "Масса дийнахь даь керда хувцамаш хьахьокха деза:",
+       "recentchangescount": "Тайп-тайпара хьаязъяьрашка хьагуш дола тоадаьрий дукхал",
+       "prefs-help-recentchangescount": "Эггара дукхагIа: 1000",
+       "prefs-help-watchlist-token2": "Ер хьа зема хьаязъяьра веб-канала къайла дIоагIа да.\nИз дIайханачунна аьттув хургба хьа зема хьаязъяьр еша, цу бахьан дIа ма хайта из кхычарга.\nЭшаш дале нагахь санна, [[Special:ResetTokens|хьа йиш из тIеракхосса]].",
        "timezonelegend": "Сахьата оаса:",
-       "localtime": "Моттига ха:",
+       "localtime": "Меттигара ха:",
+       "timezoneuseserverdefault": "Сервера ($1) оттамаш леладе",
+       "timezoneuseoffset": "Кхыдар (белгалде ха меттахьялар)",
+       "servertime": "Сервера ха:",
+       "guesstimezone": "Браузера чура оттамаш леладе",
        "timezoneregion-africa": "Африка",
        "timezoneregion-america": "Америка",
        "timezoneregion-antarctica": "Антарктика",
        "timezoneregion-arctic": "Арктика",
        "timezoneregion-asia": "Ази",
-       "timezoneregion-atlantic": "Ð\9cалÑ\85бÑ\83зеÑ\80а Ð¾ÐºÐµÐ°Ð½",
+       "timezoneregion-atlantic": "Ð\9cалÑ\85бÑ\83зеÑ\80а Ð¾Ð°ÐºÐ°Ñ\84оÑ\80д",
        "timezoneregion-australia": "Астрали",
        "timezoneregion-europe": "Европа",
-       "timezoneregion-indian": "ХIиндий океан",
-       "timezoneregion-pacific": "Тийна океан",
+       "timezoneregion-indian": "ХIиндий оакафорд",
+       "timezoneregion-pacific": "Тийна оакафорд",
+       "allowemail": "Могадайта кхыча доакъашхошка сайна каьхат ахийта электронни поште гIолла",
+       "email-allow-new-users-label": "Могадайта дукха ха яьланза кердача доакъашхошка сайна каьхат ахийта электронни поште гIолла",
+       "email-blacklist-label": "ХьатIа ма ахийта сона каьхаташ электронни поште гIолла укх доакъашхошкара:",
        "prefs-searchoptions": "Лахар",
-       "prefs-namespaces": "ЦIерий аренаш",
+       "prefs-namespaces": "ЦIерий моттигаш",
+       "default": "юххьанцара хиннача тайпара",
        "prefs-files": "Файлаш",
-       "youremail": "Электронни почта:",
+       "prefs-custom-css": "Доалахь йола CSS",
+       "prefs-custom-js": "Доалахь йола JS",
+       "prefs-common-config": "Юкъара йола CSS/JSON/JavaScript массайолча кийчдара темашта:",
+       "prefs-emailconfirm-label": "Электронни пошт тIатоаяр:",
+       "youremail": "Электронни пошт:",
        "username": "{{GENDER:$1|Доакъашхочун цӀи}}:",
+       "prefs-memberingroups": "{{GENDER:$2|Дáкъа лоацаш ва|Дáкъа лоацаш я}} {{PLURAL:$1|1=укх тоаба чу|укх тоабашка}}:",
+       "prefs-registration": "Дагара йоазув кхелла ха:",
        "yourrealname": "Бокъонца йола цIи:",
        "yourlanguage": "Мотт:",
+       "yournick": "Керда кулг яздар:",
+       "prefs-help-signature": "Дувцара оагIонаш чу шоай къамаьла тIехьа кулг язде деза ер «<nowiki>~~~~</nowiki>» диъ хьарак оттадаь, цунах тIаккха хьахул шун кулг яздари хаи (сахьати миноташи).",
+       "yourgender": "Мишта аьлча бакъахьа да хьох?",
+       "gender-unknown": "МаIа е кхал хилар белгалцадахар",
        "gender-male": "ВикиоагIонаш тоаеш ва из",
        "gender-female": "ВикиоагIонаш тоаеш я из",
+       "prefs-help-gender": "Укхаза оттадаьр ражо леладергда шуга йистхулача хана шо маIа да е кхал да хьежжа.\nМассанена ховш а бIаргагуш а хургда уж оттамаш.",
        "email": "Email",
        "prefs-help-email": "Электронни почта адрес оттаде параз дац, амма из эшаш хургда, нагахьа санна хьона хьа къайладIоагIа дицлой.",
        "prefs-help-email-others": "Иштта цунца кхыболча доакъашхошта аьттув хургба шоаца бувзам бе а, шун оагIон тIа е шун дувца оттадара оагIон тIа йола тIахьожаяргаца.\nШун электронни почта адрес цхьаннена гуш хургъяц.",
+       "prefs-info": "Кертера дараш",
+       "prefs-i18n": "Меттаца дувзаденнар",
        "prefs-signature": "Кулг яздар",
+       "prefs-dateformat": "Таьрахьа формат",
+       "prefs-timeoffset": "Хáна оттамаш",
+       "prefs-advancedediting": "Юкъара параметраш",
+       "prefs-developertools": "Кийчдархочун кечалаш",
        "prefs-preview": "Хьалххе бIаргтохар",
+       "prefs-advancedrc": "Кхыдола шердаь оттамаш",
+       "prefs-opt-out": "Алсамдалар тIацаэцар",
+       "prefs-advancedrendering": "Кхыдола шердаь оттамаш",
+       "prefs-advancedsearchoptions": "Шердаь оттамаш",
+       "prefs-advancedwatchlist": "Кхыдола шердаь оттамаш",
+       "prefs-diffs": "Эрший башхало",
        "userrights-user-editname": "Iочуязъе доакъашхочун цӀи:",
        "editusergroup": "Йотта доакъашхой тоабаш",
        "saveusergroups": "ДIаязъе {{GENDER:$1|доакъашхочун}} тоабаш",
        "userrights-unchangeable-col": "Хьа хувца йиш йоаца тоабаш",
        "group": "Тоаба:",
        "group-user": "Доакъашхой",
+       "group-autoconfirmed": "АвтохьатӀаийца доакъашхой",
        "group-bot": "Бóташ",
        "group-sysop": "Администратораш",
+       "group-bureaucrat": "Бюрократаш",
        "group-all": "(деррига)",
        "group-user-member": "{{GENDER:$1|доакъашхо}}",
+       "group-autoconfirmed-member": "{{GENDER:$1|автохьатӀаийца доакъашхо}}",
        "group-bot-member": "{{GENDER:$1|бот}}",
        "group-sysop-member": "{{GENDER:$1|администратор}}",
        "grouppage-user": "{{ns:project}}:Доакъашхой",
+       "grouppage-autoconfirmed": "{{ns:project}}:АвтохьатӀаийца доакъашхой",
        "grouppage-bot": "{{ns:project}}:Боташ",
        "grouppage-sysop": "{{ns:project}}:Администратораш",
+       "grouppage-bureaucrat": "{{ns:project}}:Бюрократаш",
        "right-read": "оагӀонашка хьажар",
        "right-edit": "оагӀонаш нийсъяр",
        "right-createtalk": "дувца оттадара оагӀонаш кхоллар",
        "recentchanges-label-plusminus": "байташкахь боарам хувцар",
        "recentchanges-legend-heading": "<strong>Легенда:&nbsp;</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (хьажа иштта [[Special:NewPages|керда оагIонашка]])",
+       "rcfilters-activefilters": "Хьалотаяь фильтраш",
+       "rcfilters-advancedfilters": "Шеръяь фильтраш",
+       "rcfilters-quickfilters": "Ӏалашъяь фильтраш",
+       "rcfilters-quickfilters-placeholder-title": "Ӏалашъяь фильтраш хIанзехьа яц",
+       "rcfilters-quickfilters-placeholder-description": "Фильтра оттамаш дIаяздергдолаши тIехьагIа царех юха а пайда эцаргболаши, лохегIа «Активни фильтр» яздаьча моттиге юкъеехкарг белгалъеча хьарака IотIатоIае.",
+       "rcfilters-savedqueries-defaultlabel": "Ӏалашъяь фильтраш",
+       "rcfilters-savedqueries-rename": "ЦIи хувца",
+       "rcfilters-savedqueries-setdefault": "Ше хиннача тайпара дIаоттаде",
+       "rcfilters-savedqueries-unsetdefault": "Ше хиннача тайпах яр дIаяккха",
+       "rcfilters-savedqueries-remove": "ДIаяккха",
+       "rcfilters-savedqueries-new-name-label": "ЦIи",
+       "rcfilters-filter-bots-label": "Бот",
+       "rcfilters-filter-bots-description": "Авто-кечалашца даь тоадар.",
+       "rcfilters-filter-humans-label": "Саг ва (бот яц)",
+       "rcfilters-filter-pageedits-label": "ОагӀона тоадаьраш",
+       "rcfilters-filter-newpages-label": "JагӀонаш кхоллар",
+       "rcfilters-filter-newpages-description": "Керда оагӀонаш кхолла аьнна даь тоадар.",
+       "rcfilters-liveupdates-button": "Ше-шегIа кердадахийта",
+       "rcfilters-liveupdates-button-title-on": "ДIадоаде ше-шегIа кердадахар",
+       "rcfilters-liveupdates-button-title-off": "Керда хувцам бешше хьахьокха",
+       "rcfilters-preference-label": "Къайлаяккха «Керда хувцамий» толашагIа йола эрш",
+       "rcfilters-preference-help": "Юхатотта 2017 шера хинна интерфейса редизайн а цу хана тӀатеха кечалаш а.",
        "rcnotefrom": "КIалхагIа {{PLURAL:$5|хувцам белгалбаьккхаб}} <strong>$3, $4</strong> тIера (хьахьекхабац <strong>$1</strong>-л дукхагIа).",
        "rclistfrom": "$3 $2 денза даь хувцамаш хьахьокха",
-       "rcshowhideminor": "$1 Ð·Iамига Ð½Ð¸Ð¹Ñ\81даÑ\80аÑ\88",
+       "rcshowhideminor": "$1 Ð·Iамига Ð´Ð¾Ð»Ð° Ñ\82оадаÑ\80",
        "rcshowhideminor-show": "Хьахьокха",
        "rcshowhideminor-hide": "Къайладаккха",
        "rcshowhidebots": "$1 боташ",
        "rcshowhideliu": "$1 ражача дӏаэтта доакъашхой",
        "rcshowhideliu-show": "Хьахьокха",
        "rcshowhideliu-hide": "Къайлабаха",
-       "rcshowhideanons": "$1 цIияккханза доакъашхой",
+       "rcshowhideanons": "$1 Ñ\88оай Ñ\86IиÑ\8fккÑ\85анза Ð´Ð¾Ð°ÐºÑ\8aаÑ\88Ñ\85ой",
        "rcshowhideanons-show": "Хьахьокха",
        "rcshowhideanons-hide": "Къайлабаха",
        "rcshowhidepatr": "$1 техка хувцамаш",
        "rcshowhidepatr-show": "Хьахьокха",
        "rcshowhidepatr-hide": "Къайладаккха",
-       "rcshowhidemine": "$1 хьа нийсдараш",
+       "rcshowhidemine": "$1 Iайха тоадаьраш",
        "rcshowhidemine-show": "Хьахьокха",
        "rcshowhidemine-hide": "Къайладаккха",
        "rclinks": "Хьахьокха $2 дийнахь даь хинна тIеххьара $1 хувцамаш",
        "recentchangeslinked": "ВIашагIдувзаденна нийсдараш",
        "recentchangeslinked-feed": "ВIашагIдувзаденна нийсдараш",
        "recentchangeslinked-toolbox": "ВIашагIдувзаденна хувцамаш",
-       "recentchangeslinked-title": "$1ца вIашидувзаденна хувцамаш",
+       "recentchangeslinked-title": "$1ца вIаши дувзаденна хувцамаш",
        "recentchangeslinked-summary": "Ӏочуязъе оагӀон цӀи, цунна тӀатовжаш йолча оагӀонаш чу даь дола хувцамаш бӀаргагургдолаш (ОагӀата доакъашхой бӀаргагургболаш Ӏочуязъе {{ns:category}}:ОагӀата цӀи).\n[[Special:Watchlist|Хьа зéма хьаязъяьрá]] юкъейоагӀача оагӀонаш чу даь хувцамаш <strong>сомача лапӀазаца</strong> белгалдаь да.",
        "recentchangeslinked-page": "ОагIон цIи",
        "recentchangeslinked-to": "Вешта, белгаляьккха оагIон тIахьожавеш дола оагIонашта даь хувцамаш хьахьокха.",
        "fileuploadsummary": "Лоаца сурт оттадар:",
        "license": "Лицензи ялар:",
        "license-header": "Лицензировани",
+       "listfiles-delete": "дӀаяккха",
        "imgfile": "файл",
        "listfiles": "Файлий хьаязъяьр",
        "listfiles_date": "Ди",
        "file-anchor-link": "Файл",
        "filehist": "Файла истори",
        "filehist-help": "Ди/ха долча IотIатоIае цу хана файл мишта хиннай хьажа йиш хуpгьйолаш",
+       "filehist-deleteone": "дӀаяккха",
        "filehist-revert": "юхаяьккха",
        "filehist-current": "xIанзара",
        "filehist-datetime": "Ди/Ха",
        "statistics": "ГӀулакх-хьал",
        "statistics-articles": "Статьяш",
        "statistics-pages": "ОагIонаш",
+       "statistics-users-active": "Хьинаре доакъашхой",
        "double-redirect-fixer": "ДӀа-хьа хьожавара оагIонаш тоаер",
        "brokenredirects-edit": "нийсъе",
        "brokenredirects-delete": "дӀаяккха",
        "withoutinterwiki-submit": "Хьахьокха",
        "nbytes": "$1 {{PLURAL:$1|байт}}",
        "nmembers": "$1 {{PLURAL:$1|объект}}",
-       "prefixindex": "Ð\9eагÓ\80оний Ñ\86Ó\80еÑ\80ий Ð´ÐµÑ\88Ñ\85Ñ\8cалÑ\85ех хьахокхар",
+       "prefixindex": "Ð\9eагÓ\80онаÑ\88 Ñ\88оай Ñ\86Ó\80еÑ\80ий Ñ\85Ñ\8cалÑ\85аÑ\80Ñ\87а Ð°Ð»Ð°Ð¿Ð°х хьахокхар",
        "prefixindex-namespace": "ОагӀоний цӀераш шоай дешхьалхех хьахьокхар (цIерий моттиг «{{ns:$1}}»)",
+       "prefixindex-submit": "Хьахьокха",
+       "prefixindex-strip": "ДIакъайлаяха хьелехача оагIоний дешхьалхенаш (префиксаш)",
        "shortpages": "Лоаца оагIонаш",
        "longpages": "ЙIаьха оагIонаш",
        "protectedpages-page": "ОагIув",
        "allpagesto": "Хьахьокхар соцадé укхун тӀа:",
        "allarticles": "Еррига оагIонаш",
        "allpagessubmit": "Кхоачашде",
+       "allpagesprefix": "Хьалаха оагӀонаш, дӀайолалуш йола укх алапах:",
        "allpages-hide-redirects": "ДIакъайладаха дӀа-хьа хьожавераш",
        "categories": "ОагӀаташ",
+       "categories-submit": "Хьахьокха",
        "linksearch": "Арахьара тIахьожаяргаш лахар",
-       "linksearch-ns": "ЦIеÑ\80ий Ð°Ñ\80енаш:",
+       "linksearch-ns": "ЦIеÑ\80ий Ð¼Ð¾Ñ\82Ñ\82игаш:",
        "linksearch-ok": "Хьалаха",
        "linksearch-line": "$1 яхача оагIонна тIатовжам $2 чура",
+       "activeusers": "Хьинаре доакъашхой",
+       "activeusers-submit": "Хьахьокха хьинаре бола доакъашхой",
+       "listgrouprights": "Доакъашхой тоабай бокъонаш",
        "listgrouprights-members": "(доакъашхой хьаязъяьр)",
-       "listgrouprights-namespaceprotection-namespace": "ЦIеÑ\80ий Ð°Ñ\80е",
+       "listgrouprights-namespaceprotection-namespace": "ЦIеÑ\80ий Ð¼Ð¾Ñ\82Ñ\82иг",
        "emailuser": "Доакъашхочоа каьхат",
        "usermessage-editor": "Системан дIакхоачадар",
-       "watchlist": "Зем бара хьаязъяьр",
-       "mywatchlist": "Зем бара хьаязъяьр",
+       "watchlist": "Зем",
+       "mywatchlist": "Зем",
        "watchlistfor2": "Цунна $1 $2",
        "addedwatchtext": "Статья «[[:$1]]» а, цун дувца оттадара оагIув а тIатехай хьа [[Special:Watchlist|зем бара хьаязъяьра]].",
        "removedwatchtext": "Статья «[[:$1]]» а, иштта цун дувца оттадара оагIув а дIаяьккхай хьа [[Special:Watchlist|зем бара хьаязъяьр]] чура.",
        "watching": "Зем бара хьаязъяьр чу тIатохар",
        "unwatching": "Зем бара хьаязъяьр чура дIадаккхар",
        "enotif_reset": "Белгалъе еррига оагӀонаш бӀаргтехача санна",
+       "enotif_impersonal_salutation": "{{grammar:genitive|{{SITENAME}}}} – доакъашхо",
        "deletepage": "ДIаяккха оагIув",
+       "delete-confirm": "$1 — дӀаяккхар",
+       "delete-legend": "ДӀаяккхар",
        "confirmdeletetext": "Оаш дIадийхад бIарчча дIадаккхар оагIон а (е сурта), цун деррига хувцара истори а. '''Дехар да''', бакъде шоай из бокъонца де безам болаш долга а, из дича хургдар кхеташ долга а, из дар укх [[{{MediaWiki:Policy-url}}|бокъонашца]] долга.",
        "actioncomplete": "Ардам кхоачашдаьд",
-       "actionfailed": "Ð\90Ñ\80дам Ðºхоачашдаьдац",
+       "actionfailed": "Ð\9aхоачашдаьдац",
        "deletedtext": "«$1» дIаяьккхай.\nХьажа $2 тIехьара дIадаккхарий хьаязъяьрга бIаргтохаргболаш.",
        "dellogpage": "ДӀадаккхарий тептар",
        "deletecomment": "Бахьан:",
        "protect-cantedit": "Хьа хувца йиш яц укх оагIон лорадара лагIа, цун хувцам бе хьа бокъо ца хиларах.",
        "restriction-type": "Бокъонаш:",
        "restriction-level": "ТIакхоачилга лагIа:",
-       "restriction-edit": "Хувцам",
+       "restriction-edit": "Хувцар",
        "restriction-move": "ЦIи хувцаp",
        "restriction-create": "Хьакхоллар",
        "restriction-upload": "Доттар",
        "undeletelink": "бIаргтоха/юхадаккха",
        "undeleteviewlink": "хьажа",
        "undelete-search-submit": "Хьалáха",
-       "namespace": "ЦIеÑ\80ий Ð°Ñ\80енаш:",
+       "namespace": "ЦIеÑ\80ий Ð¼Ð¾Ñ\82Ñ\82игаш:",
        "invert": "Хержар юхадаккха",
        "tooltip-invert": "Оттае ер белгало, хержа цIерий аре чу а (белгалъяь яле вIашагIъювзаенна цIерий аре чу а), оагIонаш тIа а даь хувцамаш къайладоахаргдолаш",
        "namespace_association": "Ювзаенна аре",
        "whatlinkshere": "Тӏатовжамаш укхаза",
        "whatlinkshere-title": "«$1» яхача оагӏонна тӏатовжаш йола оагӏонаш",
        "whatlinkshere-page": "ОагIув:",
-       "linkshere": "«'''[[:$1]]'''» ← укхунна тӀахьожавеш я тӀехьайоагӀа оагӀонаш:",
-       "nolinkshere": "Кхыйолча оагӏонашкара '''[[:$1]]''' яхача оагӏон тIатовжамаш доацаш да.",
+       "linkshere-2": "«'''$1'''» ← укхунна тӀахьожавеш я тӀехьайоагӀа оагӀонаш:",
+       "nolinkshere-2": "Кхыйолча оагӏонашкара '''$1''' яхача оагӏон тIатовжамаш доацаш да.",
        "isredirect": "дIа-хьа хьожавара оагIув",
        "istemplate": "юкъейоалаяр",
        "isimage": "Файлови тӏатовжам",
-       "whatlinkshere-prev": "{{PLURAL:$1|1=хьалхайоагIа|хьалхайоагIараш}} $1",
-       "whatlinkshere-next": "{{PLURAL:$1|1=Ñ\82IеÑ\85Ñ\8cайоагIаÑ\80\82IеÑ\85Ñ\8cайоагIаÑ\80аÑ\88}} $1",
+       "whatlinkshere-prev": "{{PLURAL:$1|1=хьалхайоагIача|хьалхайоагIача}} $1-ннега",
+       "whatlinkshere-next": "{{PLURAL:$1|1=Ñ\82IеÑ\85Ñ\8cайоагIаÑ\87а|Ñ\82IеÑ\85Ñ\8cайоагIаÑ\87а}} $1-ннега",
        "whatlinkshere-links": "← тӏатовжамаш",
        "whatlinkshere-hideredirs": "$1 дӀа-хьа хьожавараш",
        "whatlinkshere-hidetrans": "$1 юкъедоаладаьраш",
        "tooltip-ca-nstab-help": "Новкъостала оагIув",
        "tooltip-ca-nstab-category": "ОагӀата оагӀув",
        "tooltip-minoredit": "Ер хувцар кIезига дар санна белгалде",
-       "tooltip-save": "Ð¥Ñ\8cа Ñ\85Ñ\83вÑ\86амаÑ\88 Ð»Ð¾Ñ\80адеÑ\88 Ð´IаÑ\8fзде",
+       "tooltip-save": "Ð\94IаÑ\8fзде Ñ\85Ñ\8cай Ñ\85Ñ\83вÑ\86амаÑ\88",
        "tooltip-preview": "ОагIонна хьалххе бIаргтохар.\nДехар да, оагӀув дIаязъелехь хьажа из мишта я!",
        "tooltip-diff": "Чухьнахьара текстаца даь хувцамаш хьахьокха",
        "tooltip-compareselectedversions": "Укх оагIон хержа шин версешта юкъе йола башхалога хьажа.",
        "patrol-log-page": "ТӀахьожама тептар",
        "previousdiff": "← КъаьнагIа дола нийсдаьр",
        "nextdiff": "КердагӀа дола нийсдаьр →",
+       "imagemaxsize": "Сурта боарамá доазув тохар:<br />''(Файлах лаьца дувцача оагӀона)''",
+       "thumbsize": "Сурта зIамагIа йолча эрша боарам:",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|оагӀув}}",
        "file-info-size": "$1 × $2 {{PLURAL:$2|пиксель}}, файла боарам: $3, MIME-тайпа: $4",
        "file-info-size-pages": "$1 × $2 пиксель, файлан боарам: $3, MIME-тайп: $4, $5 {{PLURAL:$5|1=оагӀув}}",
        "imgmultigo": "Дехьавала!",
        "imgmultigoto": "$1 оагIон тIа дехьавала",
        "table_pager_limit_submit": "Кхоачашде",
+       "watchlistedit-normal-title": "Зема хьаязъяьр хувцар",
        "watchlisttools-clear": "IоцIанъе зем бара хьаязъяьр",
        "watchlisttools-view": "Хьаязъяьр чура оагIонаш тIа дола хувцамаш",
        "watchlisttools-edit": "Хьажа а хувца а хьаязъяьр",
        "specialpages-group-users": "Доакъашхойи бокъонаши",
        "specialpages-group-pages": "ОагIонай хьаязъяьраш",
        "specialpages-group-pagetools": "ОагIонашта эша кечалаш",
+       "specialpages-group-developer": "Кийчдархочун кечалаш",
        "external_image_whitelist": "#Ер мугI ший болча тайпара бита<pre>\n#Укхаз оттаде кастта дувлача выражений фрагменташ (// юкъе дола дакъа)\n#арахьара суртий URL адресашца дIанийсалургда уш.\n#Мегаргдола сурташ санна хьахьекха хургда, дIаходараш, сурташта тIахьожаяргаш санна хьахьекха хургда.\n#Укханца # долалуш дола могIараш алараш санна лоархIаш да.\n#МогIараш регистраца кIаьда дац\n\n#Укх могIара лакхе оттаде кастта дувлача выражений фрагменташ. Ер мугI ший болча тайпара бита</pre>",
        "tag-filter": "[[Special:Tags|Белгалонай]] фильтр:",
        "tag-filter-submit": "Литта",
        "tags-active-yes": "XӀау",
        "tags-active-no": "A",
        "tags-edit": "нийсде",
+       "tags-delete": "дӀаяккха",
        "tags-hitcount": "$1 {{PLURAL:$1|1=хувцам|хувцамаш}}",
        "tags-create-submit": "Хьакхолла",
+       "tags-deactivate-submit": "ДӀайоае",
        "compare-page1": "ЦхьоаллагIа оагIув",
        "compare-page2": "ШоллагIа оагӀув",
        "compare-rev1": "Хьалхара эрш",
        "duration-days": "{{PLURAL:$1|ди}}",
        "expand_templates_preview": "Хьалххе бIаргтохар",
        "pagelang-name": "ОагIув",
+       "pagelang-language": "Мотт",
        "special-characters-group-latin": "Латиний",
        "special-characters-group-greek": "Эллиной",
        "special-characters-group-cyrillic": "Кириллица",
index 8032223..359c6aa 100644 (file)
        "rev-deleted-user-contribs": "[Uzero od IP-adreso eliminita - la redakto celesis de la kontributaji]",
        "rev-delundel": "montrar/celar",
        "rev-showdeleted": "montrar",
+       "revisiondelete": "Efacar/Restaurar revizi",
        "revdelete-show-file-submit": "Yes",
        "revdelete-hide-image": "Celar kontenajo dil arkivo",
        "revdelete-hide-comment": "Rezumo di redakto",
        "right-upload": "Adkargar arkivi",
        "right-writeapi": "Uzez API por skribar",
        "right-delete": "Efacar pagini",
+       "right-deleterevision": "Efacar e restaurar specifika revizi de la pagini",
        "right-browsearchive": "Serchar pagini efacita",
        "right-suppressrevision": "Vidar, celar e deskovrar specifika revizi di pagini de irga uzero",
        "right-blockemail": "Blokusar uzero pri sendar e-posto",
        "rcfilters-activefilters": "Agiva filtrili",
        "rcfilters-advancedfilters": "Rafinita filtrili",
        "rcfilters-limit-title": "Rezulti por montrar",
+       "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|modifikuro|modifikuri}}, $2",
        "rcfilters-date-popup-title": "Quanto di tempo por serchar",
        "rcfilters-days-title": "Recenta dii",
        "rcfilters-hours-title": "Recenta hori",
        "rcfilters-filter-user-experience-level-experienced-label": "Experta uzeri",
        "rcfilters-filter-user-experience-level-experienced-description": "Plu kam 30 dii di agemeso e 500 redakti.",
        "rcfilters-filter-humans-label": "Homala (ne 'bot')",
+       "rcfilters-filter-humans-description": "Redakturi kreita da homi.",
        "rcfilters-filtergroup-significance": "Senco",
        "rcfilters-filter-pageedits-label": "Redakti di pagini",
+       "rcfilters-filter-pageedits-description": "Redakturi en la kontenajo dil Wiki, diskuti, deskriptado di kategorii...",
        "rcfilters-filter-newpages-label": "Kreado di pagini",
+       "rcfilters-filter-newpages-description": "Redakturi qui kreas nova pagini.",
        "rcfilters-filter-categorization-label": "Modifiki di la kategorio",
        "rcfilters-filter-logactions-label": "Agadi enrejistrata",
+       "rcfilters-filter-logactions-description": "Agadi dal administreri, kreado di konti, efaco di pagini, sendo di arkivi...",
        "rcfilters-liveupdates-button": "Quika aktualigi",
        "rcnotefrom": "Infre {{PLURAL:$5|esas la chanjo|esas la chanji}} de <strong>$3, $4</strong> (montrata til <strong>$1</strong>).",
        "rclistfrom": "Montrar nova chanji startante de $3 $2",
        "unusedimagestext": "La sequanta arkivi existas, ma ne esas enterigita en irga pagino.\nVoluntez remarkar ke altra ret-siti povus ligesar ad arkivo per direta URL, e do ol povus esar listizita hike malgre ke on aktive uzas lo.",
        "notargettitle": "Ne esas vakua pagino",
        "notargettext": "Vu ne definis en qua pagino agar ica funciono.",
+       "nopagetitle": "La pagino ne existas",
+       "nopagetext": "La pagino quon vu serchis ne existas.",
        "pager-newer-n": "{{PLURAL:$1|plu nova 1|plu nova $1}}",
        "pager-older-n": "{{PLURAL:$1|plu anciena 1|plu anciena $1}}",
        "apihelp-no-such-module": "Modulo « $1 » ne esis trovita.",
        "deleteotherreason": "Altra/suplementala motivo:",
        "deletereasonotherlist": "Altra motivo",
        "deletereason-dropdown": "*Ordinara motivi por efacado\n** \"Spam\" nedezirata mesaji\n** Vandalismo\n** Kopiyuro Violaco\n** Demandita da autoro\n** Nefuncionanta ligilo",
+       "deleting-backlinks-warning": "<strong>Atencez:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Altra pagini]] ligesas ad or inkluzas la pagino quon vu deziras efacar.",
        "rollback": "Retrorulez redakti",
        "rollbacklink": "retrorulez",
        "rollbacklinkcount": "nuligar $1 {{PLURAL:$1|modifiko|modifiki}}",
        "restriction-upload": "Adkargar",
        "undelete": "Vidar efacita pagini",
        "undeletepage": "Vidar e restaurar efacita pagini",
+       "undeletepagetitle": "<strong>Yen la efacita versioni di la pagino [[:$1|$1]]</strong>.",
+       "viewdeletedpage": "Vidar pagini efacita",
        "undeletepagetext": "La sequanta {{PLURAL:$1|pagino|pagini}} efacesis ma {{PLURAL:$1|ol|li}} ankore esas en la arkivo ed esas restaurebla. La arkivo povas netigesar periodale.",
+       "undelete-fieldset-title": "Restaurar revizi",
+       "undeleteextrahelp": "Por restaurar omna historio de la pagino, desselektez omna buxi e kliktez <strong><em>{{int:undeletebtn}}</em></strong>.\nPor selektar quala modifiki restauresos, markizez la buxi korespondanta a la revizi por restaurar, e kliktez <strong><em>{{int:undeletebtn}}</em></strong>.",
        "undeleterevisions": "$1 {{PLURAL:$1|revizo|revizi}} efacita",
        "undeletehistory": "Se vu restauros la pagino, omna antea revizi restauresos en la korespondanta historiala pagino.\nSe nova pagino kun la sama titulo kreesis pos l'efaco, la restaurita revizuri aparos en lua historiala pagino.",
+       "undeleterevdel": "La restauro ne facesos se to produktos partala o totala efaco de la maxim recenta revizo.\nCa kazi, vu mustas desselektar o trovar la maxim recenta versiono efacita.",
+       "undeletehistorynoadmin": "Ica pagino efacesis.\nLa motivo por l'efaco montresas en la rezumo adinfre, kune la detaligo dil uzeri qui redaktis la pagino ante lua efaco.\nLa kompleta texto di ca revizi efacita esas videbla nur por l'administreri.",
        "undeleterevision-missing": "Nevalida o mankanta revizo.\nSive vu skribis la ligilo nekorekte, sive la revizo restauresis o removesis del arkivo.",
        "undeletebtn": "Restaurar",
        "undeletelink": "vidar/restaurar",
        "undeleteviewlink": "videz",
+       "undeleteinvert": "Inversigar selektajo",
        "undeletecomment": "Motivo:",
        "undeletedpage": "<strong>$1 restauresis</strong>\n\nVidez la [[Special:Log/delete|'log' pri efaci]] por vidar omna recenta efaci e restauri.",
        "undelete-search-box": "Serchez efacita pagini",
        "whatlinkshere": "Quo ligesas adhike",
        "whatlinkshere-title": "Pagini qui ligas ad \"$1\"",
        "whatlinkshere-page": "Pagino:",
-       "linkshere": "Ca pagini esas ligilizita ad '''[[:$1]]''':",
-       "nolinkshere": "Nula pagino ligas ad '''[[:$1]]'''.",
+       "linkshere-2": "Ca pagini esas ligilizita ad '''$1''':",
+       "nolinkshere-2": "Nula pagino ligas ad '''$1'''.",
        "isredirect": "ridirektanta pagino",
        "istemplate": "inkluzo",
        "isimage": "arkivo-ligilo",
        "tags-hitcount": "$1 {{PLURAL:$1|chanjo|chanji}}",
        "tags-create-explanation": "Segun predefino, la nova etiketi kreita divenos disponebla por uzado, sive da uzeri, sive da informatikoprogrami 'bot'.",
        "tags-create-warnings-above": "La sequanta {{PLURAL:$2|avizo|avizi}} renkontresis, probante kreir l'etiketo \"$1\":",
+       "tags-delete-not-found": "L'etiketo \"$1\" ne existas.",
        "tags-delete-too-many-uses": "L'etiketo \"$1\" uzesas en plua kam $2 {{PLURAL:$2|revizo|revizi}}, do ol ne povas eskartesar.",
        "tags-delete-warnings-after-delete": "L'etiketo \"$1\" efacesis, ma la sequanta {{PLURAL:$2|avizo|avizi}} renkontresis:",
        "tags-activate-not-found": "L'etiketo \"$1\" ne existas.",
+       "dberr-problems": "Pardonez! Ica retopagino subisas teknikala problemi.",
+       "dberr-again": "Voluntez vartar kelka minuti, e riprobez acesar ol.",
+       "dberr-info": "(Ne povis acesar la datumaro: $1)",
+       "dberr-info-hidden": "(La datumaro ne esas disponebla)",
+       "dberr-outofdate": "Atencez ke l'indexi pri kontenaji povas esar antiquatra.",
        "htmlform-reset": "Desfacar chanji",
        "htmlform-selectorother-other": "Altra",
        "htmlform-cloner-create": "Adjuntar plue",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|modifikis}} la nivelo di protekto di $3 $4 [kaskade]",
        "logentry-upload-upload": "$1 {{GENDER:$2|uploaded}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|parsendis}} nova versiono di $3",
+       "log-name-tag": "Protokolo di etiketi",
        "rightsnone": "(nula)",
        "searchsuggest-search": "Serchez en {{SITENAME}}",
        "searchsuggest-containing": "quan kontenas...",
index eab988b..47cd5be 100644 (file)
        "grant-viewrestrictedlogs": "Skoða lokaðar skráningar",
        "newuserlogpage": "Skrá yfir nýja notendur",
        "newuserlogpagetext": "Þetta er skrá yfir nýskráða notendur.",
-       "rightslog": "Réttindaskrá notenda",
+       "rightslog": "Réttindaskrá notanda",
        "rightslogtext": "Þetta er skrá yfir breytingar á réttindum notenda.",
        "action-read": "lesa þessa síðu",
        "action-edit": "breyta þessari síðu",
        "emailuser-title-notarget": "Senda tölvupóst",
        "emailpagetext": "Hafi notandinn tilgreint netfang í stillingunum sínum er hægt að senda póst til {{GENDER:$1|hans|hennar|hans}} hér.\nPóstfangið sem þú tilgreindir í [[Special:Preferences|stillingunum þínum]] birtist í \"Frá:\" hluta tölvupóstsins, svo að viðtakandi hans geti svarað beint til þín.",
        "defemailsubject": "{{SITENAME}} skilaboð frá notandanum \"$1\"",
-       "usermaildisabled": "Netfang notenda er óvirkt",
+       "usermaildisabled": "Netfang notanda er óvirkt",
        "usermaildisabledtext": "Þú getur ekki sent tölvupóst til annara notenda á þessum wiki",
        "noemailtitle": "Ekkert póstfang",
        "noemailtext": "Þessi notandi hefur ekki tilgreint gilt netfang.",
        "whatlinkshere": "Hvað tengist hingað",
        "whatlinkshere-title": "Síður sem tengjast „$1“",
        "whatlinkshere-page": "Síða:",
-       "linkshere": "Eftirfarandi síður tengjast á '''[[:$1]]''':",
-       "nolinkshere": "Engar síður tengjast á '''[[:$1]]'''.",
-       "nolinkshere-ns": "Engar síður tengjast '''[[:$1]]''' í þessu nafnrými.",
+       "linkshere-2": "Eftirfarandi síður tengjast á '''$1''':",
+       "nolinkshere-2": "Engar síður tengjast á '''$1'''.",
+       "nolinkshere-ns-2": "Engar síður tengjast '''$1''' í þessu nafnrými.",
        "isredirect": "endurbeind síða",
        "istemplate": "innifalið",
        "isimage": "skráartengill",
        "articleexists": "Annaðhvort er þegar til síða undir þessum titli, eða sá titill sem þú hefur valið er ekki gildur.\nVeldu einhvern annan titil.",
        "cantmove-titleprotected": "Þú getur ekki fært síðu á þessa staðsetningu, því nýi titillinn hefur verið verndaður gegn sköpun",
        "movetalk": "Færa meðfylgjandi spjallsíðu",
-       "move-subpages": "Færa undirstíður (upp að $1)",
-       "move-talk-subpages": "Færa undirstíður spjallsíðunnar (upp að $1)",
+       "move-subpages": "Færa undirsíður (upp að $1)",
+       "move-talk-subpages": "Færa undirsíður spjallsíðunnar (upp að $1)",
        "movepage-page-exists": "Síðan $1 er nú þegar til og er ekki hægt að yfirskrifa sjálfkrafa.",
        "movepage-page-moved": "Síðan $1 hefur verið færð á $2.",
        "movepage-page-unmoved": "Ekki var hægt að færa síðuna $1 á $2.",
        "fileduplicatesearch-noresults": "Mistókst að finna skrána \"$1\"",
        "specialpages": "Kerfissíður",
        "specialpages-note-top": "Fyrirsögn",
+       "specialpages-note-restricted": "* Venjulegar kerfissíður.\n* <span class=\"mw-specialpagerestricted\">Kerfissíður með takmörkuðum aðgangi.</span>",
        "specialpages-group-maintenance": "Viðhaldsskýrslur",
        "specialpages-group-other": "Aðrar kerfissíður",
        "specialpages-group-login": "Skrá inn / Búa til aðgang",
        "tags-edit-reason": "Ástæða:",
        "tags-edit-success": "Breytingarnar voru framkvæmdar.",
        "tags-edit-nooldid-title": "Ógild markútgáfa",
-       "tags-edit-none-selected": "Vinsamlega veldu a.m.k. eitt merki til að bæta við eða fjarlægja.",
+       "tags-edit-none-selected": "Veldu a.m.k. eitt merki til að bæta við eða fjarlægja.",
        "comparepages": "Bera saman síður",
        "compare-page1": "Síða 1",
        "compare-page2": "Síða 2",
index 3f601e3..71eeb45 100644 (file)
        "subject-preview": "Anteprima dell'oggetto:",
        "previewerrortext": "Si è verificato un errore durante il tentativo di mostrare l'anteprima delle tue modifiche.",
        "blockedtitle": "Utente bloccato.",
-       "blockedtext": "'''Il tuo nome utente o indirizzo IP è stato bloccato.'''\n\nIl blocco è stato imposto da $1. La motivazione del blocco è la seguente: ''$2''\n\n* Inizio del blocco: $8\n* Scadenza del blocco: $6\n* Intervallo di blocco: $7\n\nSe lo si desidera, è possibile contattare $1 o un altro [[{{MediaWiki:Grouppage-sysop}}|amministratore]] per discutere del blocco.\n\nSi noti che la funzione 'Scrivi all'utente' non è attiva se non è stato registrato un indirizzo e-mail valido nelle proprie [[Special:Preferences|preferenze]] o se l'utilizzo di tale funzione è stato bloccato.\n\nL'indirizzo IP attuale è $3, il numero ID del blocco è #$5.\nSi prega di specificare tutti i dettagli precedenti in qualsiasi richiesta di chiarimenti.",
-       "autoblockedtext": "Questo indirizzo IP è stato bloccato automaticamente perché condiviso con un altro utente, a sua volta bloccato da $1.\nLa motivazione del blocco è la seguente:\n\n:''$2''\n\n* Inizio del blocco: $8\n* Scadenza del blocco: $6\n* Intervallo di blocco: $7\n\nÈ possibile contattare $1 o un altro [[{{MediaWiki:Grouppage-sysop}}|amministratore]] per richiedere eventuali chiarimenti circa il blocco.\n\nSi noti che la funzione 'Scrivi all'utente' non è attiva se non è stato registrato un indirizzo e-mail valido nelle proprie [[Special:Preferences|preferenze]] e, comunque, se nell'applicare il blocco, tale funzione è stata disabilitata (per la durata del blocco).\n\nL'indirizzo IP attuale è $3, il numero ID del blocco è #$5\nSi prega di specificare tutti i dettagli qui inclusi nel compilare qualsiasi richiesta di chiarimenti.",
+       "blockedtext": "<strong>Il tuo nome utente o indirizzo IP è stato bloccato.</strong>\n\nIl blocco è stato imposto da $1. La motivazione del blocco è la seguente: <em>$2</em>.\n\n* Inizio del blocco: $8\n* Scadenza del blocco: $6\n* Intervallo di blocco: $7\n\nSe lo si desidera, è possibile contattare $1 o un altro [[{{MediaWiki:Grouppage-sysop}}|amministratore]] per discutere del blocco.\n\nSi noti che la funzione \"{{int:emailuser}}\" non è attiva se non è stato registrato un indirizzo email valido nelle proprie [[Special:Preferences|preferenze]] o se l'utilizzo di tale funzione è stato bloccato.\n\nL'indirizzo IP attuale è $3, il numero ID del blocco è #$5.\nSi prega di specificare tutti i dettagli precedenti in qualsiasi richiesta di chiarimenti.",
+       "autoblockedtext": "Questo indirizzo IP è stato bloccato automaticamente perché condiviso con un altro utente, a sua volta bloccato da $1.\nLa motivazione del blocco è la seguente:\n\n:<em>$2</em>\n\n* Inizio del blocco: $8\n* Scadenza del blocco: $6\n* Intervallo di blocco: $7\n\nÈ possibile contattare $1 o un altro [[{{MediaWiki:Grouppage-sysop}}|amministratore]] per richiedere eventuali chiarimenti circa il blocco.\n\nSi noti che la funzione \"{{int:emailuser}}\" non è attiva se non è stato registrato un indirizzo e-mail valido nelle proprie [[Special:Preferences|preferenze]] e, comunque, se nell'applicare il blocco, tale funzione è stata disabilitata (per la durata del blocco).\n\nL'indirizzo IP attuale è $3, il numero ID del blocco è #$5\nSi prega di specificare tutti i dettagli qui inclusi nel compilare qualsiasi richiesta di chiarimenti.",
        "systemblockedtext": "Il tuo nome utente o l'indirizzo IP è stato bloccato automaticamente da MediaWiki.\nLa motivazione del blocco è la seguente:\n\n:''$2''\n\n* Inizio del blocco: $8\n* Scadenza del blocco: $6\n* Intervallo di blocco: $7\n\nL'indirizzo IP attuale è $3.\nSi prega di specificare tutti i dettagli qui inclusi nel compilare qualsiasi richiesta di chiarimenti.",
        "blockednoreason": "nessuna motivazione indicata",
        "whitelistedittext": "Per modificare le pagine è necessario $1.",
        "recentchangescount": "Numero di modifiche da mostrare nelle ultime modifiche, cronologie e registri, per impostazione predefinita:",
        "prefs-help-recentchangescount": "Numero massimo: 1000",
        "prefs-help-watchlist-token2": "Questa è la chiave segreta per il feed web dei tuoi osservati speciali.\nChiunque la conosce sarà in grado di leggere i tuoi osservati speciali, per cui non condividerla. Se necessario, [[Special:ResetTokens|puoi reimpostarla]].",
-       "prefs-help-tokenmanagement": "Puoi visualizzare e reimpostare la chiave segreta per la tua utenza con cui puoi accedere al feed web dei tuoi osservati speciali. Chiunque conosce la chiave sarà in grado di leggere i tuoi osservati speciali, quindi non condividerla.",
+       "prefs-help-tokenmanagement": "Puoi visualizzare e reimpostare la chiave segreta per la tua utenza con cui puoi accedere al feed web dei tuoi osservati speciali. Chiunque conosca la chiave sarà in grado di leggere i tuoi osservati speciali, quindi non condividerla.",
        "savedprefs": "Le preferenze sono state salvate.",
        "savedrights": "I gruppi utente di {{GENDER:$1|$1}} sono stati salvati.",
        "timezonelegend": "Fuso orario:",
        "protectedtitles-submit": "Mostra titoli",
        "listusers": "Elenco degli utenti",
        "listusers-editsonly": "Mostra solo utenti con dei contributi",
+       "listusers-temporarygroupsonly": "Mostra solo utenti in gruppi utenti temporanei",
        "listusers-creationsort": "Ordina per data di creazione",
        "listusers-desc": "Ordina in senso decrescente",
        "usereditcount": "$1 {{PLURAL:$1|contributo|contributi}}",
        "whatlinkshere": "Puntano qui",
        "whatlinkshere-title": "Pagine che puntano a \"$1\"",
        "whatlinkshere-page": "Pagina:",
-       "linkshere": "Le seguenti pagine contengono dei collegamenti a <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Nessuna pagina contiene collegamenti che puntano a '''[[:$1]]'''.",
-       "nolinkshere-ns": "Non vi sono pagine che puntano a '''[[:$1]]''' nel namespace selezionato.",
+       "linkshere-2": "Le seguenti pagine contengono dei collegamenti a <strong>$1</strong>:",
+       "nolinkshere-2": "Nessuna pagina contiene collegamenti che puntano a '''$1'''.",
+       "nolinkshere-ns-2": "Non vi sono pagine che puntano a '''$1''' nel namespace selezionato.",
        "isredirect": "redirect",
        "istemplate": "inclusione",
        "isimage": "collegamento al file",
        "undelete-cantedit": "Non puoi ripristinare questa pagina poiché non hai sufficienti permessi per modificarla.",
        "undelete-cantcreate": "Non puoi ripristinare questa pagina poiché la pagina con questo nome non è ancora inesistente e non hai sufficienti permessi per crearla.",
        "pagedata-not-acceptable": "Nessun formato corrispondente trovato. Tipi MIME supportati: $1",
-       "pagedata-bad-title": "Titolo non valido: $1."
+       "pagedata-bad-title": "Titolo non valido: $1.",
+       "unregistered-user-config": "Per motivi di sicurezza, non è possibile caricare sottopagine utente JavaScript, CSS e JSON per utenti non registrati.",
+       "passwordpolicies-group": "Gruppo",
+       "passwordpolicies-policy-minimalpasswordlength": "La password deve essere lunga almeno $1 {{PLURAL:$1|carattere|caratteri}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "La password deve essere lunga almeno $1 {{PLURAL:$1|carattere|caratteri}} per poter accedere",
+       "passwordpolicies-policy-passwordcannotmatchusername": "La password non può essere uguale al nome utente",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "La password non può corrispondere a password specificate nell'elenco delle password proibite",
+       "passwordpolicies-policy-maximalpasswordlength": "La password deve essere lunga meno di $1 {{PLURAL:$1|carattere|caratteri}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "La password non può essere {{PLURAL:$1|la password più popolare|nell'elenco delle $1 password più popolari}}"
 }
index 3e5182e..2c02c2a 100644 (file)
        "rcfilters-filter-reviewstatus-unpatrolled-description": "手動または自動で巡回されていない編集。",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "未巡回",
        "rcfilters-filter-reviewstatus-manual-description": "巡回済みと手動でマークされた編集。",
+       "rcfilters-filter-reviewstatus-manual-label": "手動巡回",
+       "rcfilters-filter-reviewstatus-auto-description": "巡回済みと自動でマークされた編集。",
+       "rcfilters-filter-reviewstatus-auto-label": "自動巡回",
        "rcfilters-filtergroup-significance": "重要度",
        "rcfilters-filter-minor-label": "細部の編集",
        "rcfilters-filter-minor-description": "編集者が細部の編集とマークしたもの。",
        "whatlinkshere": "リンク元",
        "whatlinkshere-title": "「$1」へリンクしているページ",
        "whatlinkshere-page": "ページ:",
-       "linkshere": "以下のページが、<strong>[[:$1]]</strong> にリンクしています:",
-       "nolinkshere": "<strong>[[:$1]]</strong> にリンクしているページはありません。",
-       "nolinkshere-ns": "指定した名前空間内に、<strong>[[:$1]]</strong> にリンクしているページはありません。",
+       "linkshere-2": "以下のページが、<strong>$1</strong> にリンクしています:",
+       "nolinkshere-2": "<strong>$1</strong> にリンクしているページはありません。",
+       "nolinkshere-ns-2": "指定した名前空間内に、<strong>$1</strong> にリンクしているページはありません。",
        "isredirect": "転送ページ",
        "istemplate": "参照読み込み",
        "isimage": "ファイルへのリンク",
index 198dd1d..79354d1 100644 (file)
        "whatlinkshere": "Wa lingk ya",
        "whatlinkshere-title": "Piej wa lingk tu \"$1\"",
        "whatlinkshere-page": "Piej:",
-       "linkshere": "Di falarin piejdem lingk tu '''[[:$1]]''':",
+       "linkshere-2": "Di falarin piejdem lingk tu '''$1''':",
        "isredirect": "riidirek piej",
        "istemplate": "chranskluujan",
        "isimage": "fail lingk",
index 82ace80..ae892bd 100644 (file)
        "whatlinkshere": "Hwa henwise hertil",
        "whatlinkshere-title": "Side som linke te $1",
        "whatlinkshere-page": "Siid:",
-       "linkshere": "Di följenje side henwise te '''„[[:$1]]“''':",
-       "nolinkshere": "Ien side henwise te '''„[[:$1]]“'''.",
+       "linkshere-2": "Di följenje side henwise te '''„$1“''':",
+       "nolinkshere-2": "Ien side henwise te '''„$1“'''.",
        "isredirect": "omdirigiirengssiid",
        "istemplate": "inlejreng",
        "isimage": "filhenwisneng",
index 0d85f3b..6ee482f 100644 (file)
@@ -17,7 +17,8 @@
                        "아라",
                        "Macofe",
                        "Matma Rex",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Notanotheramy"
                ]
        },
        "tog-underline": "Garis ngisori pranala:",
        "savechanges": "Simpen owahan",
        "publishpage": "Babar kaca",
        "publishchanges": "Babar owahan",
+       "publishchanges-start": "Babar owahan...",
        "preview": "Pratuduh",
        "showpreview": "Deleng pratuduh",
        "showdiff": "Tuduhaké owahan",
        "whatlinkshere": "Sing nggayut mréné",
        "whatlinkshere-title": "Kaca mawa pranala nggayut \"$1\"",
        "whatlinkshere-page": "Kaca:",
-       "linkshere": "Kaca-kaca ing ngisor iki nggayut menyang <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Ora ana kaca sing nduwé pranala menyang '''[[:$1]]'''.",
-       "nolinkshere-ns": " Ora ana kaca sing nduwé pranala menyang '''[[:$1]]''' ing bilik jeneng sing kapilih.",
+       "linkshere-2": "Kaca-kaca ing ngisor iki nggayut menyang <strong>$1</strong>:",
+       "nolinkshere-2": "Ora ana kaca sing nduwé pranala menyang '''$1'''.",
+       "nolinkshere-ns-2": " Ora ana kaca sing nduwé pranala menyang '''$1''' ing bilik jeneng sing kapilih.",
        "isredirect": "kaca lih-lihan",
        "istemplate": "tranklusi",
        "isimage": "pranala barkas",
        "fileduplicatesearch-noresults": "Ora tinemu barkas kanthi jeneng \"$1\".",
        "specialpages": "Kaca mirunggan",
        "specialpages-note-top": "Katrangan",
+       "specialpages-note-restricted": "* Kaca mirunggan sedhengan.\n* <span class=\"mw-specialpagerestricted\">Kaca mirunggan winatesan.</span>",
        "specialpages-group-maintenance": "Lapuran pangopèn",
        "specialpages-group-other": "Kaca mirunggan liyané",
        "specialpages-group-login": "Mlebu log / nggawé akun",
index a942a6b..c33e82e 100644 (file)
        "prefs-dateformat": "თარიღის ფორმატი",
        "prefs-timeoffset": "სასაათო სარტყლის ცვლილება",
        "prefs-advancedediting": "მთავარი პარამეტრები",
+       "prefs-developertools": "შემმუშავებლის ხელსაწყოები",
        "prefs-editor": "რედაქტორი",
        "prefs-preview": "წინასწარი გადახედვა",
        "prefs-advancedrc": "გაფართოებული პარამეტრები",
        "whatlinkshere": "ბმული გვერდზე",
        "whatlinkshere-title": "გვერდები, რომლებიც შეიცავენ „$1“-ის ბმულებს",
        "whatlinkshere-page": "გვერდი:",
-       "linkshere": "მომდევნო გვერდები შეიცავენ ბმულებს '''[[:$1]]'''-ზე:",
-       "nolinkshere": "'''[[:$1]]'''-ზე ბმული არ არის.",
-       "nolinkshere-ns": "არჩეულ სახელთა სივრცეში არ არის გვერდები, რომლებიც მისამართდება '''[[:$1]]'''.",
+       "linkshere-2": "მომდევნო გვერდები შეიცავენ ბმულებს '''$1'''-ზე:",
+       "nolinkshere-2": "'''$1'''-ზე ბმული არ არის.",
+       "nolinkshere-ns-2": "არჩეულ სახელთა სივრცეში არ არის გვერდები, რომლებიც მისამართდება '''$1'''.",
        "isredirect": "გადამისამართების გვერდი",
        "istemplate": "ჩართვა",
        "isimage": "ბმული ფაილზე",
        "specialpages-group-wiki": "მონაცემები და ინსტრუმენტები",
        "specialpages-group-redirects": "სპეცგვერდების გადამისამართება",
        "specialpages-group-spam": "ინსტრუმენტები სპამის წინააღმდეგ",
-       "specialpages-group-developer": "á\83¨á\83\94á\83\9bá\83¥á\83\9bá\83\9cá\83\94ლის ხელსაწყოები",
+       "specialpages-group-developer": "á\83¨á\83\94á\83\9bá\83\9bá\83£á\83¨á\83\90á\83\95á\83\94á\83\91ლის ხელსაწყოები",
        "blankpage": "ცარიელი გვერდი",
        "intentionallyblankpage": "ეს გვერდი სპეციალურად დარჩა ცარიელი",
        "external_image_whitelist": "  #დატოვეთ ეს ხაზი ისე, როგორც არის <pre>\n#განათვსეთ აქ რეგულარულ გამოთქმათა ფრაგმენტები (ისინი, რომლებიც // შორის იმყოფება)\n#ისინი იქნებიან შეფარდებულები გარე გამოსახულებათა URL-თან.\n#მოგერგებული იქნება ნაჩვენები გამოსახულებათა სახით, ხოლო სხვები ბმულების სახით.\n#ხაზები, რომლებიც იწყება #, ითვლება კომენტარად.\n#ხაზები გრძნობადები არიან რეგისტრისადმი.</pre>",
index 58fa884..e29c671 100644 (file)
        "whatlinkshere": "Siltelgen betler",
        "whatlinkshere-title": "\"$1\" betine siltelgen betler",
        "whatlinkshere-page": "Bet:",
-       "linkshere": "To'mendegi betler mınag'an siltelgen: '''[[:$1]]''':",
-       "nolinkshere": "'''[[:$1]]''' degenge hesh bet siltemeydi.",
+       "linkshere-2": "To'mendegi betler mınag'an siltelgen: '''$1''':",
+       "nolinkshere-2": "'''$1''' degenge hesh bet siltemeydi.",
        "isredirect": "burıwshı bet",
        "istemplate": "qosıw",
        "isimage": "fayl siltewi",
index a2b120d..385687b 100644 (file)
        "whatlinkshere": "Ayen i d-yettawi ɣer da",
        "whatlinkshere-title": "Isebtaren i sɛan azday ɣer « $1 »",
        "whatlinkshere-page": "Asebter :",
-       "linkshere": "Isebtar-agi sɛan azday ɣer '''[[:$1]]''':",
-       "nolinkshere": "Ulac asebter i yesɛan azday ɣer '''[[:$1]]'''.",
-       "nolinkshere-ns": "Ulac asebter i yesɛan azday ɣer '''[[:$1]]''' deg yisem n taɣult i textareḍ.",
+       "linkshere-2": "Isebtar-agi sɛan azday ɣer '''$1''':",
+       "nolinkshere-2": "Ulac asebter i yesɛan azday ɣer '''$1'''.",
+       "nolinkshere-ns-2": "Ulac asebter i yesɛan azday ɣer '''$1''' deg yisem n taɣult i textareḍ.",
        "isredirect": "Asebter n usemmimeḍ",
        "istemplate": "asekcam",
        "isimage": "azday ɣer afaylu",
        "fileduplicatesearch-noresults": "Ulac afaylu s isem « $1 ».",
        "specialpages": "isebtar usligen",
        "specialpages-note-top": "Aglam",
+       "specialpages-note-restricted": "* Isebtar usligen imugna.\n* <span class=\"mw-specialpagerestricted\">Isebtar usligen ukrifen.</span>",
        "specialpages-group-maintenance": "Iṛabulen n ibeddi",
        "specialpages-group-other": "Isebtar usligen nniḍen",
        "specialpages-group-login": "Asulu / assiggez",
index d21be5a..5e14d55 100644 (file)
        "whatlinkshere": "ТехьэпӀэхэр мыбдеж",
        "whatlinkshere-title": "«$1» техьэ напэкІуэцІхэр",
        "whatlinkshere-page": "НапэкIуэцI:",
-       "linkshere": "Мыбым '''[[:$1]]'''  тохьэ напэкӀуэцӀхэр:",
+       "linkshere-2": "Мыбым '''$1'''  тохьэ напэкӀуэцӀхэр:",
        "isredirect": "напэкIуэцI-егъэкIуэкIа",
        "istemplate": "хэгъэхьэныгъэ",
        "isimage": "сурэтым и техьэпӀэ",
index 7705d89..09db309 100644 (file)
        "whatlinkshere": "Takayɩhatʋ kɩtamtʋ",
        "whatlinkshere-title": "Takayɩhatʋ ndʋ tɩtamsɩna \\ $1 \\ yɔ",
        "whatlinkshere-page": "Takayɩhayʋʋ :",
-       "linkshere": "Takayɩhatʋ ndʋ tɩwɛ pɩ-tɛɛ yɔ tɩwɛna kpasɩ <strong>[[:$1]]<strong> yɔɔ:",
+       "linkshere-2": "Takayɩhatʋ ndʋ tɩwɛ pɩ-tɛɛ yɔ tɩwɛna kpasɩ <strong>$1<strong> yɔɔ:",
        "isredirect": "Kɩpɩsɩnaʋ takayɩhayʋʋ",
        "istemplate": "tɛɣʋ",
        "isimage": "takayaɣ yɔɔ kpayaɣ",
index bdcd3b8..637b2ae 100644 (file)
        "whatlinkshere": "ھیارا کیہ کیہ لنک شینی",
        "whatlinkshere-title": "لنک شدہ صفحات \"$1\"",
        "whatlinkshere-page": " صفحہ:",
-       "linkshere": " '''[[:$1]]''' درج ذیل صفحات لنک کوری شینی:",
-       "nolinkshere": "'''[[:$1]]''' کیہ روابط نیکی",
+       "linkshere-2": " '''$1''' درج ذیل صفحات لنک کوری شینی:",
+       "nolinkshere-2": "'''$1''' کیہ روابط نیکی",
        "isredirect": "خور ژاغا آلدو صفحہ",
        "istemplate": "ٹرانسکلوژن",
        "isimage": "ھوٹوان لنک",
index 02fb2a5..d1a7c01 100644 (file)
        "whatlinkshere": "Çı itay rê gırê beno",
        "whatlinkshere-title": "Pelê ke be \"$1\"i bestninê pa",
        "whatlinkshere-page": "Pele:",
-       "linkshere": "Ni pelgi '''[[:$1]]'''i asnenê:",
-       "nolinkshere": "Pelgê ke '''[[:$1]]'''i asnenê çinê.",
+       "linkshere-2": "Ni pelgi '''$1'''i asnenê:",
+       "nolinkshere-2": "Pelgê ke '''$1'''i asnenê çinê.",
        "isredirect": "pela ciheti",
        "istemplate": "ilawekerdis",
        "isimage": "girê dosya",
        "duplicate-defaultsort": "'''Teme:''' Tuşê default sort \"$2\" sero tuşê default sort \"$1\"î ra şino.",
        "fileduplicatesearch-filename": "Namê dosya:",
        "specialpages": "Pelê xaşi",
+       "specialpages-note-restricted": "* Pelê xususiyê normali.\n* <span class=\"mw-specialpagerestricted\">Pelê xususiyê mehcuri.</span>",
        "specialpages-group-maintenance": "Tebliğê baxımi",
        "specialpages-group-other": "Pelê xususiyê bini",
        "specialpages-group-login": "Cıkotene / qeyd",
index 642ad37..a94f33a 100644 (file)
        "whatlinkshere": "سىلتەلگەن بەتتەر",
        "whatlinkshere-title": "$1 دەگەنگە سىلتەلگەن بەتتەر",
        "whatlinkshere-page": "بەت:",
-       "linkshere": "'''[[:$1]]''' دەگەنگە مىنا بەتتەر سىلتەيدى:",
-       "nolinkshere": "'''[[:$1]]''' دەگەنگە ەش بەت سىلتەمەيدى.",
-       "nolinkshere-ns": "تاڭدالعان ەسىم اياسىندا '''[[:$1]]''' دەگەنگە ەشقانداي بەت سىلتەمەيدى.",
+       "linkshere-2": "'''$1''' دەگەنگە مىنا بەتتەر سىلتەيدى:",
+       "nolinkshere-2": "'''$1''' دەگەنگە ەش بەت سىلتەمەيدى.",
+       "nolinkshere-ns-2": "تاڭدالعان ەسىم اياسىندا '''$1''' دەگەنگە ەشقانداي بەت سىلتەمەيدى.",
        "isredirect": "ايداتۋ بەتى",
        "istemplate": "كىرىكبەت",
        "isimage": "سۋرەت سىلتەمەسى",
        "fileduplicatesearch-result-1": "«$1» فايلىنا تەڭ تەلنۇسقاسى جوق.",
        "fileduplicatesearch-result-n": "«$1» فايلىنا تەڭ $2 تەلنۇسقاسى بار.",
        "specialpages": "ارنايى بەتتەر",
+       "specialpages-note-restricted": "* كادىمگى ارنايى بەتتەر.\n* <strong class=\"mw-specialpagerestricted\">شەكتەلگەن ارنايى بەتتەر.</strong>",
        "specialpages-group-maintenance": "باپتاۋ باياناتتارى",
        "specialpages-group-other": "تاعى باسقا ارنايى بەتتەر",
        "specialpages-group-login": "كىرۋ / تىركەلۋ",
index 47431bc..28d497c 100644 (file)
        "whatlinkshere": "Мұнда сілтейтін беттер",
        "whatlinkshere-title": "$1 дегенге сілтейтін беттер",
        "whatlinkshere-page": "Бет:",
-       "linkshere": "'''[[:$1]]''' дегенге мына беттер сілтейді:",
-       "nolinkshere": "'''[[:$1]]''' дегенге еш бет сілтемейді.",
-       "nolinkshere-ns": "Таңдалған есім кеңістігінде '''[[:$1]]''' дегенге ешқандай бет сілтемейді.",
+       "linkshere-2": "'''$1''' дегенге мына беттер сілтейді:",
+       "nolinkshere-2": "'''$1''' дегенге еш бет сілтемейді.",
+       "nolinkshere-ns-2": "Таңдалған есім кеңістігінде '''$1''' дегенге ешқандай бет сілтемейді.",
        "isredirect": "бағыттау беті",
        "istemplate": "кіріcтірілген",
        "isimage": "файл сілтемесі",
        "fileduplicatesearch-noresults": "\"$1\" атауымен файл табылмады.",
        "specialpages": "Арнайы беттер",
        "specialpages-note-top": "Шартты белгілер",
+       "specialpages-note-restricted": "* Қалыпты арнайы беттер. \n* <span class=\"mw-specialpagerestricted\">Шектелген арнайы беттер.</span>",
        "specialpages-group-maintenance": "Техникалық талқылау есептері",
        "specialpages-group-other": "Тағы басқа арнайы беттер",
        "specialpages-group-login": "Кіру / тіркелу",
index 393d138..342339a 100644 (file)
        "whatlinkshere": "Mında silteýtin better",
        "whatlinkshere-title": "$1 degenge silteýtin better",
        "whatlinkshere-page": "Bet:",
-       "linkshere": "'''[[:$1]]''' degenge mına better silteýdi:",
-       "nolinkshere": "'''[[:$1]]''' degenge eş bet siltemeýdi.",
-       "nolinkshere-ns": "Tañdalğan esim ayasında '''[[:$1]]''' degenge eşqandaý bet siltemeýdi.",
+       "linkshere-2": "'''$1''' degenge mına better silteýdi:",
+       "nolinkshere-2": "'''$1''' degenge eş bet siltemeýdi.",
+       "nolinkshere-ns-2": "Tañdalğan esim ayasında '''$1''' degenge eşqandaý bet siltemeýdi.",
        "isredirect": "aýdatw beti",
        "istemplate": "kirikbet",
        "isimage": "swret siltemesi",
        "fileduplicatesearch-result-1": "«$1» faýlına teñ telnusqası joq.",
        "fileduplicatesearch-result-n": "«$1» faýlına teñ $2 telnusqası bar.",
        "specialpages": "Arnaýı better",
+       "specialpages-note-restricted": "* Kädimgi arnaýı better.\n* <strong class=\"mw-specialpagerestricted\">Şektelgen arnaýı better.</strong>",
        "specialpages-group-maintenance": "Baptaw bayanattarı",
        "specialpages-group-other": "Tağı basqa arnaýı better",
        "specialpages-group-login": "Kirw / tirkelw",
index 3692ed9..11c13cc 100644 (file)
        "whatlinkshere": "អ្វី​ដែលភ្ជាប់មកទីនេះ",
        "whatlinkshere-title": "ទំព័រនានាដែល​តភ្ជាប់​ទៅ \"$1\"",
        "whatlinkshere-page": "ទំព័រ៖",
-       "linkshere": "ទំព័រដូចតទៅ​នេះតភ្ជាប់មក '''[[:$1]]''' ៖",
-       "nolinkshere": "គ្មានទំព័រណាមួយតភ្ជាប់ទៅ '''[[:$1]]''' ទេ។",
-       "nolinkshere-ns": "គ្មានទំព័រណាមួយតភ្ជាប់ទៅ '''[[:$1]]''' ក្នុងប្រភេទដែលបានជ្រើសរើស។",
+       "linkshere-2": "ទំព័រដូចតទៅ​នេះតភ្ជាប់មក '''$1''' ៖",
+       "nolinkshere-2": "គ្មានទំព័រណាមួយតភ្ជាប់ទៅ '''$1''' ទេ។",
+       "nolinkshere-ns-2": "គ្មានទំព័រណាមួយតភ្ជាប់ទៅ '''$1''' ក្នុងប្រភេទដែលបានជ្រើសរើស។",
        "isredirect": "ទំព័របញ្ជូនបន្ត",
        "istemplate": "ការដាក់បញ្ចូល",
        "isimage": "តំណភ្ជាប់ឯកសារ",
        "fileduplicatesearch-noresults": "រកមិនឃើញឯកសារដែលមានឈ្មោះ \"$1\" ទេ។",
        "specialpages": "ទំព័រ​ពិសេស​ៗ",
        "specialpages-note-top": "កំណត់សម្គាល់",
+       "specialpages-note-restricted": "* ទំព័រពិសេសៗធម្មតា។\n* <span class=\"mw-specialpagerestricted\">ទំព័រពិសេសៗដែលមានការដាក់កំហិត។</span>",
        "specialpages-group-maintenance": "របាយការណ៍នានាអំពីតំហែទាំ",
        "specialpages-group-other": "ទំព័រពិសេសៗផ្សេងៗទៀត",
        "specialpages-group-login": "កត់ឈ្មោះចូល / បង្កើតគណនី",
index 5dc544e..6017c32 100644 (file)
        "whatlinkshere": "ಇಲ್ಲಿಗೆ ಯಾವ ಸಂಪರ್ಕ ಕೂಡುತ್ತದೆ",
        "whatlinkshere-title": "\"$1\" ಪುಟಕ್ಕೆ ಸಂಪರ್ಕ ಹೊಂದಿರುವ ಪುಟಗಳು",
        "whatlinkshere-page": "ಪುಟ:",
-       "linkshere": "'''[[:$1]]'''ಗೆ ಈ ಪುಟಗಳು ಸಂಪರ್ಕ ಹೊಂದಿವೆ:",
-       "nolinkshere": "'''[[:$1]]''' ಗೆ ಯಾವ ಪುಟಗಳೂ ಸಂಪರ್ಕ ಹೊಂದಿಲ್ಲ.",
-       "nolinkshere-ns": "ಆಯ್ಕೆ ಮಾಡಿದ ಪುಟಪ್ರಬೇಧದಲ್ಲಿ ಯಾವ ಪುಟವೂ '''[[:$1]]''' ಅಲ್ಲಿಗೆ ಸಂಪರ್ಕ ಹೊಂದಿಲ್ಲ.",
+       "linkshere-2": "'''$1'''ಗೆ ಈ ಪುಟಗಳು ಸಂಪರ್ಕ ಹೊಂದಿವೆ:",
+       "nolinkshere-2": "'''$1''' ಗೆ ಯಾವ ಪುಟಗಳೂ ಸಂಪರ್ಕ ಹೊಂದಿಲ್ಲ.",
+       "nolinkshere-ns-2": "ಆಯ್ಕೆ ಮಾಡಿದ ಪುಟಪ್ರಬೇಧದಲ್ಲಿ ಯಾವ ಪುಟವೂ '''$1''' ಅಲ್ಲಿಗೆ ಸಂಪರ್ಕ ಹೊಂದಿಲ್ಲ.",
        "isredirect": "ಪುನರ್ನಿರ್ದೇಶನ ಪುಟ",
        "istemplate": "ಸೇರ್ಪಡೆ",
        "isimage": "ಚಿತ್ರಕ್ಕೆ ಕೊಂಡಿ",
index 1b89991..ab3733a 100644 (file)
@@ -70,7 +70,8 @@
                        "렌즈",
                        "CYAN",
                        "Nuevo Paso",
-                       "Doyoon1995"
+                       "Doyoon1995",
+                       "Jay94ks"
                ]
        },
        "tog-underline": "링크에 밑줄 긋기:",
        "subject-preview": "주제 미리 보기:",
        "previewerrortext": "변경사항을 미리보기하는 도중 오류가 발생했습니다.",
        "blockedtitle": "사용자가 차단됨",
-       "blockedtext": "'''사용자 계정 또는 IP 주소가 차단되었습니다.'''\n\n차단한 사람은 $1입니다.\n차단한 이유는 다음과 같습니다: $2\n\n* 차단이 시작된 시간: $8\n* 차단이 끝나는 시간: $6\n* 차단된 사용자: $7\n\n$1 또는 [[{{MediaWiki:Grouppage-sysop}}|다른 관리자]]에게 차단에 대해 문의할 수 있습니다.\n[[Special:Preferences|계정 환경 설정]]에 올바른 이메일 주소가 있어야만 '이메일 보내기' 기능을 사용할 수 있습니다. 또 이메일 보내기 기능이 차단되어 있으면 이메일을 보낼 수 없습니다.\n현재 당신의 IP 주소는 $3이고, 차단 ID는 #$5입니다.\n문의할 때에 이 정보를 같이 알려주세요.",
-       "autoblockedtext": "당신의 IP 주소는 $1님이 차단한 사용자가 사용했던 IP이기 때문에 자동으로 차단되었습니다.\n차단된 이유는 다음과 같습니다:\n\n:$2\n\n* 차단이 시작된 시간: $8\n* 차단이 끝나는 시간: $6\n* 차단된 사용자: $7\n\n$1 또는 [[{{MediaWiki:Grouppage-sysop}}|다른 관리자]]에게 차단에 대해 문의할 수 있습니다.\n\n[[Special:Preferences|사용자 환경 설정]]에 올바른 이메일 주소가 있어야만 \"이메일 보내기\" 기능을 사용할 수 있습니다. 또한 이메일 보내기 기능이 차단되어 있으면 이메일을 보낼 수 없습니다.\n\n현재 IP 주소는 $3이고, 차단 ID는 #$5입니다.\n문의할 때에 이 정보를 같이 알려주세요.",
+       "blockedtext": "'''사용자 계정 또는 IP 주소가 차단되었습니다.'''\n\n차단한 사람은 $1입니다.\n차단한 이유는 다음과 같습니다: <em>$2</em>.\n\n* 차단이 시작된 시간: $8\n* 차단이 끝나는 시간: $6\n* 차단된 사용자: $7\n\n$1 또는 [[{{MediaWiki:Grouppage-sysop}}|다른 관리자]]에게 차단에 대해 문의할 수 있습니다.\n[[Special:Preferences|계정 환경 설정]]에 올바른 이메일 주소가 있어야만 '이메일 보내기' 기능을 사용할 수 있습니다. 또 이메일 보내기 기능이 차단되어 있으면 이메일을 보낼 수 없습니다.\n현재 당신의 IP 주소는 $3이고, 차단 ID는 #$5입니다.\n문의할 때에 이 정보를 같이 알려주세요.",
+       "autoblockedtext": "당신의 IP 주소는 $1님이 차단한 사용자가 사용했던 IP이기 때문에 자동으로 차단되었습니다.\n차단된 이유는 다음과 같습니다:\n\n:<em>$2</em>\n\n* 차단이 시작된 시간: $8\n* 차단이 끝나는 시간: $6\n* 차단된 사용자: $7\n\n$1 또는 [[{{MediaWiki:Grouppage-sysop}}|다른 관리자]]에게 차단에 대해 문의할 수 있습니다.\n\n[[Special:Preferences|사용자 환경 설정]]에 올바른 이메일 주소가 있어야만 \"이메일 보내기\" 기능을 사용할 수 있습니다. 또한 이메일 보내기 기능이 차단되어 있으면 이메일을 보낼 수 없습니다.\n\n현재 IP 주소는 $3이고, 차단 ID는 #$5입니다.\n문의할 때에 이 정보를 같이 알려주세요.",
        "systemblockedtext": "당신의 사용자 이름 또는 IP 주소가 자동으로 미디어위키에 의해 차단되었습니다.\n이유는 다음과 같습니다:\n\n:<em>$2</em>\n\n* 차단 시작: $8\n* 차단 만료: $6\n* 차단 대상: $7\n\n당신의 현재 IP 주소는 $3입니다.\n문의에 대해 상기의 상세 설명을 모두 포함해 주십시오.",
        "blockednoreason": "이유를 입력하지 않음",
        "whitelistedittext": "문서를 편집하기 전에 $1해야 합니다.",
        "uploadstash-bad-path-bad-format": "\"$1\" 키는 적절한 포맷이 아닙니다.",
        "uploadstash-file-not-found": "저장소에서 \"$1\" 키를 찾지 못했습니다.",
        "uploadstash-file-not-found-no-thumb": "섬네일을 가져오지 못했습니다.",
+       "uploadstash-file-not-found-no-local-path": "썸네일을 가르키는 로컬 경로가 없습니다.",
        "uploadstash-file-not-found-no-object": "섬네일을 위한 로컬 파일 객체를 만들 수 없습니다.",
        "uploadstash-file-not-found-no-remote-thumb": "섬네일 가져오기를 실패했습니다: $1\nURL = $2",
        "uploadstash-file-not-found-missing-content-type": "content-type 헤더가 없습니다.",
        "protectedtitles-submit": "제목 표시",
        "listusers": "사용자 목록",
        "listusers-editsonly": "기여가 있는 사용자만 보기",
+       "listusers-temporarygroupsonly": "임시 사용자 그룹의 사용자만 표시",
        "listusers-creationsort": "계정을 만든 날짜순으로 정렬",
        "listusers-desc": "내림차순으로 정렬",
        "usereditcount": "{{PLURAL:$1|편집}} $1회",
        "apisandbox-dynamic-parameters-add-label": "변수 추가:",
        "apisandbox-dynamic-parameters-add-placeholder": "변수 이름",
        "apisandbox-dynamic-error-exists": "\"$1\"이라는 변수 이름은 이미 존재합니다.",
+       "apisandbox-templated-parameter-reason": "이 [[Special:ApiHelp/main#main/templatedparams|템플릿 매개 변수]]는 $2의 {{PLURAL:$1|value|values}}에 따라 제공됩니다.",
        "apisandbox-deprecated-parameters": "앞으로 제거될 변수",
        "apisandbox-fetch-token": "토큰 자동 채우기",
        "apisandbox-add-multi": "추가",
        "whatlinkshere": "여기를 가리키는 문서",
        "whatlinkshere-title": "\"$1\" 문서를 가리키는 문서 목록",
        "whatlinkshere-page": "문서:",
-       "linkshere": "다음 문서가 '''[[:$1]]''' 문서를 가리키고 있습니다:",
-       "nolinkshere": "'''[[:$1]]''' 문서를 가리키는 문서가 없습니다.",
-       "nolinkshere-ns": "선택한 이름공간에는 '''[[:$1]]''' 문서를 가리키는 문서가 없습니다.",
+       "linkshere-2": "다음 문서가 '''$1''' 문서를 가리키고 있습니다:",
+       "nolinkshere-2": "'''$1''' 문서를 가리키는 문서가 없습니다.",
+       "nolinkshere-ns-2": "선택한 이름공간에는 '''$1''' 문서를 가리키는 문서가 없습니다.",
        "isredirect": "넘겨주기 문서",
        "istemplate": "끼워넣기",
        "isimage": "연결된 파일",
        "pagedata-title": "문서 데이터",
        "pagedata-text": "이 문서는 문서에 대한 데이터 인터페이스를 제공합니다. 하위 문서 문법을 사용하여 URL에 문서 제목을 지정해 주십시오.\n* 클라이언트의 Accept 헤더에 기반하여 내용이 절충됩니다. 즉, 문서 데이터는 클라이언트가 선호하는 형식으로 제공됩니다.",
        "pagedata-not-acceptable": "일치하는 형식을 찾을 수 없습니다. 지원하는 MIME 형식: $1",
-       "pagedata-bad-title": "유효하지 않은 제목: $1."
+       "pagedata-bad-title": "유효하지 않은 제목: $1.",
+       "unregistered-user-config": "보안을 이유로 자바스크립트, CSS, JSON 사용자 하위 문서들은 비등록 사용자에게는 불러올 수 없습니다.",
+       "passwordpolicies": "비밀번호 정책",
+       "passwordpolicies-summary": "이것은 이 위키에 정의된 사용자 그룹을 위해 시행 중인 비밀번호 정책 목록입니다.",
+       "passwordpolicies-group": "그룹",
+       "passwordpolicies-policies": "정책",
+       "passwordpolicies-policy-minimalpasswordlength": "비밀번호는 적어도 $1 {{PLURAL:$1|자}}여야 합니다",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "로그인하려면 비밀번호는 적어도 {{PLURAL:$1|자}}여야 합니다",
+       "passwordpolicies-policy-passwordcannotmatchusername": "비밀번호는 사용자 이름과 같을 수 없습니다",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "비밀번호는 블랙리스트에 있는 비밀번호와 일치할 수 없습니다",
+       "passwordpolicies-policy-maximalpasswordlength": "비밀번호는 적어도 $1 {{PLURAL:$1|자}} 미만이어야 합니다",
+       "passwordpolicies-policy-passwordcannotbepopular": "비밀번호는 {{PLURAL:$1|저명한 비밀번호가 될|$1개의 저명한 비밀번호에 속할}} 수 없습니다"
 }
index 4944409..5cc99c4 100644 (file)
        "whatlinkshere": "Бетге джибериуле",
        "whatlinkshere-title": "«$1» бетге джиберген бетле",
        "whatlinkshere-page": "Бет:",
-       "linkshere": "'''[[:$1]]''' битге джиберген бетле:",
-       "nolinkshere": "'''[[:$1]]'' бетге башха бетле джибермейдиле.",
-       "nolinkshere-ns": "Сайланнган атла аламда '''[[:$1]]''' бетге джиберген бет джокъду.",
+       "linkshere-2": "'''$1''' битге джиберген бетле:",
+       "nolinkshere-2": "'''$1'' бетге башха бетле джибермейдиле.",
+       "nolinkshere-ns-2": "Сайланнган атла аламда '''$1''' бетге джиберген бет джокъду.",
        "isredirect": "джибериу бет",
        "istemplate": "къошуу",
        "isimage": "файлгъа джибериу",
        "fileduplicatesearch-result-n": "«$1» файлны {{PLURAL:$2|1 келишген дубликаты|$2 келишген дубликаты}} барды.",
        "fileduplicatesearch-noresults": "«$1» деген файл табылмады.",
        "specialpages": "Къуллукъ бетле",
+       "specialpages-note-restricted": "* Тюз къуллукъ бетле.\n* <span class=\"mw-specialpagerestricted\">Кирирге эркинлик чекленнген къуллукъ бетле.</span>",
        "specialpages-group-maintenance": "Техника баджарыуну отчетлары",
        "specialpages-group-other": "Башха къуллукъ бетле",
        "specialpages-group-login": "Системагъа кириу / Аккаунт къурау",
index 53ba8e9..b00dfbe 100644 (file)
        "whatlinkshere": "Linkit tänne",
        "whatlinkshere-title": "Šivut, kumpaset viitatah šivulla \"$1\"",
        "whatlinkshere-page": "Šivu:",
-       "linkshere": "Šeuruavilta šivuilta on linkki šivulla <strong>[[:$1]]</strong>:",
+       "linkshere-2": "Šeuruavilta šivuilta on linkki šivulla <strong>$1</strong>:",
        "isredirect": "ohjauššivu",
        "istemplate": "šisällytetty",
        "isimage": "failin linkki",
index 9f5d0c6..52ad3d1 100644 (file)
        "whatlinkshere": "Wat noh heh link",
        "whatlinkshere-title": "Sigge, woh Lengks op „$1“ dren sen",
        "whatlinkshere-page": "Sigg:",
-       "linkshere": "Dat sin de Sigge, di op <strong>„[[:$1]]“</strong> lengke donn:",
-       "nolinkshere": "Kein Sigg link noh <strong>„[[:$1]]“</strong>.",
-       "nolinkshere-ns": "Nix link op <strong>„[[:$1]]“</strong> en dämm Appachtemang.",
+       "linkshere-2": "Dat sin de Sigge, di op <strong>„$1“</strong> lengke donn:",
+       "nolinkshere-2": "Kein Sigg link noh <strong>„$1“</strong>.",
+       "nolinkshere-ns-2": "Nix link op <strong>„$1“</strong> en dämm Appachtemang.",
        "isredirect": "Ömleidongssigg",
        "istemplate": "weed enjeföch",
        "isimage": "weed aanjezeisch",
        "fileduplicatesearch-noresults": "Mer han kein Dattei met däm Name „$1“ jefonge.",
        "specialpages": "{{int:nstab-special}}e",
        "specialpages-note-top": "Lejänd",
+       "specialpages-note-restricted": "* Jewöhnlejje {{int:nstab-special}}e för jede Metmaacher.\n* <span class=\"mw-specialpagerestricted\">{{int:nstab-special}}e bloß för Metmaacher met besönder Räächde.</span>",
        "specialpages-group-maintenance": "Waadungsleste",
        "specialpages-group-other": "Ander {{int:nstab-special}}e",
        "specialpages-group-login": "Enlogge udder Aanmälde",
index be47741..68ded3d 100644 (file)
        "whatlinkshere": "Girêdanên li ser vê rûpelê",
        "whatlinkshere-title": "Rûpelên ku yê berve \"$1\" tên",
        "whatlinkshere-page": "Rûpel:",
-       "linkshere": "Ev rûpel tên ser vê rûpelê '''[[:$1]]''':",
-       "nolinkshere": "Ne ji rûpelekê lînk tên ser '''[[:$1]]'''.",
-       "nolinkshere-ns": "Ne lînkek berve '''[[:$1]]''' di vê namespace'a da tê.",
+       "linkshere-2": "Ev rûpel tên ser vê rûpelê '''$1''':",
+       "nolinkshere-2": "Ne ji rûpelekê lînk tên ser '''$1'''.",
+       "nolinkshere-ns-2": "Ne lînkek berve '''$1''' di vê namespace'a da tê.",
        "isredirect": "rûpelê beralî bike",
        "istemplate": "tê bikaranîn",
        "isimage": "girêdana wêneyî",
        "fileduplicatesearch-filename": "Navê dosyeyê:",
        "fileduplicatesearch-submit": "Lê bigere",
        "specialpages": "Rûpelên taybet",
+       "specialpages-note-restricted": "* Rûpelên taybetî ji her kesan ra\n* <strong class=\"mw-specialpagerestricted\">Rûpelên taybetî ji bikarhêneran bi mafên zêdetir ra</strong>",
        "specialpages-group-other": "Rûpelên taybetî yên din",
        "specialpages-group-login": "Têkeve / hesabekî nû çêke",
        "specialpages-group-changes": "Guherandinên dawî û têketin",
index ef6e8ab..80dd77c 100644 (file)
@@ -68,6 +68,8 @@
        "october-date": "Байсан $1",
        "november-date": "Маййилик $1",
        "december-date": "Тунлу $1",
+       "period-am": "ТБ",
+       "period-pm": "ТС",
        "pagecategories": "{{PLURAL:$1|Категория|Категориялар}}‎",
        "category_header": "\"$1\" категориядан сагьифалар",
        "subcategories": "Субкатегориялар",
        "jumpto": "Мунда гёчмек:",
        "jumptonavigation": "навигация",
        "jumptosearch": "излев",
+       "pool-errorunknown": "Белгисиз янгылыш",
        "poolcounter-usage-error": "Къоллав хата: $1",
        "aboutsite": "{{SITENAME}} гьакъында",
        "aboutpage": "Project:Сыпатлав",
        "helppage-top-gethelp": "Кёмек",
        "mainpage": "Баш Сагьифа",
        "mainpage-description": "Баш сагьифа",
+       "policy-url": "Project:Къайдалар",
        "portal": "Бирлешив портал",
        "portal-url": "Project:Бирлешив портал",
        "privacy": "Энчилилик ёругъу",
        "privacypage": "Project:Конфиденциаллыкъ сиясаты",
+       "badaccess": "Гириш хатасы",
        "ok": "OK",
        "retrievedfrom": "Чыкъмагъы — «$1»",
        "youhavenewmessages": "{{PLURAL:$3|Сен алдынг}} $1 ($2).",
        "confirmable-confirm": "{{GENDER:$1|сен}} аминмисен?",
        "confirmable-yes": "Дюр",
        "confirmable-no": "Ёкъ",
+       "viewdeleted": "Къарамакъмы $1?",
        "feedlinks": "Агъыш",
+       "site-rss-feed": "$1 RSS агъым",
        "site-atom-feed": "$1 Atom агъышы",
+       "page-rss-feed": "\"$1\" RSS агъым",
        "page-atom-feed": "\"$1\" Atom агъышы",
        "red-link-title": "$1 (олай сагьифасы ёкъдур)",
+       "sort-descending": "Кемивюне гёре тизмек",
+       "sort-ascending": "Артывуна гёре тизмек",
        "nstab-main": "Макъала",
        "nstab-user": "Къоллавчу сагьифасы",
        "nstab-special": "Хас сагьифа",
        "nstab-help": "Кёмек сагьифа",
        "nstab-category": "Категория",
        "mainpage-nstab": "Баш сагьифа",
+       "nosuchaction": "Булай гьаракат ёкъ",
        "nosuchspecialpage": "Олай хас сагьифасы ёкъдур",
        "nospecialpagetext": "<strong>Сен талап этген хас сагьифа ёкъ.</strong>\n\nДурус хас сагьифалар булан тизме мунда: [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "Хата",
+       "databaseerror-query": "Талап: $1",
        "databaseerror-function": "Функция: $1",
        "databaseerror-error": "Хата: $1",
+       "missingarticle-rev": "(тюрю № $1)",
+       "missingarticle-diff": "(Башгъалыгъы: $1, $2)",
        "internalerror": "Ичдеги хата",
+       "internalerror_info": "Ичдеги хата: $1",
        "badtitle": "Къыйышмайгъан ат",
        "badtitletext": "Чакъырылгъан сагьифаны аты бузукъ эди, яда бош, яда тил-ара яда вики-ара байланывлары янгылыш кюйде берилген эди.\nБалики, атында бир-эки ярамайгъан гьарп берилген эди.",
        "viewsource": "Кюрчю кодуна къарамакъ",
        "viewsource-title": "$1 сагьифаны аслу текстине къарамакъ",
        "viewsourcetext": "Бу сагьифаны аслу кодуна къарап ва ону кёплеп боласан.",
+       "welcomeuser": "Хош гединг, $1!",
+       "yourname": "Къоллавчу аты",
        "userlogin-yourname": "Къоллавчу аты",
        "userlogin-yourname-ph": "Гьисабынгны атын бер",
+       "yourpassword": "Чечил:",
        "userlogin-yourpassword": "Чечил",
        "userlogin-yourpassword-ph": "Чечилингни бер",
        "createacct-yourpassword-ph": "Чечилингни бер",
        "createacct-yourpasswordagain-ph": "Чечилингни янгыдан бер",
        "userlogin-remembermypassword": "Мени къайытлы сакъламакъ",
        "login": "Гирмек",
+       "logout": "Чыкъмакъ",
+       "userlogout": "Чыкъмакъ",
        "userlogin-noaccount": "Бир бет ёкъму?",
        "userlogin-joinproject": "{{SITENAME}} проектни ортакъчы болмакъ",
        "createaccount": "Янгы бет этмек",
        "userlogin-resetpassword-link": "Чечилингни унутгъанмысан?",
        "userlogin-helplink2": "Гириш саялы кёмек",
+       "createacct-emailrequired": "Поч ерлешими",
        "createacct-emailoptional": "Электрон почну ерлешими (гёнгюллю)",
        "createacct-email-ph": "Электрон почну ерлешимин бер",
+       "createacct-another-email-ph": "Электрон почну ерлешимин бер",
+       "createacct-realname": "Герти ат (истесенг)",
+       "createacct-reason": "Себеп",
        "createacct-submit": "Бетинг яса",
+       "createacct-another-submit": "Гьисап бет ачмакъ",
        "createacct-benefit-heading": "{{SITENAME}} сени йимик адамланы ортакъ загьматы.",
        "createacct-benefit-body1": "{{PLURAL:$1|тюзлев}}",
        "createacct-benefit-body2": "{{PLURAL:$1|сагьифа|сагьифалар}}",
        "pt-login-button": "Гирмек",
        "pt-createaccount": "Янгы бет этмек",
        "pt-userlogout": "Чыкъмакъ",
+       "changepassword": "Чечил алышдырыв",
+       "oldpassword": "Эсги чечил:",
+       "newpassword": "Янгы чечил:",
+       "botpasswords-label-create": "Яратмакъ",
+       "botpasswords-label-update": "Янгыртмакъ",
+       "botpasswords-label-cancel": "Гери алыв",
+       "botpasswords-label-delete": "Тайдырмакъ",
+       "botpasswords-label-resetpassword": "Чечилни янгыдан бегетмек",
+       "resetpass-submit-loggedin": "Чечил алышдырыв",
+       "resetpass-submit-cancel": "Гери алыв",
        "passwordreset": "Чечилни янгыдан бегетмек",
+       "passwordreset-username": "Къоллавчу аты",
+       "changeemail-none": "(ёкъ)",
        "bold_sample": "Къалын матын",
        "bold_tip": "Къалын матын",
        "italic_sample": "Авункъу матын",
        "minoredit": "Увакъ тюзлев",
        "watchthis": "Бу сагьифаны гьызарламакъ",
        "savearticle": "Сагьифаны сакъламакъ",
+       "savearticle-start": "Сагьифаны сакъламакъ",
+       "savechanges-start": "Алышынывланы сакъламакъ",
        "preview": "Ингкъарав",
        "showpreview": "Ингкъарав",
        "showdiff": "Тюзлевлени гёрсетмек",
        "anoneditwarning": "<strong>Тергев:</strong> Сен гириш этмединг. Тюзлевлер этсенг сени IP адресинг публикли гёрюнер. Эгер <strong>[$1 гириш]</strong> яда <strong>[$2 къайыт]</strong> этсенг, тюзлевлеринг сени ортакъчы аты булан гьисап этилер, оьзге пайдалардан да къайры.",
        "blockedtext": "Сени къоллавчу атынг яда IP адресинг къамалгъан эди.''\n\nКъамав этген $1 ($2).\nСебеп берилген: ''$3'.\n\n* Къамав башлады: $4\n* Къамав бите: $5\n* Къамавну мурады: $7\n\n$1 булан яда къайсы оьзге [[{{MediaWiki:Grouppage-sysop}}|администратор]] булан къатнап къамавну гьакъында сёйлешмеге боласан.\nТергеп къой, сени [[Special:Preferences|энчили кюйлемлерингде]] e-mail адресинг тюз бермединг буса яда герти этмединг буса, яда къамав шартлагъа мактуп язывуну къадагъа гире буса, \"къоллавчугъа мактуп\" функцияны къоллап болмассан.\nСени IP адресинг — $3, къамавну идентификатору — $5. Тилев, бу маълюматланы бары талапларынга гийир.",
        "loginreqlink": "гирмек",
+       "newarticle": "(Янгы)",
        "newarticletext": "Сен гьалиде яратылмагъан сагьифагъа гёчдинг.\nБу сагьифаны яратмакъ учун, тюбюндеги къутугъунда язып башлагъыз (артыкъ маълюмат учун [$1 кёмек сагьифагъа] къара).\nЯнгылыш этип бери гёчген бусанг, сени браузеринг <strong>артгъа</strong> тюймесине бас.",
        "anontalkpagetext": "<em>Бу гьали де бет яратмагъан яда бетин къолламайгъан аноним къоллавчуну учун сёйлешив.</em>\nШолай буса биз ону белгилемек учун санавлу IP адресни пайдаламакъ герекбиз.\nБу IP адрес бир нече къоллавчуланы арасында пайланып турмагъа бола.\nСен аноним къоллавчу бусанг, ва сагъа тюгюл язывлар бакъдырылгъан деп ойлаша бусанг, тилев, [[Special:CreateAccount|янгы бет ярат]] яда [[Special:UserLogin|гириш эт]], гележекде оьзге аноним къоллавчулар булан сен къарашыкъ болмас учун.",
        "noarticletext": "Бу сагьифа гьали де матынсыз. Сен башгъа сагьифаларда [[Special:Search/{{PAGENAME}}|булай атын эсгеривлерини излемеге]]  боласан, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} тийишли гюнделик язывланы тапмагъа] яда '''[{{fullurl:{{FULLPAGENAME}}|action=edit}} булай аты булан сагьифа яратмагъа боласан]'''</span>.",
        "noarticletext-nopermission": "Бу сагьифа гьали де текстсиз. Сен башгъа сагьифаларда [[Special:Search/{{PAGENAME}}|булай атын эсгеривлерини излемеге]], яда <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} тийишли гюнделиклени тапмагъа боласан]. </span> Тек бу сагьифаны яратмагъа ихтиярынг ёкъ.",
        "userpage-userdoesnotexist-view": "\"$1\" гьисап къайытланмагъан.",
        "clearyourcache": "<strong>Note:</strong> Сакълангъан сонг, тюрлевлени гёрмек саялы сагъа браузерингни кэшин янгыртмагъа яда тазаламагъа герек болма бола \n* <strong>Firefox / Safari:</strong> <em>Shift</em> тутуп <em>Reload</em> бас, башгъалай <em>Ctrl-F5</em> яда <em>Ctrl-R</em> бас (Mac буса <em>⌘-R</em>)\n* <strong>Google Chrome:</strong> <em>Ctrl-Shift-R</em> бас(Mac буса <em>⌘-Shift-R</em>)\n* <strong>Internet Explorer:</strong> <em>Ctrl</em> тутуп <em>Refresh</em> бас, яда <em>Ctrl-F5</em> бас\n* <strong>Opera:</strong> <em>Menu → Settings</em> бёлмеге гёч (Mac буса <em>Opera → Preferences</em>) ва сонг <em>Privacy & security → Clear browsing data → Cached images and files</em>.",
+       "updated": "(Янгыртылгъан)",
        "previewnote": "<strong>Бу ингкъарав экенни эсде сакъла.</strong>\nАлышынывларынг гьали де сакъланмагъан!",
        "continue-editing": "Тюзлевню давамламакъ",
        "editing": "Тюзлев $1",
        "creating": "$1 сагьифасын ясаву",
        "editingsection": "Тюзлев: $1 (бёлме)",
+       "yourtext": "Текстинг",
+       "yourdiff": "Башгъалыкълар",
        "templatesused": "Бу сагьифада къоллангъан {{PLURAL:$1|къалип|къалиплер}}",
        "templatesusedpreview": "Бу инггёрсетивде пайдалангъан {{PLURAL:$1|уьлгюлер|}}:",
        "template-protected": "(къоругъан)",
        "recreate-moveddeleted-warn": "<strong>Тергев бер: Алдын тайдырылгъан сагьифаны ярашдырма айланасан.</strong>\n\nБашлап тергеп къара, гертиден де тарыкъмы экен ол сагьифаны ярашдырмагъа.\nТайдырыв ва атын алышдырыв гюнделиги тюпде берилген:",
        "moveddeleted-notice": "Бу сагьифа тайдырылгъан эди.\nБу сагьифаны тайдырыв, къорув ва атянгыртыв гюнделиги маълюмат саялы тюпде гёрсетилген.",
        "content-model-wikitext": "викиматын",
+       "content-model-javascript": "JavaScript",
        "undo-failure": "Аралыкъ алышынывланы къыйышывсызлгъы учун тюзлев гери алынмай.",
        "viewpagelogs": "Бу сагьифа учун гюнделиклени гёрсетмек",
        "currentrev-asof": "Ахырынчы тюрю $1 тархда",
        "nextrevision": "Сонггъу тюрю →",
        "currentrevisionlink": "Ахырынчы тюрю",
        "cur": "гьал.",
+       "next": "гелеген",
        "last": "ингкъ.",
+       "page_first": "биринчи",
+       "page_last": "ахырынчы",
        "histlegend": "Тюзлевлерден сайлав: тенглешдирмеге сюеген бары тюрлерин белгилеп '''{{int:compare-submit}}''' бас.<br />\nАчыкълавлар: '''({{int:cur}})''' — гьалиги тюрюнден башгъалыкъ; '''({{int:last}})''' — алдагъы тюрюнден башгъалыкъ; '''{{int:minoreditletter}}''' — увакъ тюзелтив.",
        "history-fieldset-title": "Тюзлевлеге излев",
        "histfirst": "инг эсгилер",
        "histlast": "инг янгылар",
+       "historyempty": "(бош)",
        "history-feed-title": "Тюзлевлер тарихи",
        "history-feed-description": "Бу сагьифаны викиде тюзлев тарихи",
        "history-feed-item-nocomment": "$1 $2 заманда",
        "rev-delundel": "гёрсетмек/яшырмакъ",
+       "rev-showdeleted": "гёрсетмек",
+       "revdelete-show-file-submit": "Дюр",
+       "revdelete-radio-same": "(алышдырмамакъ)",
+       "revdelete-radio-set": "Яшырылгъан",
+       "revdelete-log": "Себеп:",
+       "pagehist": "Сагьифа тарихи",
+       "deletedhist": "Тайдырыв тарихи",
+       "revdelete-reasonotherlist": "Башгъа себеп",
+       "mergehistory-reason": "Себеп:",
        "mergelog": "Бирлешдирив гюнделиги",
+       "revertmerge": "Бёлмек",
        "history-title": "\"$1\" тюзлев тарихи",
        "difference-title": "Тюрлени арасында башгъалыгъы \"$1\"",
        "lineno": "Сатыр: $1",
        "searchresults-title": "\"$1\" учун натижаланы излемек",
        "prevn": "алдагъы {{PLURAL:$1|$1}}",
        "nextn": "сонггъу {{PLURAL:$1|$1}}",
+       "prev-page": "алдагъы сагьифа",
+       "next-page": "гелеген сагьифа",
        "prevn-title": "Алдагъы $1 {{PLURAL:$1|гьасил}}",
        "nextn-title": "Гелеген $1 {{PLURAL:$1|гьасил|гьасиллер}}",
        "shown-title": "Айры бир сагьифада $1 {{PLURAL:$1|языв|язывланы}} гёрсетмек",
        "search-result-category-size": "{{PLURAL:$1|1 ортакъчы|$1 ортакъчы}} ({{PLURAL:$2|1 тюп категория|$2 тюп категория}}, {{PLURAL:$3|1 саплам|$3 саплам}})",
        "search-redirect": "($1 сагьифадан бакъдырылгъан)‎",
        "search-section": "($1 бёлме)",
+       "search-category": "(категория $1)",
        "search-file-match": "(сапламны ичделигине рас геле)",
        "search-suggest": "Буну ойлаймысан экен: $1",
+       "search-interwiki-more": "(дагъы)",
+       "search-interwiki-more-results": "дагъы да натижалар",
+       "search-relatedarticle": "Байлавлу",
+       "searchrelated": "байлавлу",
        "searchall": "бары да",
        "search-showingresults": "{{PLURAL:$4|<strong>$1</strong> натижа <strong>$3</strong> натижалардан|<strong>$1 – $2</strong> натижа <strong>$3</strong> натижалардан}}",
        "search-nonefound": "Бу талапгъа тийишли натижалар табулмады.",
+       "powersearch-legend": "Генглешген излев",
+       "powersearch-toggleall": "Тюм",
+       "powersearch-togglenone": "Ёкъ",
        "mypreferences": "Кюйлемлер",
+       "skin-preview": "Ингкъарав",
+       "prefs-user-pages": "Къоллавчу сагьифасы",
+       "prefs-watchlist": "Гьызарлав тизмеси",
+       "saveprefs": "Сакъламакъ",
+       "prefs-editing": "Тюзлев",
+       "searchresultshead": "Излев",
+       "stub-threshold-sample-link": "уьлгю",
+       "stub-threshold-disabled": "Сёнген",
+       "timezoneregion-asia": "Азия",
+       "timezoneregion-europe": "Авропа",
+       "prefs-searchoptions": "Излев",
+       "prefs-namespaces": "Атлар аралыгъы",
+       "prefs-files": "Сапламлар",
+       "youremail": "Эмейл:",
+       "group-membership-link-with-expiry": "$1 ($2 ерли)",
+       "yourrealname": "Герти аты:",
+       "yourlanguage": "Тил:",
+       "yournick": "Янгы къолбас",
+       "email": "Эмейл",
+       "prefs-signature": "Къолбас",
+       "prefs-preview": "Ингкъарав",
+       "editusergroup": "Ортакъчына гюплерин юклемек",
+       "group": "Гюп:",
+       "group-user": "Къоллавчулар",
        "group-bot": "Ботлар",
        "group-sysop": "Юрютювчилер",
+       "group-all": "(тюм)",
+       "grouppage-user": "{{ns:project}}:Къоллавчулар",
        "grouppage-bot": "{{ns:project}}:Ботлар",
        "grouppage-sysop": "{{ns:project}}:Башчылар",
+       "right-read": "Сагьифа охув",
+       "right-edit": "Сагьифа тюзлев",
        "right-writeapi": "Языв учун API‎ къоллав",
+       "right-delete": "Сагьифа тайдырыв",
        "newuserlogpage": "Янгы къоллавчу тизме гюнделиги",
        "rightslog": "Ортакъчы ихтиярларын гюнделиги",
+       "action-read": "бу сагьифаны охув",
        "action-edit": "бу сагьифаны тюзлемек",
+       "action-createpage": "бу сагьифаны яратмакъ",
        "action-createaccount": "бу гьисапны яратыву",
        "enhancedrc-history": "тарих",
        "recentchanges": "Яп-янгы тюзлевлер",
        "recentchanges-label-plusminus": "Сагьифаны гёлеми шунчакъы байт булан алышынгъан",
        "recentchanges-legend-heading": "<strong>Уйдурма:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (шунда да  [[Special:NewPages|янгы сагьифаланы сиягьына къарагъыз]])",
+       "recentchanges-submit": "Гёрсетмек",
+       "rcfilters-savedqueries-rename": "Атын алышдырмакъ",
+       "rcfilters-savedqueries-remove": "Тайдырмакъ",
+       "rcfilters-savedqueries-new-name-label": "Ат",
+       "rcfilters-savedqueries-cancel-label": "Гери алыв",
+       "rcfilters-filterlist-title": "Сюзгючлер",
+       "rcfilters-highlightmenu-title": "Тюсюн сайламакъ",
+       "rcfilters-filter-user-experience-level-learner-label": "Охуйгъанлар",
+       "rcfilters-filter-bots-label": "Бот",
        "rcnotefrom": "Тюбюндеги — <strong>$3, $4</strong> гюнден берли {{PLURAL:$5|тюзлевюдюр|тюзлевлеридир}}.",
        "rclistfrom": "$2, $3 тюзлевлерден башлап гёрсетмек",
        "rcshowhideminor": "$1 увакъ тюзлевлер",
        "rcshowhideanons-show": "Гёрсетмек",
        "rcshowhideanons-hide": "Яшырмакъ",
        "rcshowhidepatr": "$1 тергелген тюзлевлер",
+       "rcshowhidepatr-show": "Гёрсетмек",
+       "rcshowhidepatr-hide": "Яшырмакъ",
        "rcshowhidemine": "$1 мени тюзлевлерим",
        "rcshowhidemine-show": "Гёрсетмек",
        "rcshowhidemine-hide": "Яшырмакъ",
+       "rcshowhidecategorization-show": "Гёрсетмек",
+       "rcshowhidecategorization-hide": "Яшырмакъ",
        "rclinks": "Ахырынчы $2 гюнню ичинде ахырынчы $1 тюзлевню гёрсетмек",
        "diff": "алыш.",
        "hist": "тарих",
        "recentchangeslinked-page": "Сагьифаны аты:",
        "recentchangeslinked-to": "Къайта, бу сагьифагъа байлавлу сагьифаланы алышынывларын гёрсетмек",
        "upload": "Сапламны юклемек",
+       "uploadbtn": "Сапламны юклемек",
        "uploadlogpage": "Юклев журналы",
+       "filename": "Сапламны аты",
        "filedesc": "Къысгъартылым",
+       "fileuploadsummary": "Къысгъартылым:",
+       "filesource": "Эник:",
+       "upload-dialog-button-cancel": "Гери алыв",
+       "upload-dialog-button-back": "Артгъа",
+       "upload-dialog-button-done": "Гьазир",
+       "upload-dialog-button-save": "Сакъламакъ",
+       "upload-dialog-button-upload": "Юклемек",
+       "upload-form-label-infoform-title": "Толу",
+       "upload-form-label-infoform-name": "Ат",
+       "upload-form-label-infoform-description": "Тасвир",
+       "upload-form-label-usage-title": "Къоллав",
+       "upload-form-label-usage-filename": "Сапламны аты",
+       "upload-form-label-infoform-date": "Тарх",
        "license": "Лицензиялав:",
        "license-header": "Лицензиялав",
+       "listfiles-delete": "тайдырмакъ",
        "imgfile": "саплам",
        "listfiles": "Саплам тизмеси",
+       "listfiles_thumb": "Гиччисурат",
+       "listfiles_date": "Тарх",
+       "listfiles_name": "Ат",
+       "listfiles_user": "Къоллавчу",
+       "listfiles_size": "Гёлем",
+       "listfiles_description": "Тасвир",
+       "listfiles_count": "Тюрлер",
+       "listfiles-latestversion": "Гьалиги тюрю",
+       "listfiles-latestversion-yes": "Дюр",
+       "listfiles-latestversion-no": "Ёкъ",
        "file-anchor-link": "Саплам",
        "filehist": "Саплам тарихи",
        "filehist-help": "Тарх/замангъа бассанг саплам о вакътиде нечик болгъанны гёрежексен",
+       "filehist-deleteall": "Тюмюн тайдырмакъ",
+       "filehist-deleteone": "тайдырмакъ",
        "filehist-revert": "къайтармакъ",
        "filehist-current": "гьалиги",
        "filehist-datetime": "Тарх/Заман",
        "filehist-nothumb": "миниатюрю ёкъ",
        "filehist-user": "Къоллавчу",
        "filehist-dimensions": "Оьлчевлери",
+       "filehist-filesize": "Саплам гёлеми",
        "filehist-comment": "Ёрум",
        "imagelinks": "Сапламны къоллаву",
        "linkstoimage": "Шундан сонггъу {{PLURAL:$1|сагьифа|$1 сагьифалар}} бу сапламгъа байлангъан:",
        "sharedupload-desc-here": "Бу саплам $1 проектдендир, ва башгъасында да къолланма бола. Ону [$2 тасвир сагьифасындан] маълюматы тюпде бериле.‎",
        "filepage-nofile": "Булай аты булан саплам ёкъдур.",
        "upload-disallowed-here": "Бу сапламны уьстюнде язмакъ болмайсан.",
+       "filerevert-comment": "Себеп:",
+       "filerevert-submit": "Къайтармакъ",
+       "filedelete": "$1 тайдырмакъ",
+       "filedelete-legend": "Сапламны тайдырмакъ",
+       "filedelete-comment": "Себеп:",
+       "filedelete-submit": "Тайдырмакъ",
+       "filedelete-reason-otherlist": "Башгъа себеп",
+       "mimesearch": "MIME излев",
+       "download": "эндирмек",
+       "unusedtemplateswlh": "башгъа байланывлар",
        "randompage": "Хапарсыз сагьифа",
+       "randomincategory-category": "Категория:",
+       "randomincategory-submit": "Гёчмек",
        "statistics": "Истатистик",
+       "statistics-pages": "Сагьифа",
+       "pageswithprop-submit": "Тапмакъ",
        "double-redirect-fixer": "Ёллав дуруславу",
+       "brokenredirects-edit": "тюзлемек",
+       "brokenredirects-delete": "тайдырмакъ",
+       "withoutinterwiki-submit": "Гёрсетмек",
        "nbytes": "$1 {{PLURAL:$1|байт|байтлар}}‎",
        "nmembers": "$1 {{PLURAL:$1|ортакъчы}}",
        "prefixindex": "Префикс булан бары да сагьифалар",
        "whatlinkshere": "Мунда байланылгъан",
        "whatlinkshere-title": "\"$1\" бетге байлангъан сагьифалар",
        "whatlinkshere-page": "Сагьифа:",
-       "linkshere": "Гелеген сагьифалар бугъар байлавлу <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Бугъар байлавлу сагьифалар ёкъ <strong>[[:$1]]</strong>:",
+       "linkshere-2": "Гелеген сагьифалар бугъар байлавлу <strong>$1</strong>:",
+       "nolinkshere-2": "Бугъар байлавлу сагьифалар ёкъ <strong>$1</strong>:",
        "isredirect": "ёллав-сагьифа",
        "istemplate": "къошув",
        "isimage": "сапламлы байланыв",
index f523fb5..b767225 100644 (file)
        "whatlinkshere": "Pyth a gevren dhe omma",
        "whatlinkshere-title": "Folennow ow kevrenna dhe \"$1\"",
        "whatlinkshere-page": "Folen:",
-       "linkshere": "Yma an folennow a syw ow kevrenna dhe '''[[:$1]]''':",
-       "nolinkshere": "Nyns eus folen vyth ow kevrenna dhe '''[[:$1]]'''.",
+       "linkshere-2": "Yma an folennow a syw ow kevrenna dhe '''$1''':",
+       "nolinkshere-2": "Nyns eus folen vyth ow kevrenna dhe '''$1'''.",
        "isredirect": "folen daskedyans",
        "istemplate": "treuskludyans",
        "isimage": "kevren an restren",
index 19f7d87..bcedaee 100644 (file)
        "whatlinkshere": "Шилтемелерди бул жакка",
        "whatlinkshere-title": "\"$1\" -га шилтеме берген барактар",
        "whatlinkshere-page": "Барак:",
-       "linkshere": "'''[[:$1]]''' барагына шилтеме берген барактар:",
-       "nolinkshere": "'''[[:$1]]''' барагына шилтеме берген барак жок.",
+       "linkshere-2": "'''$1''' барагына шилтеме берген барактар:",
+       "nolinkshere-2": "'''$1''' барагына шилтеме берген барак жок.",
        "isredirect": "багыттама барак",
        "istemplate": "бириктирүү",
        "isimage": "файл шилтемеси",
index 11e590a..616258d 100644 (file)
        "whatlinkshere": "Nexus ad paginam",
        "whatlinkshere-title": "Paginae quae ad \"$1\" nectuntur",
        "whatlinkshere-page": "Pagina:",
-       "linkshere": "Paginae sequentes ad '''[[:$1]]''' nectunt:",
-       "nolinkshere": "Nullae paginae ad '''[[:$1]]''' nectunt.",
-       "nolinkshere-ns": "Nullae paginae spatii nominalis selecti ad '''[[:$1]]''' nectunt.",
+       "linkshere-2": "Paginae sequentes ad '''$1''' nectunt:",
+       "nolinkshere-2": "Nullae paginae ad '''$1''' nectunt.",
+       "nolinkshere-ns-2": "Nullae paginae spatii nominalis selecti ad '''$1''' nectunt.",
        "isredirect": "pagina redirectionis",
        "istemplate": "inclusio",
        "isimage": "nexus fasciculi",
index dfc7321..9e035e9 100644 (file)
        "whatlinkshere": "Hojas atadas",
        "whatlinkshere-title": "Hojas que dan link a \"$1\"",
        "whatlinkshere-page": "Hoja:",
-       "linkshere": "Las hojas venideras dan link a '''[[:$1]]''':",
-       "nolinkshere": "Dinguna ója tiene atamientos kon '''[[:$1]]'''",
+       "linkshere-2": "Las hojas venideras dan link a '''$1''':",
+       "nolinkshere-2": "Dinguna ója tiene atamientos kon '''$1'''",
        "isredirect": "Hoja redirigida",
        "istemplate": "inclusión",
        "isimage": "atamiento de la dosya",
index 8bea39a..68d5273 100644 (file)
        "botpasswords-existing": "Aktuell Botpasswierder.",
        "botpasswords-createnew": "En neit Botpasswuert uleeën",
        "botpasswords-editexisting": "E Botpasswuert änneren",
+       "botpasswords-label-needsreset": "(Passwuert muss zréckgesat ginn)",
        "botpasswords-label-appid": "Numm vum Bot:",
        "botpasswords-label-create": "Uleeën",
        "botpasswords-label-update": "Aktualiséieren",
        "subject-preview": "Sujet kucken ouni ze späicheren:",
        "previewerrortext": "Beim Versuch fir Är Ännerungen ze weisen, ass e Feeler geschitt.",
        "blockedtitle": "Benotzer ass gespaart",
-       "blockedtext": "Äre Benotzernumm oder Är IP-Adress gouf gespaart.\n\nD'Spär gouf vum $1 gemaach. Als Grond gouf ''$2'' uginn.\n\n* Ufank vun der Spär: $8\n* Enn vun der Spär: $6\n* Spär betrëfft: $7\n\nDir kënnt den/d' $1 kontaktéieren oder ee vun den aneren [[{{MediaWiki:Grouppage-sysop}}|Administrateure]] fir iwwer d'Spär ze schwätzen.\n\nDëst sollt Dir besonnesch maachen, wann Dir d'Gefill hutt, datt de Grond fir d'Spären net bei Iech läit.\nD'Ursaach dofir ass an deem Fall, datt Dir eng dynamesch IP hutt, iwwer en Access-Provider, iwwer deen och aner Leit fueren.\nAus deem Grond ass et recommandéiert, sech e Benotzernumm zouzeleeën, fir all Mëssverständnes z'evitéieren.\n\nDir kënnt d'Funktioun \"Dësem Benotzer eng E-Mail schécken\" nëmme benotzen, wann Dir eng gëlteg E-Mail Adress bei Ären [[Special:Preferences|Astellungen]] aginn hutt.\nÄr aktuell IP-Adress ass $3 an d'Nummer vun der Spär ass #$5.\nSchreift all dës Informatioune w.e.g. bei all Ufro derbäi.",
+       "blockedtext": "<strong>Äre Benotzernumm oder Är IP-Adress gouf gespaart.</strong>\n\nD'Spär gouf vum $1 gemaach.\nAls Grond gouf <em>$2</em> uginn.\n\n* Ufank vun der Spär: $8\n* Enn vun der Spär: $6\n* Spär betrëfft: $7\n\nDir kënnt den/d' $1 kontaktéieren oder ee vun den aneren [[{{MediaWiki:Grouppage-sysop}}|Administrateure]] fir iwwer d'Spär ze schwätzen.\n\nDëst sollt Dir besonnesch maachen, wann Dir d'Gefill hutt, datt de Grond fir d'Spären net bei Iech läit.\nD'Ursaach dofir ass an deem Fall, datt Dir eng dynamesch IP hutt, iwwer en Access-Provider, iwwer deen och aner Leit fueren.\nAus deem Grond ass et recommandéiert, sech e Benotzernumm zouzeleeën, fir all Mëssverständnes z'evitéieren.\n\nDir kënnt d'Funktioun \"{{int:emailuser}}\" nëmme benotzen, wann Dir eng gëlteg E-Mail Adress bei Ären [[Special:Preferences|Astellungen]] aginn hutt.\nÄr aktuell IP-Adress ass $3 an d'Nummer vun der Spär ass #$5.\nSchreift all dës Informatioune w.e.g. bei all Ufro derbäi.",
        "autoblockedtext": "Är IP-Adress gouf automatesch gespaart, well se vun engem anere Benotzer gebraucht gouf, an dee vum $1 gespaart gouf.\nDe Grond dofir war:\n\n:''$2''\n\n* Ufank vun der Spär: $8\n* Dauer vun der Spär: $6\n* D'Spär leeft of: $7\n\nDir kënnt de(n) $1 oder soss een [[{{MediaWiki:Grouppage-sysop}}|Administrateur]] kontaktéieren, fir iwwer déi Spär ze diskutéieren.\n\nBedenkt datt Dir d'Funktioun \"Dësem Benotzer eng E-Mail schécken\" benotze kënnt wann Dir eng gëlteg E-Mail-Adress an Ären [[Special:Preferences|Astellungen]] uginn hutt a wann dat net fir Iech gespaart gouf.\n\nÄr aktuell IP-Adress ass $3 an d'Nummer vun Ärer Spär ass $5.\nGitt dës Donnéeë w.e.g bei allen Ufroen zu dëser Spär un.",
        "blockednoreason": "Kee Grond uginn",
        "whitelistedittext": "Dir musst Iech $1, fir Säiten änneren ze kënnen.",
        "previewnote": "'''Denkt drun datt dëst nëmmen eng net gespäichert Versioun ass.'''\nÄr Ännerunge sinn nach net gespäichert!",
        "continue-editing": "Gitt weider an de Beräich fir z'änneren",
        "previewconflict": "Dir gesitt an dem ieweschten Textfeld wéi den Text ausgesi wäert, wann Dir späichert.",
-       "session_fail_preview": "Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.\nDir gouft eventuell ausgeloggt. <strong>Iwwerpréift w.e.g. ob Dir nach ageloggt sidd a probéiert nach eng Kéier</strong>.\nWann de Problem dann ëmmer nach bestoe sollt, da versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen an iwwerpréift datt Äre Browser Cookië vun dësem Site  akzeptéiert.",
-       "session_fail_preview_html": "Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.\n\n<em>Well op {{SITENAME}} 'raw HTML' aktivéiert ass, gouf d'Uweise vun der nach net gespäicherter Versioun ausgeblennt fir JavaScript-Attacken ze vermeiden.</em>\n\n<strong>Wann Dir eng berechtegt Ännerung maache wëllt, da versicht et w.e.g. nach eng Kéier.</strong>\n\nWann de Problem dann ëmmer nach bestoe sollt, versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen a vergewëssert Iech datt Äre Browser d^Späichere vu Cookieë vun dësem Site zouléisst.",
+       "session_fail_preview": "Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.\nDir gouft eventuell ausgeloggt. <strong>Iwwerpréift w.e.g. ob Dir nach ageloggt sidd a probéiert nach eng Kéier</strong>.\nWann de Problem dann ëmmer nach bestoe sollt, da versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen an iwwerpréift ob Äre Browser Cookië vun dësem Site  akzeptéiert.",
+       "session_fail_preview_html": "Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.\n\n<em>Well op {{SITENAME}} 'raw HTML' aktivéiert ass, gouf d'Uweise vun der nach net gespäicherter Versioun ausgeblennt fir JavaScript-Attacken ze vermeiden.</em>\n\n<strong>Wann Dir eng berechtegt Ännerung maache wëllt, da versicht et w.e.g. nach eng Kéier.</strong>\n\nWann de Problem dann ëmmer nach bestoe sollt, versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen a vergewëssert Iech ob Äre Browser d'Späichere vu Cookieë vun dësem Site zouléisst.",
        "token_suffix_mismatch": "'''Är Ännerung gouf refuséiert, well Äre Browser Zeechen am Ännerungs-Identifiant verännert huet.'''\nD'Ännerung gouf refuséiert, fir ze verhënneren datt den Text op der Säit onliesbar gëtt.\nDëst geschitt heiansdo wann Dir en anonyme Proxy-Service um Internet benotzt.",
        "edit_form_incomplete": "'''En Deel vum Ännerungsformulaire koum net um Server un; iwwerpréift w.e.g ob Är Ännerunge komplett sinn a probéiert nach emol.'''",
        "editing": "Ännere vu(n) $1",
        "recentchangeslinked-feed": "Ännerungen op verlinkt Säiten",
        "recentchangeslinked-toolbox": "Ännerungen op verlinkt Säiten",
        "recentchangeslinked-title": "Ännerungen a Verbindung mat \"$1\"",
-       "recentchangeslinked-summary": "Gitt den Numm vun enger Säit a fir Ännerungen Säiten ze gesinn op déi oder vun deene gelinkt gëtt. Ännerungen op Säite vun [[Special:Watchlist|Ärer Iwwerwaachungslëscht]] si <strong>fett</strong> geschriwwen.",
+       "recentchangeslinked-summary": "Gitt den Numm vun enger Säit a fir Ännerungen op Säiten ze gesinn op déi oder vun deene gelinkt gëtt. (Fir d'Membere vun enger Kategorie ze gesinn gitt {{ns:category}}:Numm vun der Kategorie, an.) Ännerungen op Säite vun [[Special:Watchlist|Ärer Iwwerwaachungslëscht]] si <strong>fett</strong> geschriwwen.",
        "recentchangeslinked-page": "Säitennumm:",
        "recentchangeslinked-to": "Weis Ännerungen zu de verlinkte Säiten aplaz vun der gefroter Säit",
        "recentchanges-page-added-to-category": "[[:$1]] an d'Kategorie dobäigesat",
        "whatlinkshere": "Linken op dës Säit",
        "whatlinkshere-title": "Säiten, déi mat \"$1\" verlinkt sinn",
        "whatlinkshere-page": "Säit:",
-       "linkshere": "Déi folgend Säite linken op '''[[:$1]]''':",
-       "nolinkshere": "Keng Säit ass mat '''[[:$1]]''' verlinkt.",
-       "nolinkshere-ns": "Keng Säite linken op '''[[:$1]]''' am gewielten Nummraum.",
+       "linkshere-2": "Déi folgend Säite linken op '''$1''':",
+       "nolinkshere-2": "Keng Säit ass mat '''$1''' verlinkt.",
+       "nolinkshere-ns-2": "Keng Säite linken op '''$1''' am gewielten Nummraum.",
        "isredirect": "Viruleedung",
        "istemplate": "an dëser Säit dran",
        "isimage": "Link op de Fichier",
        "fileduplicatesearch-noresults": "Et gouf kee Fichier mam Numm \"$1\" fonnt.",
        "specialpages": "Spezialsäiten",
        "specialpages-note-top": "Erklärung",
+       "specialpages-note-restricted": "* Normal Spezialsäiten.\n* <span class=\"mw-specialpagerestricted\">Spezialsäite fir Benotzer mat méi Rechter.</span>",
        "specialpages-group-maintenance": "Maintenance-Rapporten",
        "specialpages-group-other": "Aner Spezialsäiten",
        "specialpages-group-login": "Aloggen / Benotzerkont uleeën",
        "gotointerwiki-invalid": "De spezifizéierten Titel ass net valabel.",
        "gotointerwiki-external": "Dir sidd am Gaang {{SITENAME}} ze verloosse fir [[$2]] ze besichen, deen een externen Internetsite ass.\n\n'''[$1 Hei klicke fir op $1 virunzefueren]'''",
        "undelete-cantedit": "Dir kënnt dës Säit net restauréiere well Dir dës Säit net änneren däerft.",
-       "undelete-cantcreate": "Dir kënnt dës Säit net restauréieren well et elo keng Säit mat deem Numm gëtt a well Dir dës Säit net uleeën däerft."
+       "undelete-cantcreate": "Dir kënnt dës Säit net restauréieren well et elo keng Säit mat deem Numm gëtt a well Dir dës Säit net uleeën däerft.",
+       "passwordpolicies": "Richtlinne fir Passwierder",
+       "passwordpolicies-group": "Grupp",
+       "passwordpolicies-policies": "Richtlinnen"
 }
index 0ea7d77..2b857b1 100644 (file)
        "whatlinkshere": "Иниз вуч элячIзава",
        "whatlinkshere-title": "\"$1\" - даз элячlзавай ччинар",
        "whatlinkshere-page": "Ччин:",
-       "linkshere": "Гуьгъуьнин ччинар '''[[:$1]]''': - даз  элячlзава",
-       "nolinkshere": "'''[[:$1]]''' ччиниз са ччинни элячIзавач.",
+       "linkshere-2": "Гуьгъуьнин ччинар '''$1''': - даз  элячlзава",
+       "nolinkshere-2": "'''$1''' ччиниз са ччинни элячIзавач.",
        "isredirect": "Рахкъурунин ччин",
        "istemplate": "кутун",
        "isimage": "Файлдин элячlун",
index bad0415..9edaaa8 100644 (file)
@@ -10,7 +10,9 @@
                        "Katxis",
                        "Chabi",
                        "Angel Blaise",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Robin van der Vliet",
+                       "Mafcadio"
                ]
        },
        "tog-underline": "Sulini de lias:",
        "disclaimerpage": "Project:Renunsia jeneral",
        "edithelp": "Aida sur edita",
        "helppage-top-gethelp": "Aida",
-       "mainpage": "Paje Xef",
+       "mainpage": "Paje xef",
        "mainpage-description": "Paje xef",
        "policy-url": "Project:Politica",
        "portal": "Porton de comunia",
        "editold": "edita",
        "viewsourceold": "regarda vicitesto",
        "editlink": "edita",
-       "viewsourcelink": "regarda vicitesto",
+       "viewsourcelink": "regarda la fonte",
        "editsectionhint": "Edita la parte: $1",
        "toc": "Contenida",
        "showtoc": "mostra",
        "perfcachedts": "La datos seguente veni de prememoria e la refresci la plu resente ia aveni a $1. No plu ca {{PLURAL:$4|un resulta|$4 resultas}} es disponable en la prememoria.",
        "querypage-no-updates": "Refrescis de esta paje es aora descomutada.\nDatos asi no va es refrescida a presente.",
        "viewsource": "Regarda vicitesto",
-       "viewsource-title": "Regarda vicitesto per $1",
+       "viewsource-title": "Regarda fonte per $1",
        "actionthrottled": "Ata limitada",
        "actionthrottledtext": "Per defende contra malusa, usores no pote fa esta ata a tro multe veses en un tempo corta, e tu ia esede esta limita.\nPer favore, atenta denova pos alga minutos.",
        "protectedpagetext": "Esta paje es protejeda per preveni editas o otra atas.",
        "cascadeprotected": "Esta paje es protejeda contra editas car lo es transcluida en la {{PLURAL:$1|paje|pajes}} seguente, cual es cascadin protejeda:\n$2",
        "namespaceprotected": "Tu no es permeteda a edita pajes en la spasio de nom <strong>$1</strong>.",
        "customcssprotected": "Tu no es permeteda a edita esta paje de CSS, car lo conteni la preferes personal de un otra usor.",
+       "customjsonprotected": "Tu no es permeteda a edita esta paje de JSON, car lo conteni la preferes personal de un otra usor.",
        "customjsprotected": "Tu no es permeteda a edita esta paje de JavaScript, car lo conteni la preferes personal de un otra usor.",
        "mycustomcssprotected": "Tu no es permeteda a edita esta paje de CSS.",
+       "mycustomjsonprotected": "Tu no es permeteda a edita esta paje de JSON.",
        "mycustomjsprotected": "Tu no es permeteda a edita esta paje de JavaScript.",
        "myprivateinfoprotected": "Tu no es permeteda a edita tua informas privata.",
        "mypreferencesprotected": "Tu no es permeteda a edita tua preferes.",
        "nowiki_sample": "Ajunta asi testo nonformatida",
        "nowiki_tip": "Iniora sintatica de vici",
        "image_tip": "Fix interna",
-       "media_tip": "Lia a un fix",
+       "media_tip": "Lia de fix",
        "sig_tip": "Tua suscrive con indica de ora",
        "hr_tip": "Linia orizonal (per usas rara)",
        "summary": "Resoma:",
        "subject-preview": "Previde de tema:",
        "previewerrortext": "Un era ia aveni en atenta previde tua cambias.",
        "blockedtitle": "Usor es impedida",
-       "blockedtext": "<strong>Tua nom de usor o adirije IP es impedida.</strong>\n\nLa impedi ia es fada par $1.\nLa razona donada es ''$2''.\n\n* Comensa de impedi: $8\n* Fini de impedi: $6\n* Conta impedida: $7\n\nTu pote contata $1 o un otra [[{{MediaWiki:Grouppage-sysop}}|dirijor]] per discute esta impedi.\nTu no pote usa la funsiona \"envia un eposta a esta usor\" estra si un adirije valida\nde eposta es spesifada en tua [[Special:Preferences|preferes de conta]] e tu no es impedida de usa lo.\nTua adirije IP presente es $3, e la numero de impedi es #$5.\nInclui tota esta detalias en cualce demandas cual tu fa, per favore.",
+       "blockedtext": "<strong>Tua nom de usor o adirije IP es impedida.</strong>\n\nLa impedi ia es fada par $1.\nLa razona donada es <em>$2</em>.\n\n* Comensa de impedi: $8\n* Fini de impedi: $6\n* Conta impedida: $7\n\nTu pote contata $1 o un otra [[{{MediaWiki:Grouppage-sysop}}|dirijor]] per discute esta impedi.\nTu no pote usa la funsiona \"{{int:emailuser}}\" estra si un adirije valida\nde eposta es spesifada en tua [[Special:Preferences|preferes de conta]] e tu no es impedida de usa lo.\nTua adirije IP presente es $3, e la numero de impedi es #$5.\nInclui tota esta detalias en cualce demandas cual tu fa, per favore.",
        "autoblockedtext": "Tua adirije IP ia es automata impedida car lo ia es usada par un otra usor, ci ia es impedida par $1.\nLa razona donada es ''$2''.\n\n* Comensa de impedi: $8\n* Fini de impedi: $6\n* Conta impedida: $7\n\nTu pote contata $1 o un otra [[{{MediaWiki:Grouppage-sysop}}|dirijor]] per discute esta impedi.\nTu no pote usa la funsiona \"envia un eposta a esta usor\" estra si un adirije valida de eposta es spesifada en tua [[Special:Preferences|preferes de conta]] e tu no es impedida de usa lo.\nTua adirije IP presente es $3, e la numero de impedi es #$5.\nInclui tota esta detalias en cualce demandas cual tu fa, per favore.",
        "systemblockedtext": "Tua nom de usor o adirije IP ia es automata impedida par MediaWiki.\nLa razona donada es <em>$2</em>.\n\n* Comensa de impedi: $8\n* Fini de impedi: $6\n* Conta impedida: $7\nTua adirije IP presente es $3.\nInclui tota esta detalias en cualce demandas cual tu fa, per favore.",
        "blockednoreason": "no razona donada",
        "recentchangeslinked-feed": "Cambias relatada",
        "recentchangeslinked-toolbox": "Cambias relatada",
        "recentchangeslinked-title": "Cambias relatada a \"$1\"",
-       "recentchangeslinked-summary": "Tape un nom de paje per vide cambias en pajes liada a o de acel paje. (Per vide membros de un categoria, tape <strong>bold</strong>.) Cambias a pajes en [[Special:Watchlist|tua lista monitorida]] es <strong>spesa</strong>.",
+       "recentchangeslinked-summary": "Tape un nom de paje per vide cambias en pajes liada a o de acel paje. (Per vide membros de un categoria, tape {{ns:category}}:Nom de categoria.) Cambias a pajes en [[Special:Watchlist|tua lista monitorida]] es <strong>spesa</strong>.",
        "recentchangeslinked-page": "Nom de paje:",
        "recentchangeslinked-to": "Mostra cambias a pajes cual lia a la paje indicada, en loca",
        "recentchanges-page-added-to-category": "[[:$1]] ajuntada a categoria",
        "apisandbox-dynamic-error-exists": "Un parametre nomida \"$1\" esiste ja.",
        "apisandbox-deprecated-parameters": "Parametres desaprobada",
        "apisandbox-fetch-token": "Autopleni la marca",
+       "apisandbox-add-multi": "Ajunta",
        "apisandbox-submit-invalid-fields-title": "Alga campos es nonvalida",
        "apisandbox-submit-invalid-fields-message": "Coreti la campos indicada, per favore, e reatenta.",
        "apisandbox-results": "Resultas",
        "whatlinkshere": "Lias a esta paje",
        "whatlinkshere-title": "Pajes cual lia a \"$1\"",
        "whatlinkshere-page": "Paje:",
-       "linkshere": "La pajes seguente lia a <strong>[[:$1]]</strong>:",
-       "nolinkshere": "No pajes lia a <strong>[[:$1]]</strong>.",
-       "nolinkshere-ns": "No pajes lia a <strong>[[:$1]]</strong> en la spasio de nom elejeda.",
+       "linkshere-2": "La pajes seguente lia a <strong>$1</strong>:",
+       "nolinkshere-2": "No pajes lia a <strong>$1</strong>.",
+       "nolinkshere-ns-2": "No pajes lia a <strong>$1</strong> en la spasio de nom elejeda.",
        "isredirect": "paje redirijente",
        "istemplate": "transclui",
        "isimage": "lia de fix",
        "tooltip-pt-watchlist": "Un lista de pajes cual tu monitori per cambias",
        "tooltip-pt-mycontris": "Un lista de tua contribuis",
        "tooltip-pt-anoncontribs": "Un lista de editas fada de esta adirije IP",
-       "tooltip-pt-login": "Nos recomenda ce tu autentici, ma esta no es no obligante",
+       "tooltip-pt-login": "Nos recomenda ce tu autentici, ma esta no es obligante",
        "tooltip-pt-login-private": "Tu nesesa autentici per usa esta vici",
        "tooltip-pt-logout": "Desautentici",
        "tooltip-pt-createaccount": "Nos recomenda ce tu crea un conta e autentici, ma esta no es obligante",
        "tooltip-t-upload": "Carga fixes",
        "tooltip-t-specialpages": "Un lista de tota pajes spesial",
        "tooltip-t-print": "Varia primable de esta paje",
-       "tooltip-t-permalink": "Lias permanente a esta revisa de la paje",
+       "tooltip-t-permalink": "Lia permanente a esta revisa de la paje",
        "tooltip-ca-nstab-main": "Regarda la paje de contenida",
        "tooltip-ca-nstab-user": "Regarda la paje de usor",
        "tooltip-ca-nstab-media": "Regarda la paje de media",
        "feedback-thanks": "Grasias! Tua comenta apare en la paje \"[$2 $1]\".",
        "feedback-thanks-title": "Grasias!",
        "feedback-useragent": "Surfador:",
-       "searchsuggest-search": "Xerca {{SITENAME}}",
+       "searchsuggest-search": "Xerca en {{SITENAME}}",
        "searchsuggest-containing": "conteninte...",
        "api-error-badtoken": "Era interna: Mal marca.",
        "api-error-emptypage": "La crea de pajes nova e vacua no es permeteda.",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|bait|baites}}",
        "limitreport-expansiondepth": "Profondia la plu grande de despaci",
        "limitreport-expensivefunctioncount": "Cuantia de funsionas custosa de analisador sintatical",
+       "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|bait|baites}}",
        "expandtemplates": "Despaci stensiles",
        "expand_templates_intro": "Esta paje spesial prende vicitesto e despaci tota stensiles en lo, en modo recorsante. Lo despaci ance funsionas suportada de analisador sintatical como <code><nowiki>{{</nowiki>#language:…}}</code> e variables como <code><nowiki>{{</nowiki>CURRENTDAY}}</code>. En fato, lo despaci cuasi tota cosas entre brasetas risa duple.",
        "expand_templates_title": "Titulo de contesto, per {{FULLPAGENAME}}, etc.:",
index d8f54b8..d6f438e 100644 (file)
        "whatlinkshere": "Empapula ezikuggusa ku luno",
        "whatlinkshere-title": "Empapula eziriko enyunzi ezigguka ku $1",
        "whatlinkshere-page": "Lupapula:",
-       "linkshere": "Zino z'empapula eziriko enyunzi ezigguka ku '''[[:$1]]''':",
-       "nolinkshere": "Tewali mpapula eziriko enyunzi ezigguka ku '''[[:$1]]'''.",
+       "linkshere-2": "Zino z'empapula eziriko enyunzi ezigguka ku '''$1''':",
+       "nolinkshere-2": "Tewali mpapula eziriko enyunzi ezigguka ku '''$1'''.",
        "isredirect": "lupapula olukutwalabutwazi ku lunnaalwo",
        "istemplate": "kitundu ekyeyazike",
        "isimage": "lukozesa ekifaananyi kino",
index 5ef25bf..a86d842 100644 (file)
        "whatlinkshere": "Links nao dees pagina",
        "whatlinkshere-title": "Pagina's die verwieze nao \"$1\"",
        "whatlinkshere-page": "Pagina:",
-       "linkshere": "De volgende pagina's verwieze nao '''[[:$1]]''':",
-       "nolinkshere": "D'r zint gein pazjena's mit links nao '''[[:$1]]''' haer.",
-       "nolinkshere-ns": "Geine inkele pazjena link nao '''[[:$1]]''' in de gekaoze naamruumde.",
+       "linkshere-2": "De volgende pagina's verwieze nao '''$1''':",
+       "nolinkshere-2": "D'r zint gein pazjena's mit links nao '''$1''' haer.",
+       "nolinkshere-ns-2": "Geine inkele pazjena link nao '''$1''' in de gekaoze naamruumde.",
        "isredirect": "redirect pagina",
        "istemplate": "ingevoog es sjabloon",
        "isimage": "bestandjslink",
index 0a60cfc..fea67cc 100644 (file)
        "whatlinkshere": "Cöse se colega chì",
        "whatlinkshere-title": "Pàgine c'apontàn a $1",
        "whatlinkshere-page": "Pàgina:",
-       "linkshere": "E pàgine segoenti apontan a '''[[:$1]]''':",
-       "nolinkshere": "Nisciùnn-a pàgina a se collega con '''[[:$1]]'''.",
-       "nolinkshere-ns": "Pagine ch'apontan a '''[[:$1]]''' into namespace seleçionou no ghe n'è.",
+       "linkshere-2": "E pàgine segoenti apontan a '''$1''':",
+       "nolinkshere-2": "Nisciùnn-a pàgina a se collega con '''$1'''.",
+       "nolinkshere-ns-2": "Pagine ch'apontan a '''$1''' into namespace seleçionou no ghe n'è.",
        "isredirect": "Paggina de rindirissamento",
        "istemplate": "Incluxon",
        "isimage": "Colegaménto a-o file",
        "fileduplicatesearch-noresults": "Nisciun file de nomme \"$1\" trovou.",
        "specialpages": "Pàgine speciâli",
        "specialpages-note-top": "Legenda",
+       "specialpages-note-restricted": "* Pagine speciali non riservæ.\n* <span class=\"mw-specialpagerestricted\">Pagine speciali riservæ a çerte categorie d'utenti.</span>",
        "specialpages-group-maintenance": "Raporti de manutençion",
        "specialpages-group-other": "Atre paggine speciale",
        "specialpages-group-login": "Intra / Registrite",
index 0ca1316..4f060a4 100644 (file)
        "whatlinkshere": "پیوندەل وە ئێ وەڵگە",
        "whatlinkshere-title": "وۀلگۀلئ گإ  وۀ «$1» پیوۀند دِرِن",
        "whatlinkshere-page": ":وةڵگە(پەڕە)",
-       "linkshere": "The following pages link to <strong>[[:$1]]</strong>:",
-       "nolinkshere": "هیچ صفحه‌ای به '''[[:$1]]''' پیوند ندارد.",
-       "nolinkshere-ns": "هیچ صفحه‌ای از فضای نام انتخاب شده به '''[[:$1]]''' پیوند ندارد.",
+       "linkshere-2": "The following pages link to <strong>$1</strong>:",
+       "nolinkshere-2": "هیچ صفحه‌ای به '''$1''' پیوند ندارد.",
+       "nolinkshere-ns-2": "هیچ صفحه‌ای از فضای نام انتخاب شده به '''$1''' پیوند ندارد.",
        "isredirect": "وەڵگە ڕێ گؤەڕن(تغییرمسییر)",
        "istemplate": " تراگنجانش‌ها",
        "isimage": "پیوند پرونده",
        "fileduplicatesearch-noresults": "پرونده‌ای با نام «$1» أ دی نؤی /پئا نؤی.",
        "specialpages": "وەڵگەل(پەڕەل)ویژە",
        "specialpages-note-top": "شرح علائم",
+       "specialpages-note-restricted": "* صفحه‌های ویژهٔ عادی.\n* <span class=\"mw-specialpagerestricted\">صفحه‌های ویژهٔ محدودشده.</span>",
        "specialpages-group-maintenance": "گزارش‌های نگهداری",
        "specialpages-group-other": "سایر وةڵگةل ویژه",
        "specialpages-group-login": " إ نؤم هةتن سیستم/ حساوو کاربةری سازین",
index 7dbe352..a4fb8c9 100644 (file)
        "whatlinkshere": "Pagin che se culeghen chì",
        "whatlinkshere-title": "Paginn che menen a \"$1\"",
        "whatlinkshere-page": "Pagina:",
-       "linkshere": "I paginn chì de sota gh'hann di ligam che porten a '''[[:$1]]''':",
+       "linkshere-2": "I paginn chì de sota gh'hann di ligam che porten a '''$1''':",
        "isredirect": "redirezión",
        "istemplate": "inclüsión",
        "isimage": "ligam a un archivi",
index 7a4ba91..84fcc2c 100644 (file)
        "sp-contributions-submit": "ຊອກຫາ",
        "whatlinkshere": "ໜ້າທີ່ເຊື່ອມຕໍ່ມາໜ້ານີ້",
        "whatlinkshere-title": "ໜ້າທີ່ເຊື່ອມຕໍ່ຫາ $1",
-       "linkshere": "ບັນດາໜ້າຕໍ່ໄປ ລິ້ງຄ໌ ຫາ ''[[:$1]]''':",
-       "nolinkshere": "ບໍ່ມີໜ້າລິ້ງຄ໌ ຫາ '''[[:$1]]'''.",
-       "nolinkshere-ns": "ບໍ່ມີໜ້າລິ້ງຄ໌ ຫາ '''[[:$1]]''' ໃນ ຂອບເຂດຊື່ ທີ່ ທ່ານເລືອກ.",
+       "linkshere-2": "ບັນດາໜ້າຕໍ່ໄປ ລິ້ງຄ໌ ຫາ ''$1''':",
+       "nolinkshere-2": "ບໍ່ມີໜ້າລິ້ງຄ໌ ຫາ '''$1'''.",
+       "nolinkshere-ns-2": "ບໍ່ມີໜ້າລິ້ງຄ໌ ຫາ '''$1''' ໃນ ຂອບເຂດຊື່ ທີ່ ທ່ານເລືອກ.",
        "isredirect": "ໜ້າໂອນ",
        "istemplate": "ລວມ",
        "whatlinkshere-prev": "{{PLURAL:$1|ກ່ອນ|ກ່ອນ $1}}",
index cc49d74..a8146a8 100644 (file)
        "whatlinkshere": "Ling'ki di bye petulo",
        "whatlinkshere-title": "Petulo bye ling'ki di $1",
        "whatlinkshere-page": "Petulo:",
-       "linkshere": "Bye petulo ling'ki di '''[[:$1]]''':",
-       "nolinkshere": "0 petulo ling'ki di '''[[:$1]]'''.",
-       "nolinkshere-ns": "0 petulo ling'ki di '''[[:$1]]''' bye sa di bye fatukile efro.",
+       "linkshere-2": "Bye petulo ling'ki di '''$1''':",
+       "nolinkshere-2": "0 petulo ling'ki di '''$1'''.",
+       "nolinkshere-ns-2": "0 petulo ling'ki di '''$1''' bye sa di bye fatukile efro.",
        "isredirect": "petulo abezi",
        "istemplate": "yang'idole",
        "whatlinkshere-prev": "{{PLURAL:$1|kona|kona $1}}",
index ca6ac41..e822bba 100644 (file)
@@ -64,8 +64,8 @@
        "editfont-serif": "فونت سئريف",
        "sunday": "یٱشمٱ",
        "monday": "دۏشٱمٱ",
-       "tuesday": "ساÙ\9bشمٱ",
-       "wednesday": "چارشأمە",
+       "tuesday": "سئشمٱ",
+       "wednesday": "چارشٱمٱ",
        "thursday": "پن شمٱ",
        "friday": "جومٱ",
        "saturday": "شٱمٱ",
@@ -93,8 +93,8 @@
        "march-gen": "مارس",
        "april-gen": "آڤریل",
        "may-gen": "مئی",
-       "june-gen": "جوٙأن",
-       "july-gen": "جوٙلای",
+       "june-gen": "جۊٱن",
+       "july-gen": "جۊلای",
        "august-gen": "آگوست",
        "september-gen": "سئپتامر",
        "october-gen": "ئوکتوبر",
        "specialpage": "بألگە ڤیجە",
        "personaltools": "ٱڤزاریا شٱخسی",
        "talk": "گٱپ",
-       "views": "دÛ\8cاÙ\9bن",
+       "views": "دÛ\8cئن",
        "toolbox": "ٱڤزاریا",
        "imagepage": "ديئن بألگە جانیا",
        "mediawikipage": "ديئن بألگە پئيغوم",
        "perfcached": "رئسینە یا نئهایی د ڤیرگە قام بییە موٙکیس بینە و گاسی هأنی ڤئ هئنگوم سازی نأبینە.بیشتئروٙنە {{PLURAL:$4|یئ گئل نأتیجە|$4 یئ گئل نأتیجە}} د ڤیرگە قام بییە هان د دأسرئس.",
        "perfcachedts": "رئسینە یا نئهایی د ڤیرگە قام بییە موٙکیس بینە و گاسی هأنی ڤئ هئنگوم سازی نأبینە.بیشتئروٙنە {{PLURAL:$4|یئ گئل نأتیجە|$4 یئ گئل نأتیجە}} د ڤیرگە قام بییە هان د دأسرئس.",
        "querypage-no-updates": "نأبوٙە ئی بألگە ڤئ هئنگوم سازی با.\nرئسینە یا ئیچئ تازە کاری نأبینە.",
-       "viewsource": "ساÙ\9bیل د سرچشمٱ بٱکیت",
+       "viewsource": "سئیل د سرچشمٱ بٱکیت",
        "viewsource-title": "سئیل د سأرچئشمە $1 بأکیت",
        "actionthrottled": "کونئشتکاری نئهاگئری بییە",
        "actionthrottledtext": "سی نئهاگئری د دأرتیچ بییئن ئسپأم نأبوٙە کئ شوما چئنی کاری نە د یئ گاتی کوٙتا چأن گئل أنجوم بئییت.\nلوطف بأکیت د چأن دئیقە هأنی د نۊ تئلاش بأکیت.",
        "userlogin-loggedin": "شوما ئیسئ چی یئ گئل {{GENDER:$1|$1}} ئوٙمایتە ڤامین.نوم بألگە هاری نە سی ڤامین ئوٙمائن چی یئ گئل کاریار هأنی بلگه هاری سی وا مین اومائن چی یه گل کاریار هنی ڤئ کار بئیریت.",
        "userlogin-createanother": "یئ گئل حئساڤ هأنی راس بأکیت",
        "createacct-emailrequired": "تیرنئشوٙن أنجومانامە",
-       "createacct-emailoptional": "تÛ\8cرÙ\86ئشÙ\88Ù\99Ù\86 Ø£Ù\86جÙ\88Ù\85اÙ\86اÙ\85Û\95",
+       "createacct-emailoptional": "تÛ\8cرÙ\86Ø´Û\8aÙ\86 Ù±Ù\86جÙ\88Ù\85اÙ\86اÙ\85Ù±",
        "createacct-email-ph": "تیرنشون انجومانامه تونه وارد بكيت",
        "createacct-another-email-ph": "تیرنئشوٙن أنجومانامە توٙنە بأزأنیت",
        "createaccountmail": "یئ گئل رازینە گوڤاردئن موڤأقأتینە ڤئ کار بئیریت و ڤئ نەسی یئ گئل تیرنئشوٙن أنجومانامە تیار بییە کئل بأکیت.",
        "resettokens-watchlist-token": "دیارگأر سی حوڤال حوٙن تورگە(أتوم/آر ئس ئس) سی [[Special:سئیل بأرگ|آلئشت دأئن بألگە یا د سئیل بأرگئتوٙ]]",
        "resettokens-done": "نئشوٙنە یا تازه بیینە",
        "resettokens-resetbutton": "نئشوٙنە گولئ ڤورچیە د نوٙ زئنە بینە",
-       "bold_sample": "نیسسە توٙپور",
-       "bold_tip": "Ù\86Û\8cسئسÛ\95 ØªÙ\88Ù\99پور",
+       "bold_sample": "نیسسٱ مین پور",
+       "bold_tip": "Ù\86Û\8cسسٱ Ù\85Û\8cÙ\86 پور",
        "italic_sample": "نیسئسە کأج و کولە",
        "italic_tip": "نیسئسە یا کأج و کولە",
        "link_sample": "داسوٙن هوم پیڤند",
        "summary": "چکسٱ",
        "subject": "ذاسوٙن/سأرتال:",
        "minoredit": "یٱ یاٛ گاٛل ڤیرایشت کوچکٱ",
-       "watchthis": "دÛ\8cاÙ\9bن ای بلگٱ",
+       "watchthis": "دÛ\8cئن ای بلگٱ",
        "savearticle": "اٛمایٱ کردن بلگٱ",
        "preview": "پيش سئيل",
-       "showpreview": "Ù\86Ø´Û\8a Ø¯Ù±Ø¦Ù\86 Ù¾Û\8cØ´ Ø³Ø§Ù\9bیل",
+       "showpreview": "Ù\86Ø´Û\8a Ø¯Ù±Ø¦Ù\86 Ù¾Û\8cØ´ Ø³Ø¦یل",
        "showdiff": "نشۊ دٱئن آلشتکاریا",
        "blankarticle": "<strong>زنئار:</strong> بلگه ای که شما دروس کردیته حالیه.\nار شما د نو ری \"$1\" بپورنیت, بلگه وه شکل که هیچ مینونه ای دش نبا دروس بوئه.",
        "anoneditwarning": "<strong>زاٛنار:</strong> شوما هٱنی نیۊمایتٱ ڤامین. تیرنشۊن آی پی شوما سی هر گاتی کاٛ آلشتکاری بٱکیت سی کول خٱلک دیاری می کٱ. ٱر <strong>[$1 روئیت ڤامین]</strong> یا <strong>[$2 یاٛ گاٛل هساڤ کاریاری راس بٱکیت]</strong>، ڤیرایشتیا شوما ڤ نوم کاریاری خوتۊ دیاری می کٱ و سی شوما بیترٱ.",
        "revisionasof": "دوڤارٱ دیاٛن $1",
        "revision-info": "دوواره سیل بیه چی $1 وا $2",
        "previousrevision": "ڤانیٱری داٛمایی←",
-       "nextrevision": "ڤانئیأری تازە تئر",
-       "currentrevisionlink": "آخئرÛ\8c Ú¤Ø§Ù\86ئÛ\8cØ£ری",
+       "nextrevision": "ڤانیٱری تازٱتر",
+       "currentrevisionlink": "آخرÛ\8c Ú¤Ø§Ù\86Û\8cÙ±ری",
        "cur": "تازٱ باۋ",
        "next": "نئهایی",
        "last": "داٛمایی",
        "rcshowhidebots-show": "نشۊ دٱئن",
        "rcshowhidebots-hide": "قام کردن",
        "rcshowhideliu": "$1 کاریاریا ثوت نام کرده",
-       "rcshowhideliu-show": "Ù\86ئشÙ\88Ù\99 Ø¯Ø£ئن",
+       "rcshowhideliu-show": "Ù\86Ø´Û\8a Ø¯Ù±ئن",
        "rcshowhideliu-hide": "قام کئردئن",
        "rcshowhideanons": "کاریار نادیار $1",
        "rcshowhideanons-show": "نئشوٙ دأئن",
        "rc-enhanced-expand": "جزيات نشون بيئه",
        "rc-enhanced-hide": "جزياته قام كو",
        "rc-old-title": "ذاتا چی \"$1\" راس بیه",
-       "recentchangeslinked": "آلشتیا تی یکی",
+       "recentchangeslinked": "آلشتیا تی یٱکی",
        "recentchangeslinked-feed": "آلشتیا تی یکی",
        "recentchangeslinked-toolbox": "آلشتیا تاٛ یٱک",
        "recentchangeslinked-title": "آلشتیا تاٛ یکی د $1",
        "recentchangeslinked-summary": "ای نوم بلگٱ تازٱ د بلگٱیایی کاٛ ۋا بلگٱیا ۋیجٱ هوم پیۋند بینٱ آلشت بیٱ(یا سی ٱندومیا دٱسٱ بٱنی بیٱ)\nبلگٱیایی کاٛ هان د [[Special:Watchlist|your watchlist]]و گٱپ بینٱ",
-       "recentchangeslinked-page": "نوم بألگە:",
+       "recentchangeslinked-page": "نوم بلگٱ:",
        "recentchangeslinked-to": "آلشتیایی که د بلگه یا هوم پیوند بینه وه جا بلگه دئیه بیه نشو بیه",
        "recentchanges-page-added-to-category": "[[:$1]]د دأسە ئضاف بی",
        "recentchanges-page-added-to-category-bundled": "[[:$1]] و {{PLURAL:$2|بألگە تأکی|$2 بألگە یا}} د دأسە ئضاف بییئن",
        "usermessage-summary": "رئتن د سامونه پیغوم",
        "usermessage-editor": "پیغوم فرسن سیستم",
        "usermessage-template": "ویکی وارسگر:پیغوم کاریار",
-       "watchlist": "ساÙ\9bیل برگ",
+       "watchlist": "سئیل برگ",
        "mywatchlist": "ساٛیل برگ",
        "watchlistfor2": "سي $1 $2",
        "nowatchlist": "شما هیچی د سیل برگ خوتو ناریت",
        "undelete-show-file-confirm": "آیا یه دل بئیته که میهایت یه گل نسقه پاکسا بیه د جانیا \"<nowiki>$1</nowiki>\" که ها د ویرگار $2 ساعت $3 نه سیل بکیت؟",
        "undelete-show-file-submit": "هأری",
        "namespace": "نوم جا:",
-       "invert": "انتخاو برعسك بوئه",
+       "invert": "گولڤورچی بیئن بٱرٱسگ بۊٱ",
        "tooltip-invert": "د ری ای جعوه بپورنیت و آلشتیایی نه که د مینجا نوم ورگه انتخاو بیه انجوم بینه قام بکیت(و ار نوم ورگه شریکی وارسی بیه)",
        "tooltip-whatlinkshere-invert": "ای جعون نه سی نهو کردن هوم پیوند بلگه یایی که نوم جاشو انتخاو بیه، انتخاو بکیت.",
        "namespace_association": "نوم جایا یکاگرته",
        "sp-contributions-newbies": "فقط هومیاری یایی که د حساو تازه بیه نشون بئه",
        "sp-contributions-newbies-sub": "سی حساویا تازه",
        "sp-contributions-newbies-title": "هومیاریا کاریار سی حساویا تازه",
-       "sp-contributions-blocklog": "Ù\82Ù\84Ù\81",
+       "sp-contributions-blocklog": "Ù¾Ù\87رستÙ\86Û\8aÙ\85Ù± Ù\82Ù\88Ù\84Ù\81 Ø¨Û\8cÙ±",
        "sp-contributions-suppresslog": "پاکساگری کردن هومیاریا کاریار",
        "sp-contributions-deleted": "هومیاریا پاکسا بیه کاریار",
        "sp-contributions-uploads": "سواركرديا",
        "whatlinkshere": "کوم هوم پیۋندیا هان ایچاٛ",
        "whatlinkshere-title": "بلگه ای که د $1 هوم پیوند بیه",
        "whatlinkshere-page": "بلگٱ",
-       "linkshere": "بلگیا نهایی د '''[[:$1]]''' هوم پیوند بیه",
-       "nolinkshere": "هیژ بگله ای د  '''[[:$1]]''' هوم پیوند نبیه",
-       "nolinkshere-ns": "هیچ بلگه ای د نومجا انتخاو بیه وه'''[[:$1]]''' هوم پیوند ناره.",
+       "linkshere-2": "بلگیا نهایی د '''$1''' هوم پیوند بیه",
+       "nolinkshere-2": "هیژ بگله ای د  '''$1''' هوم پیوند نبیه",
+       "nolinkshere-ns-2": "هیچ بلگه ای د نومجا انتخاو بیه وه'''$1''' هوم پیوند ناره.",
        "isredirect": "بلگه دوباره ورگشتن",
        "istemplate": "نشونی دئن",
        "isimage": "جانیا هوم پیوند",
        "blocklist-nousertalk": "نبوئه بلگه چک چنه خوتونه ویرایشت بکید",
        "ipblocklist-empty": "جاگه نوم گه حالیه",
        "ipblocklist-no-results": "دسرسی نوم کاریاری یا تیرنشون آی پی حاسته بیه نهاگری نبیه.",
-       "blocklink": "ناٛهاگری بۊٱ",
+       "blocklink": "نهاگری بۊٱ",
        "unblocklink": "بی قطی",
        "change-blocklink": "اجازه نديئن سی  آلشت",
        "contribslink": "هومیاریا",
        "tooltip-pt-login": "ایما مۊئیم کاٛ رۊئیت ڤامین سامۊنگٱ؛ ڤلی ای کار اٛژبار ینی.",
        "tooltip-pt-logout": "د سامونه دراومائن",
        "tooltip-pt-createaccount": "شوما تشڤیق بیتٱ کاٛ یاٛ گاٛل هساڤ راست بکیت و بیایت ڤامین؛ د هر جۊر ای کار اٛژباری نی.",
-       "tooltip-ca-talk": "قسٱ داٛبارٱ مینۊنٱ بلگٱ.",
+       "tooltip-ca-talk": "قسٱ دائبارٱ مینۊنٱ بلگٱ.",
        "tooltip-ca-edit": "ڤیرایشت ای بلگٱ",
        "tooltip-ca-addsection": "د یه گل بهرجا هنی شرو بک",
        "tooltip-ca-viewsource": "ای بلگه پر و پیم بيه.\nشما تونيت سرچمه ش بئوينيت",
        "pageinfo-redirectsto": "واگردونی سی",
        "pageinfo-redirectsto-info": "دونسمنیا",
        "pageinfo-contentpage": "اشمارده بیه وه عنوان مینونه بلگه",
-       "pageinfo-contentpage-yes": "Ù\87رÛ\8c",
+       "pageinfo-contentpage-yes": "Ù±",
        "pageinfo-protect-cascading": "پر و پیم بیین تافنمایی د ایچه",
        "pageinfo-protect-cascading-yes": "هری",
        "pageinfo-protect-cascading-from": "پر و پیم بیین تافنمایی د",
        "exif-urgency-low": "هار ($1)",
        "exif-urgency-high": "بلنگ ($1)",
        "exif-urgency-other": "اول کاری تعریف بیه وه دس کاریار($1)",
-       "namespacesall": "Ù\87Ù\85Ù\87 Ø´Ù\88",
-       "monthsall": "Ù\87Ù\85Ù\87",
+       "namespacesall": "Ù\87Ù±Ù\85ٱشÛ\8a",
+       "monthsall": "Ù\87Ù±Ù\85Ù±",
        "confirmemail": "پشت راس کردن تیرنشون انجومانامه",
        "confirmemail_noemail": "شما د بلگه [[Special:Preferences|ترجیحات کاریاری]] خوتو یه گل تیرنشون انجومانامه نامعتور نه دئیته.",
        "confirmemail_text": "ای ویکی، شما نه مژبور می که وه پشت راسکاری تیرنشون انجومانامه خوتو، دما د یه که خدمات انجومانامه نه وه کار د ایچه وه کار بئیریت می که.دگمه هاری نه کنشتیار بکیت تا یه گل انجومانامه پشت راسکاری سی تیرنشون انجومانامه شما کل بوئه. ای انجومانامه د ور گرته یه گل رازینه ئه. هوم پیوند نه د دوارته نیئر خوتو واز بکیت تا تیرنشون انجومانامه تو پشت راسکاری با.",
        "fileduplicatesearch-noresults": "جانیایی وا نوم «$1» یافت نبی.",
        "specialpages": "بلگٱیا ڤیجٱ",
        "specialpages-note-top": "میراث",
+       "specialpages-note-restricted": "* بلگه یا ویجه عادی.\n* <span class=\"mw-specialpagerestricted\">بلگه یا ویجه محدود کاری بیه.</span>",
        "specialpages-group-maintenance": "گزارشتیا واداشتن",
        "specialpages-group-other": "بلگه یا ویجه هنی",
        "specialpages-group-login": " اومائن د سيستم/راس كردن حساو",
index 5bd4131..4387feb 100644 (file)
        "createacct-benefit-heading": "{{SITENAME}} kuria tokie žmonės kaip Jūs.",
        "createacct-benefit-body1": "{{PLURAL:$1|keitimas|keitimai|keitimų}}",
        "createacct-benefit-body2": "{{PLURAL:$1|puslapis|puslapiai|puslapių}}",
-       "createacct-benefit-body3": "Neseni {{PLURAL:$1|autorius|autoriai|autorių}}",
+       "createacct-benefit-body3": "{{PLURAL:$1|aktyvus naudotojas|aktyvūs naudotojai|aktyvių naudotojų}}",
        "badretype": "Įvesti slaptažodžiai nesutampa.",
        "usernameinprogress": "Profilio kūrimas šiam naudotojo vardui jau vyksta.\nPrašome palaukti.",
        "userexists": "Įvestasis naudotojo vardas jau naudojamas.\nPrašome pasirinkti kitą vardą.",
        "action-applychangetags": "taikyti žymes kartu su savo pokeitymais",
        "action-changetags": "pridėti ir ištrinti savavališkas žymes individualiuose pakeitimuose ir žurnalo įrašuose",
        "action-deletechangetags": "trinti žymes iš duomenų bazės",
+       "action-purge": "išvalyti puslapio podėlį",
        "nchanges": "$1 {{PLURAL:$1|pakeitimas|pakeitimai|pakeitimų}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|nuo paskutinio apsilankymo}}",
        "enhancedrc-history": "istorija",
        "rcfilters-watchlist-showupdated": "Puslapiai pakeisti nuo tada, kai paskutinį kartą apsilankėte juose, yra <strong>paryškinti</strong>.",
        "rcfilters-preference-label": "Slėpti patobulintą naujausių pakeitimų versiją",
        "rcfilters-filter-showlinkedfrom-label": "Rodyti pakeitimus puslapiuose, iš kurių esate nukreipti",
+       "rcfilters-filter-showlinkedfrom-option-label": "<strong>Puslapiai su nuorodomis iš</strong> pasirinkto puslapio",
        "rcfilters-filter-showlinkedto-label": "Rodyti pakeitimus puslapiuose, kurie nurodo į",
        "rcfilters-filter-showlinkedto-option-label": "<strong>Puslapiai su nuorodomis į</strong> pasirinktą puslapį",
        "rcfilters-target-page-placeholder": "Įveskite puslapio pavadinimą (arba kategoriją)",
        "recentchangeslinked-feed": "Susiję keitimai",
        "recentchangeslinked-toolbox": "Susiję keitimai",
        "recentchangeslinked-title": "Su „$1“ susiję keitimai",
-       "recentchangeslinked-summary": "Įveskite puslapio pavadinimą, jei norite matyti keitimus, atliktus puslapiuose, į kuriuos yra nuoroda į arba iš nurodyto puslapio. (Jei norite ieškoti nurodytos kategorijos narius, įveskite Kategorija:Kategorijos pavadinimas). Puslapiai iš jūsų [[Special:Watchlist|stebimųjų sąrašo]] yra <strong>paryškinti</strong>.",
+       "recentchangeslinked-summary": "Įveskite puslapio pavadinimą, jei norite matyti keitimus, atliktus puslapiuose, į kuriuos yra nuoroda į arba iš nurodyto puslapio. (Jei norite ieškoti nurodytos kategorijos narius, įveskite {{ns:category}}:Kategorijos pavadinimas). Puslapiai iš jūsų [[Special:Watchlist|stebimųjų sąrašo]] yra <strong>paryškinti</strong>.",
        "recentchangeslinked-page": "Puslapio pavadinimas:",
        "recentchangeslinked-to": "Rodyti su duotuoju puslapiu susijusių puslapių pakeitimus",
        "recentchanges-page-added-to-category": "[[:$1]] pridėta prie kategorijos",
        "whatlinkshere": "Susiję puslapiai",
        "whatlinkshere-title": "Puslapiai, kurie nurodo į „$1“",
        "whatlinkshere-page": "Puslapis:",
-       "linkshere": "Šie puslapiai rodo į '''[[:$1]]''':",
-       "nolinkshere": "Į '''[[:$1]]''' nuorodų nėra.",
-       "nolinkshere-ns": "Nurodytoje vardų srityje nei vienas puslapis nenurodo į '''[[:$1]]'''.",
+       "linkshere-2": "Šie puslapiai rodo į '''$1''':",
+       "nolinkshere-2": "Į '''$1''' nuorodų nėra.",
+       "nolinkshere-ns-2": "Nurodytoje vardų srityje nei vienas puslapis nenurodo į '''$1'''.",
        "isredirect": "nukreipiamasis puslapis",
        "istemplate": "įterpimas",
        "isimage": "rinkmenos nuoroda",
        "fileduplicatesearch-noresults": "Nėra failo pavadinimu \"$1\".",
        "specialpages": "Specialieji puslapiai",
        "specialpages-note-top": "Paaiškinimai",
+       "specialpages-note-restricted": "* Įprasti specialieji puslapiai.\n* <span class=\"mw-specialpagerestricted\">Apriboto pasiekiamumo specialieji puslapiai.</span>",
        "specialpages-group-maintenance": "Sistemos palaikymo pranešimai",
        "specialpages-group-other": "Kiti specialieji puslapiai",
        "specialpages-group-login": "Prisijungti / sukurti paskyrą",
        "gotointerwiki-invalid": "Nurodytas pavadinimas negalimas.",
        "undelete-cantedit": "Negalite atkurti šio puslapio, nes jums neleidžiama redaguoti šio puslapio.",
        "pagedata-title": "Puslapio duomenys",
-       "pagedata-bad-title": "Negalimas pavadinimas: $1."
+       "pagedata-bad-title": "Negalimas pavadinimas: $1.",
+       "passwordpolicies-group": "Grupė"
 }
index b5f808b..ea4bd74 100644 (file)
        "whatlinkshere": "Sasītuos nūruodis",
        "whatlinkshere-title": "Lopys, kuramuos ir saitis iz lopu $1",
        "whatlinkshere-page": "Puslopa:",
-       "linkshere": "Itamuos lopuos ir nūruodis iz lopu '''[[:$1]]''':",
+       "linkshere-2": "Itamuos lopuos ir nūruodis iz lopu '''$1''':",
        "isredirect": "puoradresiešonys puslopa",
        "istemplate": "izsaukts",
        "isimage": "Faila saita",
index 27511a3..97c76b0 100644 (file)
        "whatlinkshere": "Hemi zawmpuite",
        "whatlinkshere-title": "$1-a thlunzawm phêkte",
        "whatlinkshere-page": "Phêk:",
-       "linkshere": "A hnuaia phêkte hian '''[[:$1]]''' hi an thlunzawm:",
-       "nolinkshere": "'''[[:$1]]'''-a zawm phek pakhat mah a awm lo.",
+       "linkshere-2": "A hnuaia phêkte hian '''$1''' hi an thlunzawm:",
+       "nolinkshere-2": "'''$1'''-a zawm phek pakhat mah a awm lo.",
        "isredirect": "Hruailuhna phêk",
        "istemplate": "ziahhnan",
        "isimage": "taksa thlunzawmna",
index 6d099bf..a474cd4 100644 (file)
        "whatlinkshere": "لینکل ئی بألگە",
        "whatlinkshere-title": "بألگل کە لینک دائنە ڤە \"$1\"",
        "whatlinkshere-page": "بألگە:",
-       "linkshere": "لینک ھ بألگل دوٙمین الذیکر ڤە '''[[:$1]]''':",
+       "linkshere-2": "لینک ھ بألگل دوٙمین الذیکر ڤە '''$1''':",
        "isredirect": "بألگە تأغییر مأسیر",
        "istemplate": "ئیستیفادھ ڤابیدھ داخل بألگە",
        "isimage": "لینک ھ فایل",
index 0c88fe6..2edaca7 100644 (file)
        "user-mail-no-addy": "Mēģināja sūtīt e-pastu bez e-pasta adreses.",
        "user-mail-no-body": "Mēģināja sūtīt e-pastu ar tukšu vai nepamatoti īsu pamata daļu.",
        "changepassword": "Mainīt paroli",
+       "resetpass_announce": "Lai pabeigtu pieslēgšanos, tev ir jāuzstāda jauna parole.",
        "resetpass_header": "Mainīt konta paroli",
        "oldpassword": "Vecā parole",
        "newpassword": "Jaunā parole",
        "retypenew": "Atkārto jauno paroli",
        "resetpass_submit": "Uzstādīt paroli un ieiet",
        "changepassword-success": "Tava parole tika nomainīta!",
+       "changepassword-throttled": "Jūs esat veicis pārāk daudz pieslēgšanās mēģinājumus.\nLūdzu, uzgaidiet $1 pirms mēģiniet vēlreiz.",
        "botpasswords": "Botu paroles",
        "botpasswords-disabled": "Botu paroles ir atspējotas.",
        "botpasswords-no-central-id": "Lai izmantotu botu paroles, tev jāpieslēdzas centralizētajam kontam.",
        "history-feed-description": "Šīs wiki lapas versiju hronoloģija",
        "history-feed-item-nocomment": "$1 : $2",
        "history-feed-empty": "Pieprasītā lapa nepastāv.\nIespējams, tā ir izdzēsta vai pārdēvēta.\nMēģiniet [[Special:Search|meklēt]], lai atrastu saistītas lapas!",
+       "history-edit-tags": "Labot iezīmes izvēlētajām versijām",
        "rev-deleted-comment": "(labojuma kopsavilkums dzēsts)",
        "rev-deleted-user": "(lietotāja vārds nodzēsts)",
        "rev-deleted-event": "(reģistra detaļas noņemtas)",
        "search-category": "(kategorija $1)",
        "search-file-match": "(atbilst faila saturam)",
        "search-suggest": "Vai jūs domājāt: $1",
+       "search-rewritten": "Rāda rezultātus frāzei \"$1\". Meklēt pēc \"$2\".",
        "search-interwiki-caption": "Rezultāti no citiem projektiem",
        "search-interwiki-default": "Rezultāti no $1:",
        "search-interwiki-more": "(vairāk)",
        "default": "pēc noklusējuma",
        "prefs-files": "Faili",
        "prefs-custom-css": "Personīgais CSS",
+       "prefs-custom-json": "Pielāgots JSON",
        "prefs-custom-js": "Personīgais JS",
        "prefs-common-config": "Koplietojams CSS/JavaScript visās apdarēs:",
        "prefs-emailconfirm-label": "E-pasta statuss:",
        "right-editcontentmodel": "Labot lapas satura modeli",
        "right-editinterface": "Izmainīt dalībnieka interfeisu",
        "right-editusercss": "Izmainīt citu dalībnieku CSS failus",
+       "right-edituserjson": "Izmainīt citu dalībnieku JSON failus",
        "right-edituserjs": "Izmainīt citu dalībnieku JS failus",
        "right-editmyusercss": "Rediģējiet savus dalībnieka CSS failus",
+       "right-editmyuserjson": "Izmainīt savus dalībnieka JSON failus",
        "right-editmyuserjs": "Rediģējiet savus dalībnieka JavaScript failus",
        "right-viewmywatchlist": "Apskatīt savu uzraugāmo rakstu sarakstu",
        "right-viewmyprivateinfo": "Skatit savus privātos datus (piemēram, e-pasta adresi, īsto vārdu)",
        "recentchangeslinked-feed": "Saistītās izmaiņas",
        "recentchangeslinked-toolbox": "Saistītās izmaiņas",
        "recentchangeslinked-title": "Izmaiņas, kas saistītas ar \"$1\"",
-       "recentchangeslinked-summary": "Šiet ir nesen izdarītās izmaiņas lapās, uz kurām ir saites no norādītās lapas (vai norādītajā kategorijā ietilpstošās lapas).\nLapas, kas ir tavā [[Special:Watchlist|uzraugāmo rakstu sarakstā]] ir '''treknas'''.",
+       "recentchangeslinked-summary": "Ievadi lapas nosaukumu, lai redzētu izmaiņas lapās, uz kurām vai vai no kuras ir saites ar šo lapu (Lai redzētu kategorijā ietilpstošās, norādi {{ns:category}}:Kategorijas nosaukums).\nIzmaiņas lapās, kas ir tavā [[Special:Watchlist|uzraugāmo rakstu sarakstā]] ir <strong>treknrakstā</strong>.",
        "recentchangeslinked-page": "Lapas nosaukums:",
        "recentchangeslinked-to": "Rādīt izmaiņas lapās, kurās ir saites uz šo lapu (nevis lapās uz kurām ir saites no šīs lapas)",
        "autochange-username": "MediaWiki automātiskā izmaiņa",
        "upload-misc-error": "Nezināma augšupielādes kļūda",
        "upload-too-many-redirects": "URL sastāvēja pārāk daudz pāradresāciju",
        "upload-http-error": "HTTP kļūda: $1",
+       "upload-copy-upload-invalid-domain": "Kopēšanas augšupielādes no šī domēna nav pieejamas.",
        "upload-dialog-title": "Augšupielādēt failu",
        "upload-dialog-button-cancel": "Atcelt",
        "upload-dialog-button-back": "Atpakaļ",
        "uploadstash-errclear": "Failu tīrīšana neizdevās.",
        "uploadstash-refresh": "Atsvaidzināt failu sarakstu",
        "uploadstash-thumbnail": "aplūkot sīkbildi",
+       "uploadstash-bad-path": "Ceļš nepastāv.",
+       "uploadstash-bad-path-invalid": "Ceļš nav derīgs.",
        "uploadstash-bad-path-unknown-type": "Nezināms tips \"$1\".",
        "uploadstash-bad-path-unrecognized-thumb-name": "Neatpazīts sīktēla nosaukums.",
        "uploadstash-file-not-found-no-thumb": "Nevarēja iegūt sīkbildi.",
        "http-invalid-url": "Nederīgs URL: $1",
        "http-read-error": "HTTP nolasīšanas kļūda.",
        "http-timed-out": "HTTP pieprasījumam ir iestājies noilgums.",
+       "http-curl-error": "Kļūda, nolasot URL: $1",
+       "http-bad-status": "HTTP pieprasījuma laikā atgadījās problēma: $1 $2",
        "upload-curl-error6": "URL nevarēja sasniegt",
        "upload-curl-error28": "Augšupielādes noildze",
        "license": "Licence:",
        "nolicense": "Neviena licence nav izvēlēta",
        "licenses-edit": "Labot licenču izvēles",
        "license-nopreview": "(Priekšskatījums nav pieejams)",
-       "upload_source_url": "(derīgs, publiski pieejams URL)",
+       "upload_source_url": "(tavs izvēlēts fails no derīga, publiski pieejama URL)",
        "upload_source_file": "(tavs izvēlētais fails tavā datorā)",
        "listfiles-delete": "dzēst",
        "listfiles-summary": "Šajā īpašajā lapā ir redzami visi augšupielādētie faili.",
        "nolinkstoimage": "Nevienā lapā nav norāžu uz šo attēlu.",
        "morelinkstoimage": "Skatīt [[Special:WhatLinksHere/$1|vairāk saites]] uz šo failu.",
        "linkstoimage-redirect": "$1 (faila pāradresācija) $2",
+       "duplicatesoffile": "{{PLURAL:$1|1=Šis fails ir šī faila dublikāts|Šie $1 faili ir šī faila dublikāti|Šis $1 fails ir šī faila dublikāts|Šie $1 faili ir šī faila dublikāti}} ([[Special:FileDuplicateSearch/$2|vairāk informācijas]]):",
        "sharedupload": "Šis fails ir augšupielādēts no $1 un ir koplietojams citos projektos.",
        "sharedupload-desc-there": "Fails ir no $1, tāpēc tas var tikt izmantots citos projektos.\nLūdzu, skatīt [$2 faila apraksta lapu] papildu informācijai.",
        "sharedupload-desc-here": "Fails ir no $1, tāpēc tas var tikt izmantots citos projektos.\nApraksts ir [$2 faila apraksta lapā], kas ir parādīta zemāk.",
+       "sharedupload-desc-edit": "Šis fails ir no $1 un var tikt izmantots citos projektos.\nTu vari labot tā aprakstu [$2 faila apraksta lapā].",
        "filepage-nofile": "Ar šādu nosaukumu nav neviena faila.",
        "filepage-nofile-link": "Ar šādu nosaukumu nav neviena faila, bet Jūs varat tādu [$1 augšupielādēt].",
        "uploadnewversion-linktext": "Augšupielādēt jaunu šī faila versiju",
        "randompage": "Nejauša lapa",
        "randomincategory": "Nejauša lapa kategorijā",
        "randomincategory-invalidcategory": "\"$1\" nav derīgs kategorijas nosaukums.",
+       "randomincategory-nopages": "Kategorijā [[:Category:$1|$1]] nav lapu.",
        "randomincategory-category": "Kategorija:",
        "randomincategory-legend": "Nejauša lapa kategorijā",
        "randomincategory-submit": "Aiziet!",
        "statistics-users": "Reģistrēti dalībnieki",
        "statistics-users-active": "Aktīvi lietotāji",
        "statistics-users-active-desc": "Lietotāji, kas ir veikuši jebkādu darbību {{PLURAL:$1|iepriekšējās $1 dienās|iepriekšējā $1 dienā|iepriekšējās $1 dienās}}",
+       "pageswithprop": "Lapas ar lapas īpašību",
+       "pageswithprop-legend": "Lapas ar lapas īpašību",
+       "pageswithprop-text": "Šajā lapā uzskaitītas lapas ar konkrētu lapas īpašību.",
        "pageswithprop-prop": "Īpašības nosaukums:",
+       "pageswithprop-reverse": "Kārtot apgrieztā secībā",
+       "pageswithprop-sortbyvalue": "Kārtot pēc īpašības vērības",
        "pageswithprop-submit": "Aiziet",
        "doubleredirects": "Divkāršas pāradresācijas lapas",
        "doubleredirectstext": "Šajā lapā ir uzskaitītas pāradresācijas lapas, kuras pāradresē uz citām pāradresācijas lapām.\nKatrā rindiņā ir saites uz pirmo un otro pāradresācijas lapu, kā arī pirmā rindiņa no otrās pāradresācijas lapas teksta, kas parasti ir faktiskā \"gala\" lapa, uz kuru vajadzētu būt saitei pirmajā lapā.\n<del>Nosvītrotie</del> ieraksti jau ir tikuši salaboti.",
        "listgrouprights-namespaceprotection-header": "Vārdtelpas ierobežojumi",
        "listgrouprights-namespaceprotection-namespace": "Vārdtelpa",
        "listgrants-rights": "Tiesības",
+       "trackingcategories": "Izsekošanas kategorijas",
+       "trackingcategories-msg": "Izsekošanas kategorija",
        "trackingcategories-nodesc": "Apraksts nav pieejams.",
        "trackingcategories-disabled": "Kategorija ir atslēgta",
        "mailnologin": "Nav adreses, uz kuru sūtīt",
        "whatlinkshere": "Norādes uz šo rakstu",
        "whatlinkshere-title": "Lapas, kurās ir saites uz lapu \"$1\"",
        "whatlinkshere-page": "Lapa:",
-       "linkshere": "Šajās lapās ir norādes uz lapu '''[[:$1]]''':",
-       "nolinkshere": "Nevienā lapā nav norāžu uz lapu '''[[:$1]]'''.",
-       "nolinkshere-ns": "Neviena lapa nenorāda uz '''[[:$1]]''' izvēlētajā vārdtelpā.",
+       "linkshere-2": "Šajās lapās ir norādes uz lapu '''$1''':",
+       "nolinkshere-2": "Nevienā lapā nav norāžu uz lapu '''$1'''.",
+       "nolinkshere-ns-2": "Neviena lapa nenorāda uz '''$1''' izvēlētajā vārdtelpā.",
        "isredirect": "pāradresācijas lapa",
        "istemplate": "izsaukts",
        "isimage": "faila saite",
        "import-interwiki-submit": "Importēt",
        "import-mapping-namespace": "Importēt vārdtelpā:",
        "import-upload-filename": "Faila nosaukums:",
+       "import-upload-username-prefix": "Starpviki prefikss:",
        "import-comment": "Komentārs:",
        "importstart": "Importē lapas...",
        "import-revision-count": "$1 {{PLURAL:$1|versijas|versija|versijas}}",
        "patrol-log-header": "Šis ir pārbaudīto versiju reģistrs.",
        "log-show-hide-patrol": "$1 pārbaudes reģistrs",
        "confirm-markpatrolled-button": "Labi",
+       "confirm-markpatrolled-top": "Atzīmēt lapas \"$2\" versiju $3 kā pārbaudītu?",
        "deletedrevision": "Izdzēstā vecā versija $1",
        "filedeleteerror-short": "Kļūda dzēšot failu: $1",
        "filedeleteerror-long": "Kļūdas, kas radās failu dzēšanas laikā:\n\n$1",
        "newimages-newbies": "Rādīt tikai jaunu dalībnieku devumu",
        "newimages-showbots": "Parādīt botu augšupielādētos failus",
        "newimages-hidepatrolled": "Paslēpt pārbaudītās augšupielādes",
+       "newimages-mediatype": "Medija veids:",
        "noimages": "Nav nekā ko redzēt.",
        "gallery-slideshow-toggle": "Pārslēgt sīktēlus",
        "ilsubmit": "Meklēt",
        "exif-exposureprogram-8": "Ainavu režīms (ainavu fotogrāfijām ar fokusu uz fonu)",
        "exif-subjectdistance-value": "$1 metri",
        "exif-meteringmode-0": "Nav zināms",
+       "exif-meteringmode-3": "Punkta",
+       "exif-meteringmode-4": "Vairāku punktu",
        "exif-meteringmode-255": "Cits",
        "exif-lightsource-0": "Nav zināms",
        "exif-lightsource-1": "Dienas gaisma",
        "version-ext-colheader-license": "Licence",
        "version-ext-colheader-description": "Apraksts",
        "version-ext-colheader-credits": "Autori",
+       "version-license-title": "$1 licence",
+       "version-credits-title": "$1 ieguldījums",
        "version-poweredby-credits": "Šis viki darbojas ar '''[https://www.mediawiki.org/ MediaWiki]''' programmatūru, autortiesības © 2001-$1 $2.",
        "version-poweredby-others": "citi",
        "version-poweredby-translators": "translatewiki.net tulkotāji",
        "fileduplicatesearch-noresults": "Nav atrasts neviens fails ar nosaukumu \"$1\".",
        "specialpages": "Īpašās lapas",
        "specialpages-note-top": "Apzīmējumi",
+       "specialpages-note-restricted": "* Normālas īpašās lapas.\n* <span class=\"mw-specialpagerestricted\">Ierobežotas pieejas īpašās lapas.</span>\n* <span class=\"mw-specialpagecached\">Iekešotās īpašās lapas.</span>",
        "specialpages-group-maintenance": "Uzturēšanas atskaites",
        "specialpages-group-other": "Citas īpašās lapas",
        "specialpages-group-login": "Pieslēgties / izveidot kontu",
        "tag-mw-blank-description": "Labojumi, kas nodzēš lapas saturu",
        "tag-mw-replace": "Aizvietots",
        "tag-mw-replace-description": "Labojumi, kas izņem vairāk kā 90% no lapas satura",
+       "tag-mw-rollback": "Atcelšana",
        "tag-mw-undo": "Atsaukt",
        "tags-title": "Iezīmes",
        "tags-intro": "Šajā lapā uzskaitītas iezīmes, ar kurām programmatūra var atzīmēt labojumus, un to nozīme.",
        "tags-create-already-exists": "Iezīme \"$1\" jau pastāv.",
        "tags-delete-title": "Dzēst iezīmi",
        "tags-delete-reason": "Iemesls:",
+       "tags-delete-not-found": "Iezīme \"$1\" nepastāv.",
        "tags-delete-no-permission": "Tev nav atļaujas dzēst izmaiņu iezīmes.",
        "tags-activate-title": "Aktivizēt iezīmi",
        "tags-activate-reason": "Iemesls:",
+       "tags-activate-not-found": "Iezīme \"$1\" nepastāv.",
        "tags-activate-submit": "Aktivizēt",
        "tags-deactivate-title": "Deaktivizēt iezīmi",
        "tags-deactivate-reason": "Iemesls:",
        "tags-edit-add": "Visas šīs iezīmes:",
        "tags-edit-remove": "Noņemt šīs iezīmes:",
        "tags-edit-remove-all-tags": "(noņemt visas iezīmes)",
+       "tags-edit-chosen-placeholder": "Izvēlies dažas iezīmes",
        "tags-edit-reason": "Iemesls:",
        "comparepages": "Salīdzināt lapas",
        "compare-page1": "1. lapa",
        "revdelete-restricted": "piemērot administratoriem ierobežojumus",
        "revdelete-unrestricted": "noņemt administratoriem ierobežojumus",
        "logentry-block-block": "$1 {{GENDER:$2|nobloķēja}} {{GENDER:$4|$3}} ar beigu termiņu $5 $6",
+       "logentry-block-unblock": "$1 {{GENDER:$2|atbloķēja}} {{GENDER:$4|$3}}",
        "logentry-move-move": "$1 {{GENDER:$2|pārvietoja}} lapu $3 uz $4",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|pārvietoja}} lapu $3 uz $4, neatstājot pāradresāciju",
        "logentry-move-move_redir": "$1 {{GENDER:$2|pārvietoja}} lapu $3 uz $4, atstājot pāradresāciju",
        "logentry-newusers-create": "Lietotāja konts $1 tika {{GENDER:$2|izveidots}}",
        "logentry-newusers-create2": "$1 {{GENDER:$2|izveidoja}} lietotāja kontu $3",
        "logentry-newusers-autocreate": "Lietotaja konts $1 tika {{GENDER:$2|izveidots}} automātiski",
+       "logentry-protect-unprotect": "$1 {{GENDER:$2|noņēma}} aizsardzību no $3",
        "logentry-protect-protect": "$1 {{GENDER:$2|aizsargāja}} $3 $4",
        "logentry-upload-upload": "$1 {{GENDER:$2|augšupielādēja}} $3",
        "logentry-upload-overwrite": "$1 augšupielādēja jaunu $3 versiju",
        "duration-centuries": "$1 {{PLURAL:$1|gadsimti|gadsimts|gadsimti}}",
        "duration-millennia": "$1 {{PLURAL:$1|tūkstošgades|tūkstošgade|tūkstošgades}}",
        "limitreport-title": "Parsētāja profilēšanas dati:",
+       "limitreport-cputime": "CPU laika lietojums",
        "limitreport-cputime-value": "$1 {{PLURAL:$1|sekundes|sekunde|sekundes}}",
+       "limitreport-walltime": "Reālā laika lietojums",
        "limitreport-walltime-value": "$1 {{PLURAL:$1|sekundes|sekunde|sekundes}}",
        "limitreport-postexpandincludesize-value": "$1/$2 {{PLURAL:$2|baiti|baits|baiti}}",
        "limitreport-templateargumentsize": "Veidnes argumenta izmērs",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (iespējots)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 (<strong>atspējots</strong>)",
        "mediastatistics-table-mimetype": "MIME tips",
+       "mediastatistics-table-extensions": "Iespējamie paplašinājumi",
        "mediastatistics-table-count": "Failu skaits",
        "mediastatistics-table-totalbytes": "Kopējais izmērs",
        "mediastatistics-header-unknown": "Nav zināms",
        "mediastatistics-header-drawing": "Zīmējumi (vector attēli)",
        "mediastatistics-header-audio": "Audio",
        "mediastatistics-header-video": "Video",
+       "mediastatistics-header-office": "Ofisa",
+       "mediastatistics-header-text": "Teksta",
+       "mediastatistics-header-executable": "Izpildāmi",
+       "mediastatistics-header-archive": "Arhīva formāti",
        "mediastatistics-header-total": "Visi faili",
        "json-error-syntax": "Sintakses kļūda",
        "headline-anchor-title": "Saite uz šo sadaļu",
        "special-characters-group-persian": "Persiešu",
        "special-characters-group-hebrew": "Ebreju",
        "special-characters-group-bangla": "Bengāļu",
+       "special-characters-group-tamil": "Tamilu",
        "special-characters-group-telugu": "Telugu",
        "special-characters-group-sinhala": "Singāļu",
        "special-characters-group-gujarati": "Gudžarati",
        "sessionprovider-generic": "$1 sesijas",
        "randomrootpage": "Nejauša saknes lapa",
        "log-action-filter-suppress": "Cenzēšanas veids:",
+       "log-action-filter-upload": "Augšupielādes veids:",
+       "log-action-filter-block-unblock": "Atbloķēšana",
        "log-action-filter-delete-delete": "Lapas dzēšana",
        "log-action-filter-managetags-create": "Iezīmes izveide",
        "log-action-filter-managetags-delete": "Iezīmes dzēšana",
index c694116..6f9503b 100644 (file)
        "recentchanges-label-plusminus": "所改字節量",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}}([[Special:NewPages|新灶]])",
        "recentchanges-submit": "示",
+       "rcfilters-savedqueries-defaultlabel": "所貯條件",
+       "rcfilters-show-new-changes": "知新",
        "rcnotefrom": "下為自'''$2'''至'''$1'''之易也。",
        "rclistfrom": "自$3 $2起之易也",
        "rcshowhideminor": "$1校",
        "whatlinkshere": "取佐",
        "whatlinkshere-title": "「$1」取佐",
        "whatlinkshere-page": "題",
-       "linkshere": "取佐'''[[:$1]]'''如下:",
-       "nolinkshere": "無頁取佐'''[[:$1]]'''。",
-       "nolinkshere-ns": "名冊內無頁取佐'''[[:$1]]'''。",
+       "linkshere-2": "取佐'''$1'''如下:",
+       "nolinkshere-2": "無頁取佐'''$1'''。",
+       "nolinkshere-ns-2": "名冊內無頁取佐'''$1'''。",
        "isredirect": "渡",
        "istemplate": "含",
        "isimage": "檔佐",
        "fileduplicatesearch-result-1": "案 \"$1\" 無重也。",
        "fileduplicatesearch-result-n": "案 \"$1\" 重有$2。",
        "specialpages": "特查",
+       "specialpages-note-restricted": "* 準特查。\n* <strong class=\"mw-specialpagerestricted\">限特查。</strong>",
        "specialpages-group-maintenance": "護報",
        "specialpages-group-other": "他奇頁",
        "specialpages-group-login": "登/增",
        "htmlform-reset": "復",
        "htmlform-selectorother-other": "他",
        "logentry-delete-delete": "$1 {{GENDER:$2|已削}} 頁 $3",
+       "logentry-delete-revision": "$3一文,$1{{GENDER:$2|藏}}{{PLURAL:$5|a revision|更易凡$5筆}}: $4",
+       "logentry-suppress-revision": "$3一文,$1{{GENDER:$2|陰藏}}{{PLURAL:$5|a revision|更易凡$5筆}}: $4",
        "revdelete-restricted": "應限至有秩",
        "revdelete-unrestricted": "除限自有秩",
        "logentry-newusers-create": "簿$1已{{GENDER:$2|增}}。",
index c1f7582..381e60a 100644 (file)
        "whatlinkshere": "Butʼkʼaşa na ixvenu kʼontʼaktʼepe",
        "whatlinkshere-title": "\"$1\" maddeşa kʼontʼaktʼi na ikips butʼkʼape",
        "whatlinkshere-page": "Butʼkʼa:",
-       "linkshere": "'''[[:$1]]''' butʼkʼaşa kʼontʼaktʼi na ikips butʼkʼape:",
+       "linkshere-2": "'''$1''' butʼkʼaşa kʼontʼaktʼi na ikips butʼkʼape:",
        "isredirect": "redirektʼiş butʼkʼa",
        "istemplate": "okʼatu",
        "isimage": "dosyaşi kʼontʼaktʼi",
index 4dfda8f..63b2084 100644 (file)
        "whatlinkshere": "एतय कोन लिङ्क अछि",
        "whatlinkshere-title": "\"$1\" सँ सम्बन्धित पन्नासभ",
        "whatlinkshere-page": "पन्ना:",
-       "linkshere": "ई सभ पन्ना सम्बन्धित अछि '''[[:$1]]''':",
-       "nolinkshere": "'''[[:$1]]''' पर कोनो पन्नाक लागि नै अछि।",
-       "nolinkshere-ns": "कोनो पन्नाक लागि '''[[:$1]]''' चुनल नामगाममे नै अछि।",
+       "linkshere-2": "ई सभ पन्ना सम्बन्धित अछि '''$1''':",
+       "nolinkshere-2": "'''$1''' पर कोनो पन्नाक लागि नै अछि।",
+       "nolinkshere-ns-2": "कोनो पन्नाक लागि '''$1''' चुनल नामगाममे नै अछि।",
        "isredirect": "पुनर्निर्देशन पृष्ठ",
        "istemplate": "परागत",
        "isimage": "फाइल लिङ्क",
        "fileduplicatesearch-noresults": "कोनो \"$1\" नाम्ना संचिका नै।",
        "specialpages": "विशेष पन्नासभ",
        "specialpages-note-top": "कुंजी",
+       "specialpages-note-restricted": "* सामान्य विशिष्ट पन्ना।\n* <span class=\"mw-specialpagerestricted\">प्रतिबंधित विशिष्ट पन्ना।</span>\n* <span class=\"mw-specialpagecached\">उपस्मृतिक विशिष्ट पन्ना (पुरान भऽ सकैए)।</span>",
        "specialpages-group-maintenance": "सुस्थापन प्रतिवेदन",
        "specialpages-group-other": "दोसर विशेष पन्ना",
        "specialpages-group-login": "सम्प्रवेश/ सम्प्रवेश आवेदन",
index a08fb4e..c5b6f61 100644 (file)
        "whatlinkshere": "Pranala Kaca Kiye",
        "whatlinkshere-title": "Kaca-kaca sing duwe pranala maring \"$1\"",
        "whatlinkshere-page": "Kaca:",
-       "linkshere": "Kaca-kaca kiye duwe pranala maring '''[[:$1]]''':",
-       "nolinkshere": "Ora ana kaca sing nduwé pranala maring '''[[:$1]]'''.",
+       "linkshere-2": "Kaca-kaca kiye duwe pranala maring '''$1''':",
+       "nolinkshere-2": "Ora ana kaca sing nduwé pranala maring '''$1'''.",
        "isredirect": "kaca pangalihan",
        "istemplate": "karo cithakan",
        "isimage": "pranala berkas",
index 22a8eb8..e236da3 100644 (file)
        "whatlinkshere": "Сюлмафкст тяза",
        "whatlinkshere-title": "Лопат конат сюлмафт \"$1\" мархта",
        "whatlinkshere-page": "Лопа:",
-       "linkshere": "Ся лопатне сюлмафт '''[[:$1]]''' мархта:",
-       "nolinkshere": "Лопат, конат сюлмафт '''[[:$1]]''' мархта ашет.",
-       "nolinkshere-ns": "Аш лопат сюлмафт '''[[:$1]]''' мархта  кочкаф лемботмоста.",
+       "linkshere-2": "Ся лопатне сюлмафт '''$1''' мархта:",
+       "nolinkshere-2": "Лопат, конат сюлмафт '''$1''' мархта ашет.",
+       "nolinkshere-ns-2": "Аш лопат сюлмафт '''$1''' мархта  кочкаф лемботмоста.",
        "isredirect": "умборондафтф лопа",
        "istemplate": "сувафтома",
        "isimage": "↓архтофксонь сюлмафкссь",
        "fileduplicatesearch-result-1": "Файлть \"$1\" ашет тяконь кафонзамонза.",
        "fileduplicatesearch-result-n": "Файлть \"$1\" {{PLURAL:$2|1 тяконь кафонзамац|$2 тяконь кафонзаманза}}.",
        "specialpages": "Башка лопат",
+       "specialpages-note-restricted": "* Кърдань башка лопат.\n* <strong class=\"mw-specialpagerestricted\">Кардаф башка лопат.</strong>",
        "specialpages-group-maintenance": "Латцема лувоматне",
        "specialpages-group-other": "Иля башка тевонь лопатне",
        "specialpages-group-login": "Сувамс / сёрматфтомс",
index 22179fe..0467390 100644 (file)
        "whatlinkshere": "Pejy mirohy eto",
        "whatlinkshere-title": "Pejy mirohy any amin'i « $1 »",
        "whatlinkshere-page": "Pejy :",
-       "linkshere": "Ireo pejy ireo dia manana rohy mankany amin'i '''[[:$1]]'''",
-       "nolinkshere": "Tsy nahitana pejy mirohy any amin'i '''[[:$1]]'''.",
-       "nolinkshere-ns": "Tsy nahitana pejy mirohy any amin'i [[:$1]] ao amin'ny anaran-tsehatra nofidiana.",
+       "linkshere-2": "Ireo pejy ireo dia manana rohy mankany amin'i '''$1'''",
+       "nolinkshere-2": "Tsy nahitana pejy mirohy any amin'i '''$1'''.",
+       "nolinkshere-ns-2": "Tsy nahitana pejy mirohy any amin'i $1 ao amin'ny anaran-tsehatra nofidiana.",
        "isredirect": "pejy fihodinana",
        "istemplate": "tsofo-pejy",
        "isimage": "rohy mankany amin'ilay rakitra",
        "fileduplicatesearch-result-n": "Misy rakitra {{PLURAL:}}$2 mitovy amin'i « $1 ».",
        "specialpages": "Pejy manokana",
        "specialpages-note-top": "Maribolana",
+       "specialpages-note-restricted": "* Pejy manokana tsotra\n* <span class=\"mw-specialpagerestricted\">Pejy manokana voafetra ara-pijey.</span>",
        "specialpages-group-maintenance": "laogy hikojakojana",
        "specialpages-group-other": "Pejy manokana hafa",
        "specialpages-group-login": "Hiditra / hisoratra anarana",
index ab164a4..c9c2dc7 100644 (file)
        "whatlinkshere": "Тышке кондышо кылвер-влак",
        "whatlinkshere-title": "\"$1\" дене лаштык-влак кылым палемдат",
        "whatlinkshere-page": "Лаштык:",
-       "linkshere": "'''[[:$1]]''' лаштык дене кылдалтше лаштык-влак:",
-       "nolinkshere": "'''[[:$1]]''' лаштык дене тетла нимогай лаштык кылдалтын огыл",
-       "nolinkshere-ns": "Тыгай лӱм-влакын кумдыкышто '''[[:$1]]''' лаштык дене нимогай лаштык-влак огыт кылдалт.",
+       "linkshere-2": "'''$1''' лаштык дене кылдалтше лаштык-влак:",
+       "nolinkshere-2": "'''$1''' лаштык дене тетла нимогай лаштык кылдалтын огыл",
+       "nolinkshere-ns-2": "Тыгай лӱм-влакын кумдыкышто '''$1''' лаштык дене нимогай лаштык-влак огыт кылдалт.",
        "isredirect": "вес вере колтышо лаштык",
        "istemplate": "пуртымаш",
        "isimage": "файлыш кылвер",
index 62ccc4f..81c9e84 100644 (file)
        "whatlinkshere": "Pautan baliak",
        "whatlinkshere-title": "Laman nan takaik ka \"$1\"",
        "whatlinkshere-page": "Laman:",
-       "linkshere": "Laman-laman ko bakaik ka '''[[:$1]]''':",
-       "nolinkshere": "Indak ado laman nan punyo tautan ka '''[[:$1]]'''.",
-       "nolinkshere-ns": "Indak ado pautan laman ka '''[[:$1]]''' pado ruang namo nan dipiliah.",
+       "linkshere-2": "Laman-laman ko bakaik ka '''$1''':",
+       "nolinkshere-2": "Indak ado laman nan punyo tautan ka '''$1'''.",
+       "nolinkshere-ns-2": "Indak ado pautan laman ka '''$1''' pado ruang namo nan dipiliah.",
        "isredirect": "laman pangaliahan",
        "istemplate": "transklusi",
        "isimage": "pautan berkas",
        "fileduplicatesearch-result-n": "Berkas \"$1\" ado {{PLURAL:$2|$2 duplikat nan samo}}.",
        "fileduplicatesearch-noresults": "Indak basobok berkas banamo \"$1\".",
        "specialpages": "Laman istimewa",
+       "specialpages-note-restricted": "* Laman istimewa normal.\n* <span class=\"mw-specialpagerestricted\">Laman istimewa talarang.</span>\n* <span class=\"mw-specialpagecached\">Laman istimewa tasinggah (mungkin usang).</span>",
        "specialpages-group-maintenance": "Laporan pamaliharoan",
        "specialpages-group-other": "Lain-lain",
        "specialpages-group-login": "Masuak log / mandaftar",
index 7783806..b55fb55 100644 (file)
        "subject-preview": "Преглед на насловот:",
        "previewerrortext": "Се појави грешка при обидот да се прегледаат промените.",
        "blockedtitle": "Корисникот е блокиран",
-       "blockedtext": "'''Вашето корисничко име или IP-адреса е блокирано.'''\n\nБлокирањето е направено од страна на $1.\nДаденото образложение е ''$2''.\n\n* Почеток на блокирањето: $8\n* Истекување на блокирањето: $6\n* Корисникот што требало да биде блокиран: $7\n\nМоже да контактирате со $1 или некој друг [[{{MediaWiki:Grouppage-sysop}}|администратор]] за да разговарате во врска со блокирањето.\nМожете да ја искористите можноста „Е-пошта до овој корисник“ ако е назначена важечка е-поштенска адреса во [[Special:Preferences|вашите нагодувања]] и не ви е забрането да ја користите.\nВашата сегашна IP-адреса е $3, а назнака на блокирањето гласи #$5.\nВе молиме наведете ги сите подробности прикажани погоре, во вашата евентуална реакција.",
-       "autoblockedtext": "Вашата IP-адреса е автоматски блокирана бидејќи била користена од страна на друг корисник, кој бил блокиран од $1.\nДаденото образложение е следново:\n\n:''$2''\n\n* Почеток на блокирањето: $8\n* Истекување на блокирањето: $6\n* Со намера да се блокира: $7\n\nМоже да контактирате со $1 или некој друг [[{{MediaWiki:Grouppage-sysop}}|администратор]] за да разговарате во врска со ова блокирање.\n\nИмајте предвид дека можеби нема да можете да ја искористите можноста „Е-пошта до овој корисник“ доколку не е назначена важечка е-поштенска адреса во [[Special:Preferences|вашите нагодувања]] и ви е забрането користитење на истата.\n\nВашата IP-адреса е $3, a ID на блокирањеto е $5.\nВе молиме наведете ги овие подробности доколку реагирате на блокирањето.",
+       "blockedtext": "<strong>Вашето корисничко име или IP-адреса е блокирано.</strong>\n\nБлокирањето е направено од страна на $1.\nДаденото образложение е ''$2''.\n\n* Почеток на блокирањето: $8\n* Истекување на блокирањето: $6\n* Корисникот што требало да биде блокиран: $7\n\nМоже да контактирате со $1 или некој друг [[{{MediaWiki:Grouppage-sysop}}|администратор]] за да разговарате во врска со блокирањето.\nМожете да ја искористите можноста „{{int:emailuser}}“ ако е назначена важечка е-поштенска адреса во [[Special:Preferences|вашите нагодувања]] и не ви е забрането да ја користите.\nВашата сегашна IP-адреса е $3, а назнака на блокирањето гласи #$5.\nВе молиме наведете ги сите подробности прикажани погоре, во вашата евентуална реакција.",
+       "autoblockedtext": "Вашата IP-адреса е автоматски блокирана бидејќи била користена од страна на друг корисник, кој бил блокиран од $1.\nДаденото образложение е следново:\n\n:<em>$2</em>\n\n* Почеток на блокирањето: $8\n* Истекување на блокирањето: $6\n* Со намера да се блокира: $7\n\nМоже да контактирате со $1 или некој друг [[{{MediaWiki:Grouppage-sysop}}|администратор]] за да разговарате во врска со ова блокирање.\n\nИмајте предвид дека можеби нема да можете да ја искористите можноста „{{int:emailuser}}“ доколку не е назначена важечка е-поштенска адреса во [[Special:Preferences|вашите нагодувања]] и ви е забрането користитење на истата.\n\nВашата IP-адреса е $3, a ID на блокирањеto е $5.\nВе молиме наведете ги овие подробности доколку реагирате на блокирањето.",
        "systemblockedtext": "Вашето корисничко име или IP-адреса е автоматски блокирано од МедијаВики.\nПонудена причина:\n\n:<em>$2</em>\n\n* Почеток на блокот: $8\n* Истек на блокот: $6\n* Блокот е наменет за: $7\n\nВашата тековна IP-адреса гласи $3.\nПрепишете ги сите горенаведени поединости доколку сакате да се распрашате кај надлежните во врска со блокот.",
        "blockednoreason": "не е наведена причина",
        "whitelistedittext": "Мора да сте $1 за да уредувате страници.",
        "protectedtitles-submit": "Прикажи наслови",
        "listusers": "Список на корисници",
        "listusers-editsonly": "Прикажи само корисници кои уредувале",
+       "listusers-temporarygroupsonly": "Прикажи само корисници во привремени кориснички групи",
        "listusers-creationsort": "Подреди по датум на создавање",
        "listusers-desc": "Подреди по надолен редослед",
        "usereditcount": "$1 {{PLURAL:$1|уредување|уредувања}}",
        "apisandbox-dynamic-parameters-add-label": "Додај параметар:",
        "apisandbox-dynamic-parameters-add-placeholder": "Назив на параметарот",
        "apisandbox-dynamic-error-exists": "Праметарот по име „$1“ веќе постои.",
+       "apisandbox-templated-parameter-reason": "Овој [[Special:ApiHelp/main#main/templatedparams|шаблонизиран параметар]] се нуди според {{PLURAL:$1|вредноста|вредностите}} на $2.",
        "apisandbox-deprecated-parameters": "Застарени параметри",
        "apisandbox-fetch-token": "Самопополни ја шифрата",
        "apisandbox-add-multi": "Додај",
        "whatlinkshere": "Што води овде",
        "whatlinkshere-title": "Страници со врски што водат до „$1“",
        "whatlinkshere-page": "Страница:",
-       "linkshere": "Следните страници водат кон „'''[[:$1]]'''“:",
-       "nolinkshere": "Нема страници што водат кон '''[[:$1]]'''.",
-       "nolinkshere-ns": "Нема страници што водат кон '''[[:$1]]''' во избраниот именски простор.",
+       "linkshere-2": "Следните страници водат кон „'''$1'''“:",
+       "nolinkshere-2": "Нема страници што водат кон '''$1'''.",
+       "nolinkshere-ns-2": "Нема страници што водат кон '''$1''' во избраниот именски простор.",
        "isredirect": "пренасочувачка страница",
        "istemplate": "превметнување",
        "isimage": "врска до податотеката",
        "special-characters-group-hebrew": "Хебрејски",
        "special-characters-group-bangla": "Бенгалски",
        "special-characters-group-tamil": "тамилски",
-       "special-characters-group-telugu": "Телугу",
+       "special-characters-group-telugu": "Телушки",
        "special-characters-group-sinhala": "Синхалски",
-       "special-characters-group-gujarati": "Гуџарати",
+       "special-characters-group-gujarati": "Гуџаратски",
        "special-characters-group-devanagari": "деванагари",
        "special-characters-group-thai": "Тајландски",
        "special-characters-group-lao": "Лаошки",
        "pagedata-title": "Податоци за страницата",
        "pagedata-text": "Страницава дава посредник за податоци за страниците. Укажете го насловот на страницата во URL-то, користејќи ја синтаксата за потстраници.\n* Префрлањето на содржината се заснова на заглавието Прифати на вашиот клиент. Ова значи дека податоците за страницата ќе бидат ставени во форматот кој го претпочита вашиот клиент.",
        "pagedata-not-acceptable": "Не најдов соодветен формат. Поддржани MIME-типови: $1",
-       "pagedata-bad-title": "Неважечки наслов: $1."
+       "pagedata-bad-title": "Неважечки наслов: $1.",
+       "unregistered-user-config": "Од безбедносни причини, корисничките потстраници со JavaScript, CSS и JSON не се вчитуваат за нерегистрирани корисници.",
+       "passwordpolicies": "Правила за лозинки",
+       "passwordpolicies-summary": "Ова е список на делотворни правила за лозинки за корисничките групи определени на ова вики.",
+       "passwordpolicies-group": "Група",
+       "passwordpolicies-policies": "Правила",
+       "passwordpolicies-policy-minimalpasswordlength": "Лозинката мора да има барем $1 {{PLURAL:$1|знак|знаци}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Лозинката мора да има барем $1 {{PLURAL:$1|знак|знаци}} за да можете да се најавите",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Лозинката не може да биде иста што и корисничкото име",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Лозинката не смее да биде од оние на црниот список",
+       "passwordpolicies-policy-maximalpasswordlength": "Лозинката не треба да има повеќе од $1 {{PLURAL:$1|знак|знаци}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "Лозинката не треба да биде {{PLURAL:$1|најзастапената|од списокот на $1 најзастапени лозинки}}"
 }
index bfd785d..9d1ac9a 100644 (file)
        "subject-preview": "വിഷയം എങ്ങനെയുണ്ടെന്ന് കാണുക:",
        "previewerrortext": "താങ്കളുടെ മാറ്റങ്ങൾ എങ്ങനെയുണ്ടെന്ന് കാണാൻ ശ്രമിച്ചപ്പോൾ പിഴവുണ്ടായി.",
        "blockedtitle": "ഉപയോക്താവിനെ തടഞ്ഞിരിക്കുന്നു",
-       "blockedtext": "'''താങ്കളുടെ ഉപയോക്തൃനാമത്തേയോ താങ്കൾ ഇപ്പോൾ ലോഗിൻ ചെയ്തിട്ടുള്ള ഐ.പി. വിലാസത്തേയോ ഈ വിക്കി തിരുത്തുന്നതിൽ നിന്നു തടഞ്ഞിരിക്കുന്നു'''\n\n$1 ആണ് ഈ തടയൽ നടത്തിയത്. ''$2'' എന്നതാണു് അതിനു രേഖപ്പെടുത്തിയിട്ടുള്ള കാരണം.\n\n* തടയലിന്റെ തുടക്കം: $8\n* തടയലിന്റെ കാലാവധി: $6\n* തടയപ്പെട്ട ഉപയോക്താവ്: $7\n\nഈ തടയലിനെ പറ്റി ചർച്ച ചെയ്യാൻ താങ്കൾക്ക് $1 എന്ന ഉപയോക്താവിനേയോ മറ്റ് [[{{MediaWiki:Grouppage-sysop}}|കാര്യനിർവാഹകരെയോ]] സമീപിക്കാവുന്നതാണ്. [[Special:Preferences|താങ്കളുടെ ക്രമീകരണങ്ങളിൽ]] താങ്കൾ സാധുവായ ഇമെയിൽ വിലാസം കൊടുത്തിട്ടുണ്ടെങ്കിൽ, അതു അയക്കുന്നതിൽ നിന്നു താങ്കൾ തടയപ്പെട്ടിട്ടില്ലെങ്കിൽ, 'ഇദ്ദേഹത്തിന് ഇമെയിൽ അയക്കൂ' എന്ന സം‌വിധാനം ഉപയോഗിച്ച് താങ്കൾക്ക് മറ്റുപയോക്താക്കളുമായി ബന്ധപ്പെടാം. താങ്കളുടെ നിലവിലുള്ള ഐ.പി. വിലാസം $3 ഉം, താങ്കളുടെ തടയൽ ഐ.ഡി. #$5 ഉം ആണ്. ഇവ രണ്ടും താങ്കൾ കാര്യനിർവാഹകനെ ബന്ധപ്പെടുമ്പോൾ ചേർക്കുക.",
-       "autoblockedtext": "താങ്കളുടെ ഐ.പി. വിലാസം സ്വയം തടയപ്പെട്ടിരിക്കുന്നു, മറ്റൊരു ഉപയോക്താവ് ഉപയോഗിച്ച കാരണത്താൽ $1 എന്ന കാര്യനിർവാഹകനാണ് തടഞ്ഞുവെച്ചത്.\nഇതിനു കാരണമായി നൽകിയിട്ടുള്ളത്:\n\n:''$2''\n\n* തടയൽ തുടങ്ങിയത്: $8\n* തടയൽ അവസാനിക്കുന്നത്: $6\n* തടയാൻ ഉദ്ദേശിച്ചത്: $7\n\nഈ തടയലിനെ കുറിച്ച് ചർച്ച ചെയ്യാൻ താങ്കൾക്കു $1 എന്ന കാര്യനിവാഹകനേയോ മറ്റു [[{{MediaWiki:Grouppage-sysop}}|കാര്യനിർവാഹകരെയോ]] ബന്ധപ്പെടാവുന്നതാണ്.\n\nശ്രദ്ധിക്കുക [[Special:Preferences|താങ്കളുടെ ക്രമീകരണങ്ങളിൽ]] സാധുവായ ഇമെയിൽ വിലാസം രേഖപ്പെടുത്താതിരിക്കുകയോ, അത് ഉപയോഗിക്കുന്നതിൽ നിന്ന് താങ്കളെ തടയുകയോ ചെയ്തിട്ടുണ്ടെങ്കിൽ \"ഇദ്ദേഹത്തിന് ഇമെയിൽ അയക്കൂ\" എന്ന സം‌വിധാനം പ്രവർത്തന രഹിതമായിരിക്കും.\n\nതാങ്കളുടെ നിലവിലുള്ള ഐ.പി. വിലാസം $3 ആണ്, താങ്കളുടെ തടയലിന്റെ ഐ.ഡി. #$5 ആകുന്നു.\nദയവായി മുകളിൽ കൊടുത്തിരിക്കുന്ന വിവരങ്ങളെല്ലാം താങ്കൾ നടത്തുന്ന അന്വേഷണങ്ങളിൽ ഉൾപ്പെടുത്തുവാൻ ശ്രദ്ധിക്കുക.",
+       "blockedtext": "<strong>താങ്കളുടെ ഉപയോക്തൃനാമത്തേയോ താങ്കൾ ഇപ്പോൾ ലോഗിൻ ചെയ്തിട്ടുള്ള ഐ.പി. വിലാസത്തേയോ ഈ വിക്കി തിരുത്തുന്നതിൽ നിന്നു തടഞ്ഞിരിക്കുന്നു</strong>\n\n$1 ആണ് ഈ തടയൽ നടത്തിയത്. <em>$2</em> എന്നതാണു് അതിനു രേഖപ്പെടുത്തിയിട്ടുള്ള കാരണം.\n\n* തടയലിന്റെ തുടക്കം: $8\n* തടയലിന്റെ കാലാവധി: $6\n* തടയപ്പെട്ട ഉപയോക്താവ്: $7\n\nഈ തടയലിനെ പറ്റി ചർച്ച ചെയ്യാൻ താങ്കൾക്ക് $1 എന്ന ഉപയോക്താവിനേയോ മറ്റ് [[{{MediaWiki:Grouppage-sysop}}|കാര്യനിർവാഹകരെയോ]] സമീപിക്കാവുന്നതാണ്. [[Special:Preferences|താങ്കളുടെ ക്രമീകരണങ്ങളിൽ]] താങ്കൾ സാധുവായ ഇമെയിൽ വിലാസം കൊടുത്തിട്ടുണ്ടെങ്കിൽ, അതു അയക്കുന്നതിൽ നിന്നു താങ്കൾ തടയപ്പെട്ടിട്ടില്ലെങ്കിൽ, \"{{int:emailuser}}\" എന്ന സം‌വിധാനം ഉപയോഗിച്ച് താങ്കൾക്ക് മറ്റുപയോക്താക്കളുമായി ബന്ധപ്പെടാം. താങ്കളുടെ നിലവിലുള്ള ഐ.പി. വിലാസം $3 ഉം, താങ്കളുടെ തടയൽ ഐ.ഡി. #$5 ഉം ആണ്. ഇവ രണ്ടും താങ്കൾ കാര്യനിർവാഹകനെ ബന്ധപ്പെടുമ്പോൾ ചേർക്കുക.",
+       "autoblockedtext": "താങ്കളുടെ ഐ.പി. വിലാസം സ്വയം തടയപ്പെട്ടിരിക്കുന്നു, മറ്റൊരു ഉപയോക്താവ് ഉപയോഗിച്ച കാരണത്താൽ $1 എന്ന കാര്യനിർവാഹകനാണ് തടഞ്ഞുവെച്ചത്.\nഇതിനു കാരണമായി നൽകിയിട്ടുള്ളത്:\n\n:<em>$2</em>\n\n* തടയൽ തുടങ്ങിയത്: $8\n* തടയൽ അവസാനിക്കുന്നത്: $6\n* തടയാൻ ഉദ്ദേശിച്ചത്: $7\n\nഈ തടയലിനെ കുറിച്ച് ചർച്ച ചെയ്യാൻ താങ്കൾക്കു $1 എന്ന കാര്യനിവാഹകനേയോ മറ്റു [[{{MediaWiki:Grouppage-sysop}}|കാര്യനിർവാഹകരെയോ]] ബന്ധപ്പെടാവുന്നതാണ്.\n\nശ്രദ്ധിക്കുക [[Special:Preferences|താങ്കളുടെ ക്രമീകരണങ്ങളിൽ]] സാധുവായ ഇമെയിൽ വിലാസം രേഖപ്പെടുത്താതിരിക്കുകയോ, അത് ഉപയോഗിക്കുന്നതിൽ നിന്ന് താങ്കളെ തടയുകയോ ചെയ്തിട്ടുണ്ടെങ്കിൽ \"{{int:emailuser}}\" എന്ന സം‌വിധാനം പ്രവർത്തന രഹിതമായിരിക്കും.\n\nതാങ്കളുടെ നിലവിലുള്ള ഐ.പി. വിലാസം $3 ആണ്, താങ്കളുടെ തടയലിന്റെ ഐ.ഡി. #$5 ആകുന്നു.\nദയവായി മുകളിൽ കൊടുത്തിരിക്കുന്ന വിവരങ്ങളെല്ലാം താങ്കൾ നടത്തുന്ന അന്വേഷണങ്ങളിൽ ഉൾപ്പെടുത്തുവാൻ ശ്രദ്ധിക്കുക.",
        "systemblockedtext": "താങ്കളുടെ ഉപയോക്തൃനാമം അല്ലെങ്കിൽ ഐ.പി. വിലാസം മീഡിയവിക്കി സ്വയം തടഞ്ഞിരിക്കുന്നു.\nതടയാനുള്ള കാരണം:\n\n:<em>$2</em>\n\n* തടയൽ തുടങ്ങിയത്: $8\n* തടയൽ കാലഹരണപ്പെടുന്നത്: $6\n* തടയാനുദ്ദേശിച്ചയാൾ: $7\n\nതാങ്കളുടെ നിലവിലെ ഐ.പി. വിലാസം $3 ആണ്.\nതാങ്കൾക്കെന്തെങ്കിലും ചോദ്യങ്ങളുണ്ടെങ്കിൽ മുകളിലെ എല്ലാ വിവരങ്ങളും ഉൾപ്പെടുത്തുക.",
        "blockednoreason": "കാരണമൊന്നും സൂചിപ്പിച്ചിട്ടില്ല",
        "whitelistedittext": "താളുകൾ തിരുത്താൻ താങ്കൾ $1 ചെയ്യേണ്ടതാണ്",
        "stub-threshold-disabled": "നിർജ്ജീവമാക്കപ്പെട്ടിരിക്കുന്നു",
        "recentchangesdays": "പുതിയ മാറ്റങ്ങളിൽ കാണിക്കേണ്ട ദിവസങ്ങളുടെ എണ്ണം:",
        "recentchangesdays-max": "പരമാവധി {{PLURAL:$1|ഒരു ദിവസം|$1 ദിവസങ്ങൾ}}",
-       "recentchangescount": "സമàµ\80à´ªà´\95ാലമാറàµ\8dà´±à´\99àµ\8dà´\99ളിലàµ\81à´\82 à´¤à´¾à´³àµ\81à´\95à´³àµ\81à´\9fàµ\86 à´¨à´¾àµ¾à´ªàµ\8dപതിപàµ\8dà´ªàµ\81à´\95ളിലàµ\81à´\82 à´°àµ\87à´\96à´\95ളിലàµ\81à´\82 à´¸àµ\8dവതàµ\87 à´ªàµ\8dരദർശിപàµ\8dപിà´\95àµ\8dà´\95àµ\87à´£àµ\8dà´\9f à´¤à´¿à´°àµ\81à´¤àµ\8dതലàµ\81à´\95à´³àµ\81à´\9fàµ\86 à´\8eà´£àµ\8dà´£à´\82:",
+       "recentchangescount": "സമീപകാലമാറ്റങ്ങളിലും താളുകളുടെ നാൾപ്പതിപ്പുകളിലും രേഖകളിലും സ്വതേ പ്രദർശിപ്പിക്കേണ്ട തിരുത്തുകളുടെ എണ്ണം:",
        "prefs-help-recentchangescount": "പരമാവധി എണ്ണം: 1000",
        "prefs-help-watchlist-token2": "ഇത് താങ്കൾ ശ്രദ്ധിക്കുന്നവയുടെ  പട്ടികയുടെ വെബ്‌ഫീഡിനുള്ള രഹസ്യചാവിയാണ്.\nഇത് അറിയാവുന്നവർക്ക് താങ്കൾ ശ്രദ്ധിക്കുന്നവയെന്താണെന്ന് വായിക്കാനാവുമെന്നതിനാൽ, പങ്ക് വെയ്ക്കാതിരിക്കുക.\nതാങ്കൾക്കാവശ്യമെങ്കിൽ [[Special:ResetTokens|ഇത് പുനസജ്ജീകരിക്കാവുന്നതാണ്]].",
        "savedprefs": "താങ്കളുടെ ക്രമീകരണങ്ങൾ കാത്തുസൂക്ഷിച്ചിരിക്കുന്നു.",
        "whatlinkshere": "ഈ താളിലേക്കുള്ള കണ്ണികൾ",
        "whatlinkshere-title": "\"$1\" എന്ന താളിലേക്കുള്ള കണ്ണികൾ",
        "whatlinkshere-page": "താൾ:",
-       "linkshere": "താഴെക്കൊടുത്തിരിക്കുന്ന താളുകളിൽ നിന്നും '''[[:$1]]''' എന്ന താളിലേക്ക് കണ്ണികളുണ്ട്:",
-       "nolinkshere": "'''[[:$1]]''' എന്ന താളിലേക്ക് കണ്ണികളൊന്നും നിലവിലില്ല.",
-       "nolinkshere-ns": "തിരഞ്ഞെടുത്ത നാമമേഖലയിൽ '''[[:$1]]''' എന്ന താളിലേക്ക് മറ്റൊരു താളുകളിൽനിന്നും കണ്ണികളില്ല.",
+       "linkshere-2": "താഴെക്കൊടുത്തിരിക്കുന്ന താളുകളിൽ നിന്നും '''$1''' എന്ന താളിലേക്ക് കണ്ണികളുണ്ട്:",
+       "nolinkshere-2": "'''$1''' എന്ന താളിലേക്ക് കണ്ണികളൊന്നും നിലവിലില്ല.",
+       "nolinkshere-ns-2": "തിരഞ്ഞെടുത്ത നാമമേഖലയിൽ '''$1''' എന്ന താളിലേക്ക് മറ്റൊരു താളുകളിൽനിന്നും കണ്ണികളില്ല.",
        "isredirect": "തിരിച്ചുവിടൽ താൾ",
        "istemplate": "ഉൾപ്പെടുത്തൽ",
        "isimage": "പ്രമാണത്തിന്റെ കണ്ണി",
index bc64d1c..113c30f 100644 (file)
        "whatlinkshere": "Энд холбогдсон хуудсууд",
        "whatlinkshere-title": "\"$1\"-д холбоостой хуудаснууд",
        "whatlinkshere-page": "Хуудас:",
-       "linkshere": "Дараах хуудсууд '''[[:$1]]'''-тай холбогдсон байна:",
-       "nolinkshere": "'''[[:$1]]'''-тай холбогдсон хуудас байхгүй байна.",
-       "nolinkshere-ns": "Сонгосон нэрний зайд '''[[:$1]]''' руу холбогдсон хуудас байхгүй байна.",
+       "linkshere-2": "Дараах хуудсууд '''$1'''-тай холбогдсон байна:",
+       "nolinkshere-2": "'''$1'''-тай холбогдсон хуудас байхгүй байна.",
+       "nolinkshere-ns-2": "Сонгосон нэрний зайд '''$1''' руу холбогдсон хуудас байхгүй байна.",
        "isredirect": "чиглүүлэгч",
        "istemplate": "оруулалт",
        "isimage": "файлын холбоос",
        "fileduplicatesearch-noresults": "\"$1\" нэртэй файл олдсонгүй.",
        "specialpages": "Тусгай хуудсууд",
        "specialpages-note-top": "Томъёолбор",
+       "specialpages-note-restricted": "* Ердийн тусгай хуудсууд.\n* <strong class=\"mw-specialpagerestricted\">Хориотой тусгай хуудсууд.</strong>",
        "specialpages-group-maintenance": "Засвар үйлчилгээний тайлангууд",
        "specialpages-group-other": "Бусад тусгай хуудсууд",
        "specialpages-group-login": "Нэвтрэх / бүртгүүлэх",
index 5fb8c78..e860acb 100644 (file)
        "whatlinkshere": "येथे काय जोडले आहे",
        "whatlinkshere-title": "\"$1\" ला जुळलेली पाने",
        "whatlinkshere-page": "पान:",
-       "linkshere": "खालील लेख '''[[:$1]]''' या पानांशी जोडले आहेत:",
-       "nolinkshere": "'''[[:$1]]''' येथे कोणत्याही पानांचे दुवे नाहीत.",
-       "nolinkshere-ns": "निवडलेल्या नामविश्वातील कोणतीही पाने <strong>[[:$1]]</strong>ला दुवा देत नाहीत .",
+       "linkshere-2": "खालील लेख '''$1''' या पानांशी जोडले आहेत:",
+       "nolinkshere-2": "'''$1''' येथे कोणत्याही पानांचे दुवे नाहीत.",
+       "nolinkshere-ns-2": "निवडलेल्या नामविश्वातील कोणतीही पाने <strong>$1</strong>ला दुवा देत नाहीत .",
        "isredirect": "पुनर्निर्देशित पान",
        "istemplate": "आंतर्न्यास (ट्रांसक्लूजन)",
        "isimage": "संचिका दुवा",
index 771c077..96132fd 100644 (file)
        "whatlinkshere": "Pautan ke laman ini",
        "whatlinkshere-title": "Laman yang mengandungi pautan ke \"$1\"",
        "whatlinkshere-page": "Laman:",
-       "linkshere": "Laman-laman berikut mengandungi pautan ke '''[[:$1]]''':",
-       "nolinkshere": "Tiada laman yang mengandungi pautan ke '''[[:$1]]'''.",
-       "nolinkshere-ns": "Tiada laman yang mengandungi pautan ke '''[[:$1]]''' dalam ruang nama yang dinyatakan.",
+       "linkshere-2": "Laman-laman berikut mengandungi pautan ke '''$1''':",
+       "nolinkshere-2": "Tiada laman yang mengandungi pautan ke '''$1'''.",
+       "nolinkshere-ns-2": "Tiada laman yang mengandungi pautan ke '''$1''' dalam ruang nama yang dinyatakan.",
        "isredirect": "laman lencongan",
        "istemplate": "penyertaan",
        "isimage": "pautan fail",
        "fileduplicatesearch-noresults": "Tidak ada gambar-gambar dengan nama \"$1\" dijumpai.",
        "specialpages": "Laman khas",
        "specialpages-note-top": "Petunjuk",
+       "specialpages-note-restricted": "* Laman khas biasa.\n* <span class=\"mw-specialpagerestricted\">Laman khas terhad.</span>",
        "specialpages-group-maintenance": "Laporan penyenggaraan",
        "specialpages-group-other": "Laman khas lain",
        "specialpages-group-login": "Log masuk / buka akaun",
index 958bdae..e67b778 100644 (file)
        "whatlinkshere": "Li jwasslu 'l hawn",
        "whatlinkshere-title": "Paġni li jippuntaw lejn $1",
        "whatlinkshere-page": "Paġna:",
-       "linkshere": "Il-paġni segwenti jorbtu lejn '''[[:$1]]''':",
-       "nolinkshere": "L-ebda paġna ma twassal għal '''[[:$1]]'''.",
-       "nolinkshere-ns": "L-ebda paġna ma tipponta lejn '''[[:$1]]''' fl-ispazju tal-isem magħżul.",
+       "linkshere-2": "Il-paġni segwenti jorbtu lejn '''$1''':",
+       "nolinkshere-2": "L-ebda paġna ma twassal għal '''$1'''.",
+       "nolinkshere-ns-2": "L-ebda paġna ma tipponta lejn '''$1''' fl-ispazju tal-isem magħżul.",
        "isredirect": "paġna ta' rindirizz",
        "istemplate": "inklużjoni",
        "isimage": "ħolqa lejn il-fajl",
        "fileduplicatesearch-noresults": "Ma nstab l-ebda fajl bl-isem \"$1\".",
        "specialpages": "Paġni speċjali",
        "specialpages-note-top": "Leġġenda",
+       "specialpages-note-restricted": "* Paġni speċjali normali.\n* <span class=\"mw-specialpagerestricted\">Paġni speċjali ristretti.</span>",
        "specialpages-group-maintenance": "Rapporti ta' manutenzjoni",
        "specialpages-group-other": "Paġni speċjali oħrajn",
        "specialpages-group-login": "Idħol / oħloq kont",
index 516b4fc..297cde8 100644 (file)
        "whatlinkshere": "L que lhiga eiqui",
        "whatlinkshere-title": "Páiginas que lhígan a \"$1\"",
        "whatlinkshere-page": "Páigina:",
-       "linkshere": "Estas páiginas ténen lhigaçones pa <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Nun eisisten lhigaçones pa '''[[:$1]]'''.",
+       "linkshere-2": "Estas páiginas ténen lhigaçones pa <strong>$1</strong>:",
+       "nolinkshere-2": "Nun eisisten lhigaçones pa '''$1'''.",
        "isredirect": "páigina de ancaminamiento",
        "istemplate": "ancluson",
        "isimage": "lhigaçon pa l fexeiro",
index 397c965..ca80b0b 100644 (file)
        "bold_tip": "စာလုံးမည်း",
        "italic_sample": "စာလုံး အစောင်း",
        "italic_tip": "စာလုံး အစောင်း",
-       "link_sample": "လင့် ခေါင်းစဉ်",
-       "link_tip": "အတွင်းပိုင်း လင့်",
-       "extlink_sample": "http://www.example.com လင့် ခေါင်းစဉ်",
+       "link_sample": "လင့်ခ် ခေါင်းစဉ်",
+       "link_tip": "အတွင်းပိုင်း လင့်ခ်",
+       "extlink_sample": "http://www.example.com လင့်ခ် ခေါင်းစဉ်",
        "extlink_tip": "ပြင်ပလင့်များ (http:// ကို ရှေ့ဆုံးမှ ထည့်ရေးရန် မမေ့ပါနှင့်)",
        "headline_sample": "ခေါင်းကြီးစာသား",
        "headline_tip": "အဆင့် ၂ ခေါင်းစီး",
        "summary-preview": "တည်းဖြတ်အကျဉ်းချုပ် နမူနာ:",
        "subject-preview": "အကြောင်းအရာ နမူနာ:",
        "blockedtitle": "အသုံးပြုသူကို ပိတ်ပင်ထားသည်",
-       "blockedtext": "<strong>သင်၏ အသုံးပြုသူအမည် သို့မဟုတ် အိုင်ပီလိပ်စာသည် ပိတ်ပင်ခြင်း ခံထားရသည်။</strong>\n\nဤပိတ်ပင်မှုအား $1 က ဆောင်ရွက်ခဲ့သည်။\nအကြောင်းရင်းမှာ <em>$2</em> ဖြစ်သည်။\n\n* ပိတ်ပင်ခြင်း စတင်ချိန်: $8\n* ပိတ်ပင်ခြင်း သက်တမ်းကုန်ချိန်: $6\n* ရည်ရွယ်ရာ blockee: $7\n\nသင်သည် ပိတ်ပင်မှုအတွက် ဆွေးနွေးရန် $1 သို့မဟုတ် အခြား [[{{MediaWiki:Grouppage-sysop}}|စီမံခန့်ခွဲသူ]] အား ဆက်သွယ်နိုင်သည်။\nသင့်အနေဖြင့် [[Special:Preferences|အကောင့်၏ ရွေးချယ်စရာများ]]ထဲတွင် ရေရာသော အီးမေးလိပ်စာအား မထည့်သွင်းထားပါက \"ဤအသုံးပြုသူအား အီးမေးပို့ပါ\" လုပ်ဆောင်ချက်ကို အသုံးပြုနိုင်မည် မဟုတ်ပါ။ အလားတူ ယင်းလုပ်ဆောင်ချက်ကို ပိတ်ပင်မခံရမှ လုပ်ဆောင်နိုင်မည်ဖြစ်သည်။\nသင်၏ လက်ရှိ အိုင်ပီလိပ်စာမှာ $3 ဖြစ်ပြီး၊ ပိတ်ပင်မှုအိုင်ဒီမှာ #$5 ဖြစ်သည်။\nသင်ပြုလုပ်မည့် စုံစမ်းမေးမြန်းမှုများတွင် အထက်ပါ အချက်များ အားလုံး ပါဝင်နေပါစေ။",
+       "blockedtext": "<strong>သင်၏ အသုံးပြုသူအမည် သို့မဟုတ် အိုင်ပီလိပ်စာသည် ပိတ်ပင်ခြင်း ခံထားရသည်။</strong>\n\nဤပိတ်ပင်မှုအား $1 က ဆောင်ရွက်ခဲ့သည်။\nအကြောင်းရင်းမှာ <em>$2</em> ဖြစ်သည်။\n\n* ပိတ်ပင်ခြင်း စတင်ချိန်: $8\n* ပိတ်ပင်ခြင်း သက်တမ်းကုန်ချိန်: $6\n* ရည်ရွယ်ရာ blockee: $7\n\nသင်သည် ပိတ်ပင်မှုအတွက် ဆွေးနွေးရန် $1 သို့မဟုတ် အခြား [[{{MediaWiki:Grouppage-sysop}}|စီမံခန့်ခွဲသူ]] အား ဆက်သွယ်နိုင်သည်။\nသင့်အနေဖြင့် [[Special:Preferences|အကောင့်၏ ရွေးချယ်စရာများ]]ထဲတွင် ရေရာသော အီးမေးလိပ်စာအား မထည့်သွင်းထားပါက \"{{int:emailuser}}\" လုပ်ဆောင်ချက်ကို အသုံးပြုနိုင်မည် မဟုတ်ပါ။ အလားတူ ယင်းလုပ်ဆောင်ချက်ကို ပိတ်ပင်မခံရမှ လုပ်ဆောင်နိုင်မည်ဖြစ်သည်။\nသင်၏ လက်ရှိ အိုင်ပီလိပ်စာမှာ $3 ဖြစ်ပြီး၊ ပိတ်ပင်မှုအိုင်ဒီမှာ #$5 ဖြစ်သည်။\nသင်ပြုလုပ်မည့် စုံစမ်းမေးမြန်းမှုများတွင် အထက်ပါ အချက်များ အားလုံး ပါဝင်နေပါစေ။",
        "blockednoreason": "အကြောင်းပြချက် မပေးထားပါ",
        "whitelistedittext": "စာမျက်နှာများကို တည်းဖြတ်ရန် $1ရမည်။",
        "nosuchsectiontitle": "အပိုင်းကို ရှာမရနိုင်ပါ",
        "recentchangeslinked-feed": "ဆက်စပ်သော ​အ​ပြောင်း​အ​လဲ​များ​",
        "recentchangeslinked-toolbox": "ဆက်စပ်သော အပြောင်းအလဲများ",
        "recentchangeslinked-title": "\"$1\" နှင့် ဆက်စပ်သော အပြောင်းအလဲများ",
-       "recentchangeslinked-summary": "ဤစာမျက်နှာမှ သို့မဟုတ် ဤစာမျက်နှာသို့ ချိတ်ဆက်ထားသော စာမျက်နှာများ၏ ပြောင်းလဲမှုများကို ကြည့်ရှုနိုင်ရန် စာမျက်နှာအမည်တစ်ခုကို ထည့်သွင်းပါ။ (ကဏ္ဍတစ်ခု၏ အဖွဲ့ဝင်များကို ကြည့်ရှုရန် Category:ကဏ္ဍအမည် ကို ရိုက်ထည့်ပါ။) [[Special:Watchlist|သင့်စောင့်ကြည့်စာရင်း]]ရှိ စာမျက်နှာများ၏ ပြောင်းလဲမှုများကို <strong>စာလုံးအထူ</strong>ဖြင့် ပြထားသည်။",
+       "recentchangeslinked-summary": "ဤစာမျက်နှာမှ သို့မဟုတ် ဤစာမျက်နှာသို့ ချိတ်ဆက်ထားသော စာမျက်နှာများ၏ ပြောင်းလဲမှုများကို ကြည့်ရှုနိုင်ရန် စာမျက်နှာအမည်တစ်ခုကို ထည့်သွင်းပါ။ (ကဏ္ဍတစ်ခု၏ အဖွဲ့ဝင်များကို ကြည့်ရှုရန် {{ns:category}}:ကဏ္ဍအမည် ကို ရိုက်ထည့်ပါ။) [[Special:Watchlist|သင့်စောင့်ကြည့်စာရင်း]]ရှိ စာမျက်နှာများ၏ ပြောင်းလဲမှုများကို <strong>စာလုံးအထူ</strong>ဖြင့် ပြထားသည်။",
        "recentchangeslinked-page": "စာမျက်နှာ အမည် -",
        "recentchangeslinked-to": "ပေးထားသော စာမျက်နှာများအစား လင့်များနှင့် ဆက်စပ်နေသာ စာမျက်နှာများ၏ အပြောင်းအလဲများကို ပြရန်",
        "recentchanges-page-added-to-category": "ကဏ္ဍထဲသို့ [[:$1]] ကို ပေါင်းထည့်ခဲ့သည်",
        "whatlinkshere": "ဘယ်ကလင့်ခ်ထားလဲ",
        "whatlinkshere-title": "\"$1\" သို့ ချိတ်ဆက်ထားသော စာမျက်နှာများ",
        "whatlinkshere-page": "စာမျက်နှာ -",
-       "linkshere": "အောက်ပါစာမျက်နှာများသည် <strong>[[:$1]]</strong> သို့ ချိတ်ဆက်ထားသည် -",
-       "nolinkshere": "'''[[:$1]]''' သို့ လင့်ထားသော စာမျက်နှာ မရှိပါ။",
+       "linkshere-2": "အောက်ပါစာမျက်နှာများသည် <strong>$1</strong> သို့ ချိတ်ဆက်ထားသည် -",
+       "nolinkshere-2": "<strong>$1</strong> သို့ လင့်ခ်ထားသော စာမျက်နှာ မရှိပါ။",
        "isredirect": "ပြန်ညွှန်းသော စာမျက်နှာ",
        "istemplate": "ထည့်သွင်းကူးယူချက်",
        "isimage": "ဖိုင်လင့်",
        "whatlinkshere-prev": "{{PLURAL:$1|နောက်သို့|နောက်သို့ $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|ရှေ့သို့|ရှေ့သို့ $1}}",
-       "whatlinkshere-links": "← လင့်များ",
+       "whatlinkshere-links": "â\86\90 á\80\9cá\80\84á\80·á\80ºá\80\81á\80ºá\80\99á\80»á\80¬á\80¸",
        "whatlinkshere-hideredirs": "ပြန်ညွှန်းများ $1",
        "whatlinkshere-hidetrans": "ထည့်သွင်းကူးယူချက် $1",
        "whatlinkshere-hidelinks": "လင့်ခ်များ $1 ခု",
        "blocklist-nousertalk": "မိမိ၏ဆွေးနွေးချက်စာမျက်နှာကို တည်းဖြတ်မရနိုင်ပါ",
        "ipblocklist-empty": "ပိတ်ပင်ထားမှုစာရင်းသည် ဗလာဖြစ်နေသည်။",
        "blocklink": "ပိတ်ပင်",
-       "unblocklink": "á\80\9cá\80\84á\80·á\80º á\80\95á\80¼á\80\94á\80ºá\80\96á\80¼á\80±ရန်",
+       "unblocklink": "á\80\99á\80\95á\80­á\80\90á\80ºá\80\95á\80\84á\80ºá\80\90á\80±á\80¬á\80·ရန်",
        "change-blocklink": "စာကြောင်းအမည် ပြောင်းရန်",
        "contribslink": "ပံ့ပိုး",
        "blocklogpage": "ပိတ်ပင်တားဆီးမှု မှတ်တမ်း",
        "newimages-label": "ဖိုင်အမည် (သို့ ယင်း၏အစိတ်အပိုင်း) -",
        "noimages": "ကြည့်စရာဘာမှ မရှိပါ။",
        "ilsubmit": "ရှာဖွေရန်",
-       "bydate": "á\80\9bá\80\80á\80ºá\80\85á\80½á\80²á\80\96á\80¼á\80­á\80\84á\80·á\80º",
+       "bydate": "ရက်စွဲဖြင့်",
        "sp-newimages-showfrom": "$1 နေ့ $2 အချိန်ကစသော ဖိုင်အသစ်များကို ပြရန်",
        "bad_image_list": "ဖောမတ်ပုံစံမှာ အောက်ပါအတိုင်းဖြစ်သည်။\n\nစာရင်းတွင်ထည့်သွင်းထားသော အရာများကိုသာ ထည့်သွင်းစဉ်းစားမည်။ (ခရေပွင့် * ဖြင့်စသော စာကြောင်းများ)\nစာကြောင်း၏ ပထမဆုံး လင့်သည် ဖိုင်ညံ့ ဖြစ်ရမည်။\nယင်းစာကြောင်းတွင်ပင် နောက်ထပ်လာသောလင့်များကို ချွင်းချက်အဖြစ် စဉ်းစားမည်။ ဆိုလိုသည်မှာ ၎င်းလင့်များတွင်လည်း အဆိုပါ ဖိုင်ညံ့ ပါကောင်း ပါဝင်နေမည်။",
        "metadata": "Metadata",
        "specialpages-group-maintenance": "ထိန်းသိမ်းမှု အစီရင်ခံချက်များ",
        "specialpages-group-other": "အခြားအထူးစာမျက်နှာများ",
        "specialpages-group-login": "Log in ဝင်ရန်/ အကောင့် ဖန်တီးရန်",
-       "specialpages-group-changes": "လတ်တလောအေပြောင်းအလဲနှင့် မှတ်တမ်းများ",
+       "specialpages-group-changes": "လတ်တလော အပြောင်းအလဲနှင့် မှတ်တမ်းများ",
        "specialpages-group-media": "မီဒီယာ အစီရင်ခံချက်များနှင့် Upload တင်ထားသည်များ",
        "specialpages-group-users": "အသုံးပြုသူများနှင့် အခွင့်အရေးများ",
        "specialpages-group-highuse": "အသုံးများသော စာမျက်နှာများ",
index c78c814..903c2c4 100644 (file)
        "whatlinkshere": "Мезе тезэнь сюлмави",
        "whatlinkshere-title": "$1 марто сюлмазь лопатне",
        "whatlinkshere-page": "Лопась:",
-       "linkshere": "Сыця лопатьне сюлмававить '''[[:$1]]''' марто:",
-       "nolinkshere": "Кодаткак лопат асульмавить '''[[:$1]]''' марто.",
+       "linkshere-2": "Сыця лопатьне сюлмававить '''$1''' марто:",
+       "nolinkshere-2": "Кодаткак лопат асульмавить '''$1''' марто.",
        "isredirect": "Лиякс витнинк-петнинк лопанть",
        "istemplate": "совавтомс",
        "isimage": "файлань сюлмавома пене",
index 2aeac60..b4e276f 100644 (file)
        "whatlinkshere": "لینک‌ئون ِاینتا صفحه",
        "whatlinkshere-title": "وألـگ‌ئونی که \"$1\" ره لـیـنک هه‌دانه",
        "whatlinkshere-page": "صفحه:",
-       "linkshere": "اینان صفحه‌ئون به '''[[:$1]]''' لینک هدانه:",
+       "linkshere-2": "اینان صفحه‌ئون به '''$1''' لینک هدانه:",
        "isredirect": "دکشی‌ین صفحه",
        "istemplate": "تراگنجانش‌ئون",
        "isimage": "فایل ِلینک",
index e7aa2ae..1f1925d 100644 (file)
        "whatlinkshere": "In tlein quitzonhuilia nican",
        "whatlinkshere-title": "Zāzaniltin quitzonhuiliah $1",
        "whatlinkshere-page": "Tlahcuilolamatl:",
-       "linkshere": "Inīn zāzaniltin quitzonhuiliah '''[[:$1]]''' īhuīc:",
-       "nolinkshere": "Ahtle quitzonhuilia '''[[:$1]]''' īhuīc.",
+       "linkshere-2": "Inīn zāzaniltin quitzonhuiliah '''$1''' īhuīc:",
+       "nolinkshere-2": "Ahtle quitzonhuilia '''$1''' īhuīc.",
        "isredirect": "Tlacueptli tlahcuilolamatl",
        "isimage": "īxiptlahtli tzonhuiliztli",
        "whatlinkshere-prev": "{{PLURAL:$1|achtopa|$1 achtopa}}",
        "fileduplicatesearch-submit": "Tlatemoliztli",
        "fileduplicatesearch-info": "$1 × $2 pixelli<br />Tlahcuilōlli īxquichiliz: $3<br />MIME iuhcāyōtl: $4",
        "specialpages": "Noncuahquizqui tlahcuilolli",
+       "specialpages-note-restricted": "* Yeliztli nōncuahquīzqui āmatl.\n* <span class=\"mw-specialpagerestricted\">Tlaquīxtīlli nōncuahquīzqui āmatl.</span>\n* <span class=\"mw-specialpagecached\">Tlatlātīlli nōncuahquīzqui āmatl (aocmo monemitīa).</span>",
        "specialpages-group-other": "Oksẻki nònkuâkìskàtlaìxtlapaltìn",
        "specialpages-group-login": "Ximocalaqui / ximomachiyōmaca",
        "specialpages-group-changes": "Yancuīc tlapatlaliztli īhuān tlahcuilōlloh",
index f7fcfc6..93069ae 100644 (file)
        "whatlinkshere": "Tó-ūi liân kàu chia",
        "whatlinkshere-title": "Liân khì \"$1\" ê ia̍h-bīn",
        "whatlinkshere-page": "Ia̍h:",
-       "linkshere": "Í-hā '''[[:$1]]''' liân kàu chia:",
-       "nolinkshere": "Bô poàⁿ ia̍h liân kàu '''[[:$1]]'''.",
+       "linkshere-2": "Í-hā '''$1''' liân kàu chia:",
+       "nolinkshere-2": "Bô poàⁿ ia̍h liân kàu '''$1'''.",
        "isredirect": "choán-ia̍h",
        "isimage": "tóng-àn liân-kiat",
        "whatlinkshere-prev": "{{PLURAL:$1|chêng|chêng $1 ê}}",
index 09f09f2..e7b4c82 100644 (file)
        "redirectedfrom": "(Redirect 'a $1)",
        "redirectpagesub": "Paggena 'e redirect",
        "redirectto": "Reindirizza a:",
-       "lastmodifiedat": "Sta paggena fuje, n'urdema vota, cagnàta 'o $1, 'e $2.",
+       "lastmodifiedat": "Sta paggena fuje cagnàta ll'urdema vota 'o $1, 'e $2.",
        "viewcount": "Chesta paggena è stata liggiùta {{PLURAL:$1|una vòta|$1 vòte}}.",
        "protectedpage": "Paggena prutetta",
        "jumpto": "Vaje a:",
        "viewsource": "Vere sorgente",
        "viewsource-title": "Vere surgente 'e $1",
        "actionthrottled": "Azione ritardata",
-       "actionthrottledtext": "Comme misura anti-abuse, site lemmetato 'a ffà st'azione troppe vote dint'a nu curto spazio 'e tiempo, e mò stu lèmmeto è stato superato.\nPe' piacere pruvate n'ata vota dint'a cocche minuto.",
+       "actionthrottledtext": "Comme mesùra anti-abuse, site lemmetato 'a ffà st'azione troppe vote dint'a nu curto spazio 'e tiempo, e mo stu lèmmeto l'avite superato.\nPe piacere pruvate n'ata vota dint'a quacche minuto.",
        "protectedpagetext": "Sta paggena s'è prutetta pe' ne bloccà 'a mudifeca o n'ata azione.",
        "viewsourcetext": "Putite vedé e copià 'o codece surgiva 'e sta paggena.",
        "viewyourtext": "Putite vedé e copià 'o codice surgiva d' 'e <strong>cagnamiénte vuoste</strong> a sta paggena.",
        "virus-scanfailed": "scanziona fallita (codece $1)",
        "virus-unknownscanner": "antivirus scanusciuto:",
        "logouttext": "'''Site asciùte.'''\n\nNota ca arcune paggene putessero cuntinuà ad cumparì comme se 'o logout nun fosse affettuato fin quanno nun sarrà pulezzata 'a cache d\"o proprio browser.",
-       "cannotlogoutnow-title": "Nun se pò ascì mò",
+       "cannotlogoutnow-title": "Mo nun se pò ascì",
        "cannotlogoutnow-text": "'A disconessione nun è possibbele quanno s'ausa $1.",
        "welcomeuser": "Bemmenuto, $1!",
        "welcomecreation-msg": "'O cunto vuosto è stato criato.\nMo' putite cagnà 'e [[Special:Preferences|preferenze 'e {{SITENAME}}]].",
        "userlogin-signwithsecure": "Usa na conessione sicura",
        "cannotlogin-title": "Nun se pò trasì",
        "cannotlogin-text": "Trasì nun è possibbele mò.",
-       "cannotloginnow-title": "Nun se pò trasì mò",
+       "cannotloginnow-title": "Mo nun se pò trasì",
        "cannotloginnow-text": "'A connessione nun è possibbele quanno s'ausa $1.",
        "cannotcreateaccount-title": "Nun se ponno crià cunte",
        "cannotcreateaccount-text": "'A criazione diretta 'e cunte è stutata int'a stu wiki.",
        "password-login-forbidden": "L'uso 'e stu nomme utente e password è stato proibito.",
        "mailmypassword": "Riabbìa 'a password",
        "passwordremindertitle": "Nnova password temporale pe' {{SITENAME}}",
-       "passwordremindertext": "Cocche perzona (pussibbilmente tu, cu n'innerizzo IP $1) ha dimmannato l'invio 'e na password d'accieso nova pe' {{SITENAME}} ($4).\nNa password temporanea e' l'utente \"$2\" s'è abbiata comme \"$3\".\nSi chest'è stata l'intenzione toja, allora hè a trasì dint'o sito e cagnà 'a password mò. 'A password temporanea scade aropp'a {{PLURAL:$5|nu juorno|$5 ghiuorne}}.\n\nSi nun sì stato tu a dimannà 'a password, o pure hè truvat'a password e nun 'a bbuò cagnà cchiù, allora nun fà niente e continua a usare 'a password viecchia.",
+       "passwordremindertext": "Quaccheduno (pussibbilmente tu, cu n'innerizzo IP $1) ha dimmannato l'invio 'e na password d'accieso nova pe {{SITENAME}} ($4).\nNa password temporanea 'e l'utente \"$2\" s'è abbiata comme \"$3\".\nSi chest'è stata l'intenzione toja, allora hè a trasì dint'o sito e cagnà 'a password primm'e mo. 'A password temporanea scade aropp'a {{PLURAL:$5|nu juorno|$5 ghiuorne}}.\n\nSi nun sì stato tu a dimannà 'a password, o pure hê truvat'a password e nun 'a bbuò cagnà cchiù, allora nun fà niente e continua a usare 'a password viecchia.",
        "noemail": "Nun ce sta indirizzo e-mail pe' l'utente \"$1\".",
        "noemailcreate": "S'add'appruviggiunà n'indirizzo e-mail buono.",
        "passwordsent": "Na password nova è stata inviata a l'innerizzo e-mail riggistrato 'a ll'utente \"$1\".\nPe' piacere, trasite appena avite ricevuta sta password.",
        "eauthentsent": "Na mmasciata 'e conferma t'è stata mannata a l'indirizzo e-mail nzignàto.\nApprimm' 'e te mannà n'atu mail, hè 'a stà 'a ffà 'e struzione dint'a l'e-mail, pe' cunfermà ca 'o cunto fosse d' 'o tujo overo.",
        "throttled-mailpassword": "S'è mannata na mail pe te' riabbià 'a password 'a meno 'e {{PLURAL:$1|n'ora|$1 ore}}.\nPe' ce sparagnà abbuse, 'a funzione 'e riabbiamento d' 'a password se può usa sulamente na vota ogne {{PLURAL:$1|ora|$1 ore}}.",
        "mailerror": "Errore pe' tramente ca se mannava na mmasciata: $1",
-       "acct_creation_throttle_hit": "'E vvisite a sta wiki ausanno l'IP tuoja se so' mise a crià {{PLURAL:$1|1 registrazzione|$1 registrazzione}} int'a ll'urdeme juorne ($2), chesto fosse 'o massimo premmesso pe' stu periodo 'e tiempo.\nPerciò, 'e utente ca ausano chisto innerezzo IP nun se ponno riggistrà ancora mò mò.",
+       "acct_creation_throttle_hit": "'E vvisite a sta wiki ausanno l'IP tuoja se so' mise a crià {{PLURAL:$1|1 registrazzione|$1 registrazzione}} int'a ll'urdeme juorne ($2), chesto fosse 'o massimo premmesso pe' stu periodo 'e tiempo.\nPerciò, ll'utente ca ausano chisto innerezzo IP nun se ponno riggistrà mo.",
        "emailauthenticated": "'O ndirizzo email è stato cunfermato 'o $2 a 'e $3.",
        "emailnotauthenticated": "'O ndirizzo 'e posta elettronica nun è stat'ancora cunfermato.\nNun se mannarranno mmasciate e-mail p' ' funzione ccà abbascio.",
        "noemailprefs": "Avite 'a specificà nu ndirizzo e-mail pe ll'attivà sti funzione.",
        "subject-preview": "Anteprimma 'e l'oggetto:",
        "previewerrortext": "È succiesso n'errore quanno se steva a ffà pre-veré 'e cagnamiente vuoste.",
        "blockedtitle": "Utente bloccato.",
-       "blockedtext": "<strong>'O nomme utente o ll'IP vuosto è stato bloccato.</strong>\n\n'O blocco è stato mpustato 'a $1. 'O mutivo d' 'o blocco è chesto: ''$2''\n\n* Abbiàta d' 'o blocco: $8\n* Ammaturità d' 'o blocco: $6\n* Tiempo 'e blocco: $7\n\nPutite cuntattà $1 o n'atu [[{{MediaWiki:Grouppage-sysop}}|ammenistratore]] pe' discutere 'o blocco.\n\nVedite c' 'a funzione 'Scrivete a ll'utente' nun è attiva si nun s'è riggistrato 'o ndirizzo e-mail buono dint' 'e [[Special:Preferences|preferenze]] o pùre si ll'uso 'e tale funzione è stato bloccato.\n\n'O ndirizzo IP attuale è $3, 'o nummero ID d' 'o blocco è #$5.\nPe' piacere avite 'e specificà tutte sti dettaglie ccà ncoppa quanno facite cocche dumanna.",
+       "blockedtext": "<strong>'O nomme utente o ll'IP vuosto è stato bloccato.</strong>\n\n'O blocco è stato mpustato 'a $1. 'O mutivo d' 'o blocco è chisto: ''$2''\n\n* Abbiàta d' 'o blocco: $8\n* Ammaturità d' 'o blocco: $6\n* Tiempo 'e blocco: $7\n\nPutite cuntattà $1 o n'atu [[{{MediaWiki:Grouppage-sysop}}|ammenistratore]] pe discutere d'ô blocco.\n\nVedite c' 'a funzione \"{{int:emailuser}}\" nun è attiva si nun s'ave riggistrato 'o ndirizzo e-mail buono dint' 'e [[Special:Preferences|preferenze]] o pùre si ll'uso 'e tale funzione è stato bloccato.\n\n'O ndirizzo IP 'e mo è $3, 'o nummero ID d' 'o blocco è #$5.\nPe piacere avite 'a specificà tutte sti dettaglie quanno facite carche dumanna.",
        "autoblockedtext": "Ll'IP vuosto è stato bloccato pecché 'o steva piglianno n'atu utente, ch'è stato bloccato pe' $1.\n\n'O mutivo d' 'o blocco è chesto:\n\n:''$2''\n\n* Abbiàta d' 'o blocco: $8\n* Ammaturità d' 'o blocco: $6\n* Tiempo 'e blocco: $7\n\nPutite cuntattà $1 o n'atu [[{{MediaWiki:Grouppage-sysop}}|ammenistratore]] pe' discutere 'o blocco.\n\nVedite c' 'a funzione 'Scrivete a ll'utente' nun è attiva si nun s'è riggistrato 'o ndirizzo e-mail buono dint' 'e [[Special:Preferences|preferenze]] o pùre si ll'uso 'e tale funzione è stato bloccato.\n\n'O ndirizzo IP attuale è $3, 'o nummero ID d' 'o blocco è #$5.\nPe' piacere avite 'e specificà tutte sti dettaglie ccà ncoppa quanno facite cocche dumanna.",
-       "systemblockedtext": "'O nomme utente d' 'o vuosto o ll'IP address fosse stata automaticamente bluccata 'a MediaWiki.\n'O mutivo fosse chesto:\n\n:<em>$2</em>\n\n* Inizio d' 'o blocco: $8\n* Ammatura 'o blocco: $6\n* Intervall' 'e blocco: $7\n\n'O indirizzo IP 'e mò fosse $3.\nPe' piacere, facite specifice tuttuquante 'e ddettaglie ccà quanno iate a ghienchere na richiesta 'e chiarimiente.",
+       "systemblockedtext": "'O nomme utente d' 'o vuosto o ll'IP address songo stati automaticamente bluccati 'a MediaWiki.\n'O mutivo fosse chesto:\n\n:<em>$2</em>\n\n* Inizio d' 'o blocco: $8\n* Ammatura 'o blocco: $6\n* Intervall' 'e blocco: $7\n\n'O indirizzo IP fusse $3.\nPe piacere, facite specifice tutt' 'e ddettaglie ccà quanno iate a fà na richiesta 'e chiarimiente.",
        "blockednoreason": "nisciuna ragione è stata indicata",
        "whitelistedittext": "Pe' cagnà 'e ppaggene è necessario $1.",
        "confirmedittext": "Pe puté cagnà paggene avite 'a cunfermà l'indirizzo e-mail.\nPe' piacere abbiate e ffà 'a validazione d' 'o ndirizzo e-mail pe' bbìa d' 'e [[Special:Preferences|preferenze d'utente]].",
        "editingsection": "Cagnamiénto 'e $1 (sezzione)",
        "editingcomment": "Cagnamiénto 'e $1 (nova sezzione)",
        "editconflict": "Conflitto d'edizzione: $1",
-       "explainconflict": "N'at'utente ave sarvato na nova verziona d' 'a paggena pe' tramente ca stevate a fà 'e cagnamiente.\n'A cascia 'e mudifeca ncoppa cuntene 'o testo d' 'a paggena ca mò sta online, accussì comme è stato agghiurnato a l'at'utente.\n'A verziona ch' 'e cagnamiente vuoste è stata mmece riportata dint'a cascia 'e mudifeca abbascio.\nSi 'e vulite cunfermà avite 'a ripurtà 'e cagnamiente d' 'e vuoste dint'o testo ca esiste (dint'a cascia ncoppa).\nSpremmendo 'o buttón '$1', sarrà sarvato '''sulamente''' 'o testo cuntenuto dint'a cascia 'e cagnamiento ncoppa.",
+       "explainconflict": "N'at'utente ave sarvato na verziona nova d' 'a paggena pe tramente ca stevate a ffà 'e cagnamiente.\n'A cascia 'e mmudifeca ncoppa tene 'o testo d' 'a paggena ca sta online mo, accussì comme fuje agghiurnato pe ll'at'utente.\n'A verziona ch' 'e cagnamiente vuoste è stata mmece riportata dint'a cascia 'e mudifeca abbascio.\nSi 'e vulite cunfermà, avite 'a ripurtà 'e cagnamiente d' 'e vuoste dint'o testo ca esiste (dint'a cascia ncoppa).\nSpremmendo 'o buttón '$1', sarrà sarvato '''sulamente''' 'o testo cuntenuto dint'a cascia 'e cagnamiento ncoppa.",
        "yourtext": "'O testo vuosto",
-       "storedversion": "A verziona 'n memoria",
+       "storedversion": "A verziona int'a memoria",
        "editingold": "'''Attenziò: staje cagnanno na verziona nun agghiurnata d' 'a paggena. Si 'a sarve accussì, tutte 'e cagnamiente fatte aropp'a sta verziona sarranno sperdute.'''",
        "yourdiff": "Differenze",
        "copyrightwarning": "Pe' piacere tenite a mmente ca tutte 'e contribbute a {{SITENAME}} songo cunziderate pubbrecate dint'e térmene d'uso d' 'a licienza $2 (vedite $1 pe n'avé cchiù dettaglie).\nSi nun vulite ca 'e testi vuoste fossero cagnate e distribuite 'a uno qualunque senza lémmeto, nun 'e mannate ccà.<br />\nMannanno stu testo dichiarate pùre, sott'a responsabilità vuosta, ch'è stato scritto 'a vuje perzunalmente o pure ca è stato copiato 'a na fonte n pubblico dominio o similarmente libbera.\n'''Nun mannate materiale prutetto 'a copyright senz'avé autorizzaziona!'''",
        "permissionserrors": "Nun haje 'e premmesse abbastante.",
        "permissionserrorstext": "Nun haje premmesse pe lle ffà st'azziune, {{PLURAL:$1|'o mutivo è chesto|'e mutive so' chiste}}:",
        "permissionserrorstext-withaction": "Nun haje premmesse abbastante pe' $2, {{PLURAL:$1|'o mutivo è chesto|'e mutive so' chiste}}:",
-       "contentmodelediterror": "Vuje nun putite cagnà sta verziona pecché 'o mudell' 'e cuntenute è <code>$1</code>, ca cagnasse nu poco nfacc' 'o mudell' 'e mò d' 'a paggena è <code>$2</code>.",
+       "contentmodelediterror": "Vuje nun putite cagnà sta verziona pecché 'o mudello d' 'e cuntenute è <code>$1</code>, ca cagnasse nu poco nfacc' 'o mudello d' 'a paggena  <code>$2</code> 'e mo.",
        "recreate-moveddeleted-warn": "'''Attenziò: staje a crià na paggena scancellata già.'''\n\nVire si è bbuono 'e cuntinuà a cagnà sta paggena. L'elenco ch' 'e relative scancellamiente e spustamente s'è scritto ccà abbascio pe' ffà comodo:",
        "moveddeleted-notice": "Sta paggena è stata scancellata.\n'A lista d' 'e relative scancellamiente e spustamente sta cca 'bbascio pe' n'avé 'nfurmazione.",
        "moveddeleted-notice-recent": "Scusate, sta mmasciata è stata scancellata mo mo (dint'a sti 24 ore).\n\nL'aziune 'e scancellazione e spustamento pe' sta paggena so dispunibbele ccà p' 'a cumpretezza.",
        "rev-showdeleted": "faje vedé",
        "revisiondelete": "Scancella o ripiglia verziune",
        "revdelete-nooldid-title": "Verziona nun specificata",
-       "revdelete-nooldid-text": "Nun avite specificato nu target 'e verziona addò s'avess'apprecà sta funzione, o 'a verziona specificata nun esiste o pure jate truvanno 'annascónnere 'a verziona 'e mò.",
+       "revdelete-nooldid-text": "Nun avite specificato nisciuna verzione 'e target addò s'aviss'apprecà sta funzione, o 'a verziona specificata nun esiste o pure jate truvanno 'annascùnnere 'a verziona 'e mo.",
        "revdelete-no-file": "'O file specificato nun esiste.",
        "revdelete-show-file-confirm": "Sì sicuro/a ca vulite veré 'a verziona scancellata d' 'o file \"<nowiki>$1</nowiki>\" d' 'o $2 a 'e $3?",
        "revdelete-show-file-submit": "Sì",
        "revdelete-edit-reasonlist": "Càgna 'e mutive pe' fà 'o scancellamiento",
        "revdelete-offender": "Autore d' 'a verziona:",
        "suppressionlog": "Riggistro 'e luvamiente",
-       "suppressionlogtext": "Ccà abbascio ce sta n'alenco ch' 'e scancellamiente e blocche ca teneno cuntenute annascunnuto a l'ammenistrature.\nVide l'[[Special:BlockList|elenco d' 'e blocche]] pe' l'elenco e banne e blocche attive 'e mò.",
+       "suppressionlogtext": "Ccà abbascio ce sta n'alenco 'e scancellamiente e blocche ca teneno cuntenute annascunnuti â ll'ammenistrature.\nVide l'[[Special:BlockList|elenco d' 'e blocche]] pe ll'elenco e banne e blocche attive ca ce stanno mo.",
        "mergehistory": "Aunisce 'e cronologgie",
        "mergehistory-header": "Sta paggena te permette d'aunì 'e verziune d' 'a cronologgia 'e na paggena origgine a na paggena nova.\nVedite ca s'avesse 'a nchiantà stu cagnamiento senza scassà 'a continuità storeca d' 'a paggena.",
        "mergehistory-box": "Aunisce 'a cronologgia 'e ddoje ppaggene:",
        "right-suppressrevision": "Vide, annascunne e ripiglia 'e verziune specifiche d' 'e paggene a cocherun'utente",
        "right-viewsuppressed": "Vide 'e verziune annascunnute a coccherun'utente",
        "right-suppressionlog": "Vide 'e riggistre private",
-       "right-block": "Blocca 'e cagnamiente 'a parte 'e l'at'utente",
-       "right-blockemail": "Blocca n'utente a mannà e-mail",
+       "right-block": "Nun fa fa' cagnamienti a ll'at'utente",
+       "right-blockemail": "Nun fa mannà e-mail a n'utente",
        "right-hideuser": "Blocca n'utente e fallo sparì 'a 'o pubbreco",
        "right-ipblock-exempt": "Ignora 'e blocche 'e l'IP, 'e blocche automatece e li blocche 'e range 'e l'IP",
        "right-unblockself": "Sblocca se stesso",
        "grant-group-administration": "Secuta aziune ammenistrative",
        "grant-group-private-information": "Tràse dint' 'e date private ncopp'a tte",
        "grant-group-other": "Attività differénte",
-       "grant-blockusers": "Blocca e sblocca utente",
+       "grant-blockusers": "Fremma e lassa i ll'utenti",
        "grant-createaccount": "Crìa cunte",
        "grant-createeditmovepage": "Créa, cagna e móve paggene",
        "grant-delete": "Scancella paggene, verziune, trasute 'e riggistro",
        "action-undelete": "arripiglia chista paggena",
        "action-suppressrevision": "rivedé e arripiglià 'e cagnamiente annascunnute",
        "action-suppressionlog": "vide stu riggistro privato",
-       "action-block": "blocca 'e cagnamiente 'a parte 'e st'utente",
+       "action-block": "fremma st'utente 'e fa' cagnamiente",
        "action-protect": "cagna 'e livelle 'e prutezione pe' sta paggena",
        "action-rollback": "annulla ampresso 'e cagnamiente 'e ll'urdem'utente c'avesse cagnato na paggena particulare",
        "action-import": "carreca paggene 'a n'ata wiki",
        "recentchangeslinked-feed": "Cagnamiénte cullegate",
        "recentchangeslinked-toolbox": "Cagnamiénte cullegate",
        "recentchangeslinked-title": "Cagnamiénte cullegate a \"$1\"",
-       "recentchangeslinked-summary": "Chest'è n'alenco d' 'e cagnamiente fatte mò a 'e paggene cullegate 'a chilla specificata (o pe' cuntenute dint'a na categurìa specificata). 'E paggene cuntenute dint' 'o proprio elenco 'e l'[[Special:Watchlist|Paggene cuntrullate]] songo mmustate 'n '''grassetto'''.",
+       "recentchangeslinked-summary": "Nzerta nu nomme 'e paggena pe verè 'e cagnamiente fatte ê paggene cullegate 'a chella specificata (pe verè ll'elementi 'e na categurìa, scrivi {{ns:category}}:Nomme categurìa). 'E cagnamiente cuntenute dint' 'a ll'elenco 'e l'[[Special:Watchlist|Paggene cuntrullate]] songo mmustate c'ô '''grassetto'''.",
        "recentchangeslinked-page": "Nomme d' 'a paggena",
        "recentchangeslinked-to": "Mmusta sulamente 'e cagnamiente a 'e paggene cullegate a chilla specificata",
        "recentchanges-page-added-to-category": "[[:$1]] azzeccato â categurìa",
        "tmp-write-error": "Errore a scrivere nu file temporaneo.",
        "large-file": "S'arraccumanna 'e nun appassà 'e diminsione 'e $1 p'ogne file; stu file è gruosso $2.",
        "largefileserver": "Stu file appassa 'e dimensiune permesse 'a la configurazione d' 'o server",
-       "emptyfile": "'O file carrecato mò mò pare abbacante. Può darse ch'è stato n'errore int' 'o nomme d' 'o file. Cuntrullate ca vulite overamente carrecà stu file.",
+       "emptyfile": "'O file c'avite carrecato pare avvacante. Può essere ch'è stato n'errore int' 'o nomme d' 'o file. Cuntrullate ca vulite overamente carrecà stu file.",
        "windows-nonascii-filename": "Chista wiki nun supporta nomme d' 'e file cu carattere spiciale",
        "fileexists": "Nu file cu stu nomme esiste già.\nPe' piacere cuntrullate primma <strong>[[:$1]]</strong> si nun site sicure ca 'o vulite cagnà.\n[[$1|thumb]]",
        "filepageexists": "'A paggena 'e descrizione 'e stu file è stata già criata a l'indirizzo <strong>[[:$1]]</strong>, pùre si nun esiste ancora nu file cu stu nomme. 'A descrizione 'e l'oggetto nzertàta 'n fase 'e carreca nun cumparerrà ncopp' 'a paggena 'e descrizione. Pe' ffà l'oggetto cumparì ncopp' 'a paggena 'e descrizione, l'avisseve 'a cagnà manualmente.\n[[$1|thumb]]",
        "uploaded-animate-svg": "Truvato 'o tag \"animate\" ca putesse stà a cagnà href, ausanno l'attribbuto \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> int' 'o file carrecato SVG.",
        "uploaded-setting-event-handler-svg": "Mpustà n'attributo event-handler è bluccato, truvato <code>&lt;$1 $2=\"$3\"&gt;</code> int' 'o fie carrecato SVG.",
        "uploaded-setting-href-svg": "Ausà 'o tag \"set\" pe' putè azzeccà attribbute \"href\" a l'elemento parente è bluccato.",
-       "uploaded-wrong-setting-svg": "D'ausà 'o tag \"set\" pe' putè azzeccà nu target remoto/date/script a n'attribbuto mò è bluccato. Truvato 'o code>&lt;set to=\"$1\"&gt;</code> dint' 'o file SVG carrecato.",
+       "uploaded-wrong-setting-svg": "D'ausà 'o tag \"set\" pe putè azzeccà nu target remoto/date/script a n'attribbuto mo sta bluccato. Truvato 'o code>&lt;set to=\"$1\"&gt;</code> dint' 'o file SVG carrecato.",
        "uploaded-setting-handler-svg": "'o SVG ca mpustasse l'attribbuto \"handler\" cu nu remoto/date/script è bluccato. Truvato <code>$1=\"$2\"</code> dint' 'o file SVG carrecato.",
        "uploaded-remote-url-svg": "SVG ca mpustasse n'attribbuto 'e stile cu n'URL remota bluccata. Truvate <code>$1=\"$2\"</code> int' 'o file carrecato SVG.",
        "uploaded-image-filter-svg": "Truvato filtro immaggene cu n'URL: <code>&lt;$1 $2=\"$3\"&gt;</code> int' 'o file SVG carrecato.",
        "backend-fail-read": "Nun se può lieggere 'o file \"$1\".",
        "backend-fail-create": "Nun se può scrivere 'o file \"$1\"",
        "backend-fail-maxsize": "Nun se può scrivere 'o file \"$1\" pecché chist'è cchiù gruosso 'e {{PLURAL:$2|nu byte|$2 byte}}",
-       "backend-fail-readonly": "L'archivio 'e rezza \"$1\" è mò mò 'n sola-lettura. 'O mutivo è: <em>$2</em>",
+       "backend-fail-readonly": "L'archivio 'e rezza \"$1\" sta mo c'â sola-lettura. 'O mutivo è: <em>$2</em>",
        "backend-fail-synced": "'O file \"$1\" è int' 'a nu stato ncunzistente dint'a l'archivie nterne.",
        "backend-fail-connect": "Nun se può cunnettà â memoria 'e rezza \"$1\".",
        "backend-fail-internal": "N'errore scanusciuto s'è verificato int'a l'archivie 'e rezza \"$1\".",
        "filerevert-submit": "Arrepiglia",
        "filerevert-success": "'''[[Media:$1|$1]]''' è stat'arripigliato â verziona [$4 d' 'e $3 d' 'o $2].",
        "filerevert-badversion": "Nun ce sta na virziona lucale 'e stu file cu l'orario addimannato.",
-       "filerevert-identical": "'A verziona 'e mò d' 'o file è già eguale eguale a chilla scigliuta.",
+       "filerevert-identical": "'A verziona 'e mo d' 'o file è già eguale eguale a chella scigliuta.",
        "filedelete": "Scancella $1",
        "filedelete-legend": "Scancella 'o file",
        "filedelete-intro": "State pe' scancellà 'o file '''[[Media:$1|$1]]''' cu tutta 'a cronologgia 'e chisto.",
        "deadendpagestext": "'E paggene ccà abbascio nun spontano a n'ati paggene ncopp'a {{SITENAME}}.",
        "protectedpages": "Paggene prutette",
        "protectedpages-indef": "Sulamente prutezziune a tiempo nun definito",
-       "protectedpages-summary": "Sta paggena elenca 'e paggene ch'esisteno e ca songo prutette mò. Pe n'avé n'elenco 'e titule prutette â criazione, vedite [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
+       "protectedpages-summary": "Sta paggena elenca 'e paggene ch'esisteno e ca mo stanne prutette. P'avé n'elenco 'e titule prutette â criazione, vedite [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Sulamente prutezziune ricurzive",
        "protectedpages-noredirect": "Annascunne redirect",
-       "protectedpagesempty": "Nisciuna paggena è prutetta pe mò cu sti parametre.",
+       "protectedpagesempty": "Nisciuna paggena è prutetta pe mo cu sti parametre.",
        "protectedpages-timestamp": "Data e ora",
        "protectedpages-page": "Paggena",
        "protectedpages-expiry": "Ammatura",
        "protectedpages-unknown-performer": "Utente scanusciuto",
        "protectedtitles": "Paggene prutette",
        "protectedtitles-summary": "Sta paggena elenca 'e titule ca song'attualmente prutette 'a criazione. Pe' n'avé n'elenco 'e paggene prutette ch'esisteno, vedite [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
-       "protectedtitlesempty": "Nisciunu titolo è prutetto pe mò cu sti parametre.",
+       "protectedtitlesempty": "Nisciuno titolo è prutetto pe mo cu sti parametre.",
        "protectedtitles-submit": "Mmusta titule",
        "listusers": "Lista 'e l'utente",
        "listusers-editsonly": "Fà vedé sulamente l'utente cu cagnamiente fatte",
        "apisandbox-dynamic-parameters-add-label": "Azzecca nu parametro:",
        "apisandbox-dynamic-parameters-add-placeholder": "Nomme d' 'o parametro",
        "apisandbox-dynamic-error-exists": "Nu parametro denommenato \"$1\" esiste già.",
-       "apisandbox-deprecated-parameters": "Parametre mò obsoleti",
+       "apisandbox-deprecated-parameters": "Parametri obsoleti",
        "apisandbox-fetch-token": "Auto-ghienche 'o token",
        "apisandbox-submit-invalid-fields-title": "Cocche campo nun è buono",
        "apisandbox-submit-invalid-fields-message": "Pe' piacere curriggite 'e campe nzegnàte e tentate n'ata vota.",
        "unwatchthispage": "Nun cuntrullà cchiù sta paggena",
        "notanarticle": "Chesta paggena nun è na voce",
        "notvisiblerev": "'A verzione è stata scancellata",
-       "watchlist-details": "L'elenco 'e paggene cuntrullate tene {{PLURAL:$1|na paggena (e pure 'a paggena 'e chiacchiera)|$1 paggene (e pure 'e ppaggene 'e chiacchiera}}.",
+       "watchlist-details": "L'elenco 'e paggene cuntrullate tene {{PLURAL:$1|na paggena (e pure 'a paggena 'e chiacchiera)|$1 paggene (e pure 'e ppaggene 'e chiacchiera)}}.",
        "wlheader-enotif": "'A funzione 'e notifiche e-mail è appicciata.",
        "wlheader-showupdated": "* 'E paggene cca so' state cagnate a l'urdema visita avevano so' nzignate ccà 'n '''grassetto'''.",
        "wlnote": "Ccà abbascio {{PLURAL:$1|è elencato 'o cagnamiento cchiù ricente|songo elencate 'e <strong>$1</strong> cagnamiente cchiù recente}} {{PLURAL:$2|int'a ll'urdema ora|int' 'e ll'urdeme <strong>$2</strong> ore}}; 'e date songo agghiurnate 'o $3, $4.",
        "whatlinkshere": "Paggene ca cullegano a chesta",
        "whatlinkshere-title": "Paggene ca cullegano a $1",
        "whatlinkshere-page": "Paggena:",
-       "linkshere": "'E paggene ccà abbascio cunteneno jonte ca spuntano a '''[[:$1]]'''.",
-       "nolinkshere": "Nisciuna paggena cuntene jonte ca spuntasse a <strong>[[:$1]]</strong>.",
-       "nolinkshere-ns": "Nun ce stanno paggene ca spuntassero '''[[:$1]]''' dint' 'o namespace scigliuto.",
+       "linkshere-2": "'E paggene ccà abbascio cunteneno jonte ca spuntano a '''$1'''.",
+       "nolinkshere-2": "Nisciuna paggena cuntene jonte ca spuntasse a <strong>$1</strong>.",
+       "nolinkshere-ns-2": "Nun ce stanno paggene ca spuntassero '''$1''' dint' 'o namespace scigliuto.",
        "isredirect": "redirect a paggena",
        "istemplate": "'nclusione",
        "isimage": "Cullegamente a file multimediale",
        "whatlinkshere-filters": "Filtre",
        "whatlinkshere-submit": "Vaje",
        "autoblockid": "Autoblocco #$1",
-       "block": "Blocca l'utente",
+       "block": "Fremma st'utente.",
        "unblock": "Sblocca l'utente",
-       "blockip": "Blocca {{GENDER:$1|utente}}",
+       "blockip": "Fremma {{GENDER:$1|utente}}",
        "blockiptext": "Ausa 'o modulo ccà abbascio pe' bluccà l'acciesso 'e scrittura a n'indirizzo IP o utente.\nChisto s'avesse 'a ffà sulamente pe' se pruteggere d' 'o vandalismo, d'accordo ch' [[{{MediaWiki:Policy-url}}|'e reole]].\nMettite pure nu mutivo specifico ccà abbascio (p'esempio, facenno 'o nomme 'e paggene addò se so' fatte 'e vandalisme).\nPutite bluccà ntervalle IP ausanno 'a sintasse [https://it.wikipedia.org/wiki/CIDR CIDR]; l'intervallo cchiù ampio cunzentito è /$1 pe' IPv4 e /$2 pe' IPv6.",
        "ipaddressorusername": "Nnerizzo IP o nomme utente",
        "ipbexpiry": "Ammatura:",
        "ipbreason-dropdown": "* Mutive comune pe' ffà 'o blocco\n** Steva nzertanno nfurmaziune fauze\n** Steva a luvà cuntenute d' 'e paggene\n** Steva a fà spam 'e cullegamiente a 'e site 'e fore\n** Steva a nzertà robbe senza senso dint' 'e paggene\n** Minacce e ntimidaziune\n** Abbuso 'e cunte utente multiple\n** Nomme utente inaccettabbele",
        "ipb-hardblock": "Nun permettere 'o cagnamiento a l'utente riggistrate ca veneno 'a st'indirizzo IP",
        "ipbcreateaccount": "Nun fà crià 'o cunto",
-       "ipbemailban": "Blocca utente a mannà e-mail",
-       "ipbenableautoblock": "Automaticamende blocca l'urdeme indirizze IP ausate 'a st'utente, e pure tutte l'IP c'ausasse pe' pruvà 'e fà ati cagnamiente",
-       "ipbsubmit": "Blocca st'utente",
+       "ipbemailban": "Nun fa mannà e-mail a st'utente",
+       "ipbenableautoblock": "Fremma automaticamende l'urdeme indirizze IP ausate 'a st'utente, e pùre tutte ll'IP c'ausasse pe pruvà 'e fà ati cagnamienti",
+       "ipbsubmit": "Fremma st'utente",
        "ipbother": "N'ata durata:",
        "ipboptions": "2 ore:2 hours,1 juorno:1 day,3 juorne:3 days,1 semmana:1 week,2 semmane:2 weeks,1 mese:1 month,3 mise:3 months,6 mise:6 months,1 anno:1 year,infinito:infinite",
        "ipbhidename": "Annascunne 'o nomme utente d' 'a lista 'e cagnamiente e l'ati liste",
        "ipbwatchuser": "Fà vedé 'a paggena utente e le chiacchieriate 'e st'utente",
        "ipb-disableusertalk": "Nun permettere a st'utente edità 'a paggena 'e chiacchiera d' 'a soja pe' tramente ch'e bloccato",
-       "ipb-change-block": "Blocca n'ata vota l'utente cu sti mpustaziune",
+       "ipb-change-block": "Fremma n'ata vota ll'utente cu ste mpustaziune",
        "ipb-confirm": "Cunferma 'o blocco",
        "badipaddress": "Indirizzo IP nun valido",
        "blockipsuccesssub": "Blocco aseguito",
        "blocklist-nousertalk": "nun può cagnà 'a paggena 'e chiacchiera d' 'a soja",
        "ipblocklist-empty": "'A lista 'e blocche è abbacante.",
        "ipblocklist-no-results": "L'indirizzo IP o nomme utente c'asciate nun songo bloccate.",
-       "blocklink": "ferma",
+       "blocklink": "fremma",
        "unblocklink": "sblocca",
        "change-blocklink": "càgna blocco",
        "contribslink": "contribuzzione",
        "blocklogpage": "Blocche",
        "blocklog-showlog": "St'utente è stato bloccato primma.\n'O riggistro d' 'e blocche se può vedé ccà abbascio pe' riferimento:",
        "blocklog-showsuppresslog": "St'utente è stato bloccato e annascunuto primma.\n'O riggistro d' 'e luvamiente se può vedé ccà abbascio pe' riferimento:",
-       "blocklogentry": "ha fermato \"[[$1]]\" pe' nu mumento 'e $2 $3",
+       "blocklogentry": "ha fremmato \"[[$1]]\" pe nu mumento 'e $2 $3",
        "reblock-logentry": "cagnate 'e mpustaziune 'e blocco pe' [[$1]] cu na data d'ammaturamiento 'e $2 $3",
        "blocklogtext": "Chesta è 'a lista d''e azzione 'e blocco e sblocco utente.  'E nnerizze IP bloccate automaticamente nun nce so'. Addumannà 'a [[Special:BlockList|lista bloccate]] pp' 'a lista d''e nnerizze e nomme utente 'o ca blocco nce sta.",
        "unblocklogentry": "sbluccato $1",
        "cant-see-hidden-user": "L'utente ca state a bluccà è stato già bluccato e annascunnuto. Si nun tenite 'o deritto ''hideuser'', nun putite veré stu blocco d'utente.",
        "ipbblocked": "Nun putite bloccà o sbluccà utente pecche vuje stesso site bluccato.",
        "ipbnounblockself": "Nun avite permesso a ve bluccà vuje stesso.",
-       "lockdb": "Blocca 'o database",
+       "lockdb": "Nzerra 'o database",
        "unlockdb": "Sblocca 'o database",
        "lockdbtext": "Bluccanno 'o database se luvarranno l'abbilità 'e tutte l'utente 'e cagnà 'e paggene, cagnà 'e preferenze lloro, cagnà 'a lista 'e paggene cuntrullate e ati cose ca richiedessero cagnamiente ô database.\nPe' piacere cunfermate ca chisto e chello ca vulite fà, e ca luvarrate 'o blocco ô database quanno sta manutenziona sarrà fernuta.",
        "unlockdbtext": "Sbluccanno 'o database se s'arrepigliarranno l'abbilità 'e tutte l'utente 'e cagnà 'e paggene, cagnà 'e preferenze lloro, cagnà 'a lista 'e paggene cuntrullate e ati cose ca richiedessero cagnamiente ô database.\nPe' piacere cunfermate ca chisto e chello ca vulite fà.",
        "lockconfirm": "Sì, overo vulesse bluccà 'o database.",
        "unlockconfirm": "Sì, overo vulesse sbluccà 'o database.",
-       "lockbtn": "Blocca 'o database",
+       "lockbtn": "Nzerra 'o database",
        "unlockbtn": "Sblocca 'o database",
        "locknoconfirm": "Nun avite scigliuto 'a casciulella 'e cunferma.",
        "lockdbsuccesssub": "Blocco d' 'o database secutato",
        "tooltip-pt-anoncontribs": "N'elenco 'e cagnamiente fatte 'a st'indirizzo IP",
        "tooltip-pt-login": "A reggistrazione è cunsigliata",
        "tooltip-pt-logout": "Jésce (logout)",
-       "tooltip-pt-createaccount": "Pigliateve curaggio e criate n'utente e trasìte; ancora ca chisto nun s'avesse 'a ffà pe' fforza",
+       "tooltip-pt-createaccount": "Pigliateve curaggio e criate n'utente e trasìte; eziamme ca chisto nun s'avesse 'a ffà pe' fforza",
        "tooltip-ca-talk": "Vede e discussione rilative a chista paggena",
        "tooltip-ca-edit": "Cagna sta paggena",
        "tooltip-ca-addsection": "Cummincia 'na nova sezzione",
        "tooltip-n-mainpage": "Visita a paggena prencepale",
        "tooltip-n-mainpage-description": "Visita a paggena prencepale",
        "tooltip-n-portal": "Descrizione d' 'o prugietto, che po' ffa, addò truvà 'e ccose",
-       "tooltip-n-currentevents": "Ascìa 'e nfurmaziune ncopp' 'e fatte succiesse mò mò",
+       "tooltip-n-currentevents": "Ascìa 'e nfurmaziune ncopp' 'e fatte succiesse mo mmo",
        "tooltip-n-recentchanges": "Ennece dde urdeme cagnamiénte d' 'o sito",
        "tooltip-n-randompage": "Na paggena qualsiase",
        "tooltip-n-help": "Paggena 'e ajùto",
        "tooltip-t-info": "Cchiù nfurmaziune ncopp'a sta paggena",
        "tooltip-t-upload": "Carreca file",
        "tooltip-t-specialpages": "Lista 'e tutte e paggene speciale",
-       "tooltip-t-print": "Vversione pe' stampa 'e chista paggena",
+       "tooltip-t-print": "Vversione pe stampà 'a chesta paggena",
        "tooltip-t-permalink": "Jonta permanente a chista vversione dda paggena",
        "tooltip-ca-nstab-main": "Vere a paggena e contenuto",
        "tooltip-ca-nstab-user": "Vere a paggena utente",
        "tooltip-watchlistedit-raw-submit": "Agghiurna l'elenco 'e paggene cuntrullate",
        "tooltip-recreate": "Arricrèa 'e paggene pure si so state scancellate",
        "tooltip-upload": "Accummencia 'a carreca",
-       "tooltip-rollback": "\"A vascio\" annulla 'e modefeche 'e chista paggena ell'ultimo contributore cu n' uneco click",
+       "tooltip-rollback": "\"A vascio\" annulla 'e cagnamiente a chesta paggena a ll'ultimo contributore cu nu click sulo",
        "tooltip-undo": "\"Annulla\" annulla stu cagnamiento e arape 'u form 'e cagnamiento facenno vedé l'anteprimma.\nPermette azzeccà nu mutivo dint' 'o riepilego.",
        "tooltip-preferences-save": "Riggistra 'e preferenze",
        "tooltip-summary": "Miette nu riepilego piccerillo",
        "months": "{{PLURAL:$1|$1 mese|$1 mese}}",
        "years": "{{PLURAL:$1|$1 anno|$1 anne}}",
        "ago": "$1 fà",
-       "just-now": "mò mò",
+       "just-now": "mo mmo",
        "hours-ago": "$1 {{PLURAL:$1|ora|ore}} fà",
        "minutes-ago": "$1 {{PLURAL:$1|minuto|minute}} fà",
        "seconds-ago": "$1 {{PLURAL:$1|secondo|seconde}} fà",
        "confirmemail": "Cunfermate 'o nderizzo mail",
        "confirmemail_noemail": "Nun tenite nu nderizzo e-mail bbuono pe' ve putè configurà ncopp' 'e [[Special:Preferences|preferenze vuoste]].",
        "confirmemail_text": "{{SITENAME}} bbuò ca vuje validasseve 'o nderizzo e-mail vuosto apprimm' 'e putè ausà 'e ffunziune 'e-mail.\nSpremmete 'o buttone 'e sotto pe' mannà na mmasciata e-mail 'e cunferma a l'indirizzo vuosto.\n'A mmasciata e-mail ca v'arreverrà tenesse nu cullegamento cu nu codece; carrecate 'o cullegamiento dint' 'a nu navigatóre web pe' ve putè cunfermà cu stu ndirizzo e nce ffà assapé 'o sito ch' 'è bbuono.",
-       "confirmemail_pending": "Nu codece 'e cunferma è stato gia mannato a l'email vuosto;\nSi mò mò nu cunto utente avite criato, allora putite aspettà cocche minuto ca chist'arriva, apprimm' 'e pruvà n'ata vota 'addimannà nu codece nuovo.",
+       "confirmemail_pending": "Nu codece 'e cunferma è stato mannato ggià a ll'email vuosto;\nSi avite criato 'a poco nu cunto utente, allòra putite aspettà quacche minuto ca chist'arriva, primm' 'e pruvà n'ata vota a 'ddimannà nu codece nuovo.",
        "confirmemail_send": "Manna nu codece 'e cunferma",
        "confirmemail_sent": "Mmasciata e-mail 'e cunferma mannata.",
        "confirmemail_oncreate": "'O codece 'e cunferma è stato mannato al'indirizzo e-mail d' 'o vuosto.\nStu codece nun è addimannato pe' ve putè fà trasì, ma vuje n'avite abbesuogno 'e l'avé apprimm' 'e putè ausà cocche funziune 'e chille ca facessero l'uso d' 'o cunto e-mail ncopp'a sta wiki.",
        "confirmemail_sendfailed": "{{SITENAME}} nun può mannà 'a mmasciata e-mail d' 'a vuosta 'e cunferma.\nPe' piacere cuntrullate si 'o nderizzo e-mail c'avite scritto tenesse cocche carattere nvalido.\n\nMmasciata d'errore a 'o mailer: $1",
        "confirmemail_invalid": "'O codece 'e cunferma nun è bbuono.\n'O codece fosse ammaturato.",
        "confirmemail_needlogin": "Abbesognate $1 pe cunfirmà 'o nnerizzo 'e e-mail d''o vuosto.",
-       "confirmemail_success": "'O ndirizzo e-mail d' 'o vuosto è stato cunfermato.\nVuje mò ne putite [[Special:UserLogin|trasì]] e ve putite spassà ncopp' 'a wiki.",
+       "confirmemail_success": "'O ndirizzo e-mail d' 'o vuosto è stato cunfermato.\nMo putite [[Special:UserLogin|trasì]] e ve putite spassà ncopp' 'a wiki.",
        "confirmemail_loggedin": "'O nnerizzo 'e e-mail è vàleto",
        "confirmemail_subject": "Indirizzo e-mail 'e cunferma pe' {{SITENAME}}",
        "confirmemail_body": "Coccheruno, può darse ca site vuje, 'a l'indirizzo IP $1,\nha riggistrato nu cunto utente \"$2\" cu st'indirizzo e-mail ncopp'a {{SITENAME}}.\n\nPe' putè cunfermà ca stu cunto è stato overo criato e vuje e ve putè apiccià 'a funziona e-mail 'e {{SITENAME}}, arapite stu cullegamento dint' 'o navigatóre web d' 'o vuosto:\n\n$3\n\nSi vuje *NUN* avite riggistrato 'o cunto utente, secutate stu cullegamento pe' ve scancellà st'indirizzo e-mail utente:\n\n$5\n\nStu codece 'e cunferma murarrà 'o $4.",
        "invalidateemail": "Scancella 'a cunferma 'e l'e-mail",
        "notificationemail_subject_changed": "L'indirizzo email riggistrato ncopp'a {{SITENAME}} è stato cagnato",
        "notificationemail_subject_removed": "L'indirizzo email riggistrato dint'a {{SITENAME}} è stato luvato",
-       "notificationemail_body_changed": "Coccheruno, probbabilmente vuje, 'a ll'indirizzo IP $1,\nave cagnato l'indirizze e-mail d' 'o cunto \"$2\" a \"$3\" ncopp'a {{SITENAME}}.\n\nSi nun eravate vuje, pe' piacere tuzzuliate mò mò n'ammenistratore.",
-       "notificationemail_body_removed": "Coccheruno, probbabilmente vuje, 'a ll'indirizzo IP $1,\nave luvato l'indirizze e-mail d' 'o cunto \"$2\" ncopp'a {{SITENAME}}.\n\nSi nun eravate vuje, pe' piacere tuzzuliate mò mò n'ammenistratore.",
+       "notificationemail_body_changed": "Coccheruno, probbabilmente vuje, a ll'indirizzo IP $1,\nave cagnato 'o ndirizzo e-mail d' 'o cunto \"$2\" a \"$3\" ncopp'a {{SITENAME}}.\n\nSi nun eravate vuje, pe piacere tuzzuliate a n'ammenistratore primma 'e mo.",
+       "notificationemail_body_removed": "Coccheruno, probbabilmente vuje, 'a ll'indirizzo IP $1,\nave luvato l'indirizze e-mail d' 'o cunto \"$2\" ncopp'a {{SITENAME}}.\n\nSi nun eravate vuje, pe piacere tuzzuliate a n'ammenistratore.",
        "scarytranscludedisabled": "['A funziona cullegamiento nfra site wiki è stata stutata]",
        "scarytranscludefailed": "[L'analisi d' 'o template s'è scassato pe' $1]",
        "scarytranscludefailed-httpstatus": "[L'analisi d' 'o template s'è scassato pe' $1: HTTP $2]",
        "timezone-local": "Lucale",
        "duplicate-defaultsort": "<strong>Attenziò:</strong> A chiave d'arricetto \"$2\" se miette ncuollo a nu valore 'e primma \"$1\".",
        "duplicate-displaytitle": "<strong>Attenziò:</strong> A chiave d'arricetto \"$2\" se scagna p' 'o valore 'e primma \"$1\".",
-       "restricted-displaytitle": "<strong>Attenziò:</strong> 'O titolo ccà \"$1\" è stato lassato perdere pecché nun fosse eguale a 'o titolo 'e mò d' 'a paggena.",
+       "restricted-displaytitle": "<strong>Attenziò:</strong> 'O titolo ccà \"$1\" è stato lassato perdere pecché nun fosse eguale a 'o titolo 'e mo d' 'a paggena.",
        "invalid-indicator-name": "<strong>Errore:</strong> attribbuto <code>name</code> 'e ll'innecature d' 'o stato d' 'a paggena nu può rummanè abbacante.",
        "version": "Verziona",
        "version-extensions": "Estenziune installate",
        "fileduplicatesearch-noresults": "Nisciuno file chiamato \"$1\" è stato accucchiato.",
        "specialpages": "Paggene speciale",
        "specialpages-note-top": "Liggenda",
+       "specialpages-note-restricted": "* Paggene speciale normale.\n* <span class=\"mw-specialpagerestricted\">Paggene speciale ch' 'e restriziune.</span>",
        "specialpages-group-maintenance": "Report 'e manutenzione",
        "specialpages-group-other": "Ati paggene speciale",
        "specialpages-group-login": "Trasite o criate n'acciesso nuovo",
-       "specialpages-group-changes": "Cagnamiente 'e mò mò e riggistre",
+       "specialpages-group-changes": "Urdeme cagnamiénte e riggistre",
        "specialpages-group-media": "Riepileghe 'e media e carreche",
        "specialpages-group-users": "Utente e deritte",
        "specialpages-group-highuse": "Pàggene ausate assaje proprio",
        "tags-create-warnings-below": "Vulite cuntinuà a crià 'o tag?",
        "tags-delete-title": "Scancella tag",
        "tags-delete-explanation-initial": "State pe' scancellà 'o tag \"$1\" d' 'o database.",
-       "tags-delete-explanation-in-use": "Sarrà luvato d' 'o {{PLURAL:$2|$2 verziona o d' 'o riggistro|tutt' 'e verziune $2 e/o 'e nutarelle int' 'o riggistro}} ô quale fosse azzeccato mò mò.",
+       "tags-delete-explanation-in-use": "Sarrà luvato d' 'o {{PLURAL:$2|$2 verziona o d' 'o riggistro|tutt' 'e verziune $2 e/o 'e nutarelle int' 'o riggistro}} addò stesse azzeccato.",
        "tags-delete-explanation-warning": "St'aziona è <strong>irreversibbele</strong> e <strong>nun se pò turnà arreto</strong>, pure 'a ll'ammenistrature d' 'o database. Faciteve capace ca stu tag è chillu ca vulite scancellà.",
        "tags-delete-explanation-active": "<strong>'O tag \"$1\" è ancora attivo, e sarrà apprecato int' 'o futuro.</strong> Pe' fernì cu st'attività, jate, a lloco addò 'o tag s'è apprecato, e stutate llànno.",
        "tags-delete-reason": "Mutivo:",
        "dberr-info": "(Nun se può trasì 'o database: $1)",
        "dberr-info-hidden": "(Nun se può trasì 'o database)",
        "dberr-usegoogle": "Pe' tramente putite pruvà 'ascianno ncoppa Google.",
-       "dberr-outofdate": "Vedite ca l'indice lloro d' 'e cuntenute nuoste ponno nun essere agghiurnate mò mò.",
+       "dberr-outofdate": "Vedite ca ll'indice lloro d'ê cuntenute nuoste ponno essere passate.",
        "dberr-cachederror": "Chest'è na copia \"cache\" d' 'a paggena c'avite asciato, e putesse nun essere agghiurnata.",
        "htmlform-invalid-input": "Ce sta cocche probblema cu l'input c'avite miso.",
        "htmlform-select-badoption": "'O valore c'avite specificato nun è n'opziona bbuona.",
        "logentry-delete-delete": "$1 {{GENDER:$2|scancellaje}} 'a paggena $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|arrepigliaje}} 'a paggena $3 ($4)",
        "logentry-delete-event": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà 'e {{PLURAL:$5|n'azione d' 'o riggistro|$5 aziune d' 'o riggistro}} ncopp' 'a 'a $3: $4",
-       "logentry-delete-revision": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà 'e {{PLURAL:$5|na verziona|$5 verziune}} ncopp' 'a 'a $3: $4",
-       "logentry-delete-event-legacy": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà 'e l'aziune dint' 'o riggistro ncopp' 'a $3: $4",
-       "logentry-delete-revision-legacy": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà d' 'e verziune ncopp' 'a $3",
+       "logentry-delete-revision": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà 'e {{PLURAL:$5|na verziona|$5 verziune}} ncopp'a $3: $4",
+       "logentry-delete-event-legacy": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà 'e l'aziune int' 'o riggistro ncopp'a $3: $4",
+       "logentry-delete-revision-legacy": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà d'ê verziune ncopp'a $3",
        "logentry-suppress-delete": "$1 {{GENDER:$2|luvaje pe' sempe}} 'a paggena $3",
        "logentry-suppress-event": "$1 {{GENDER:$2|annascunnuto cagnaie|annascunnuta cagnaie}} 'a vesibbiletà 'e {{PLURAL:$5|n'azione d' 'o riggistro|$5 aziune d' 'o riggistro}} ncopp' 'a 'a $3: $4",
        "logentry-suppress-revision": "$1 {{GENDER:$2|annascunnuto cagnaie|annascunnuta cagnaie}} 'a vesibbiletà 'e {{PLURAL:$5|na verziona|$5 verziune}} ncopp' 'a 'a $3: $4",
-       "logentry-suppress-event-legacy": "$1 {{GENDER:$2|annascunnuto cagnaie|annascunnuta cagnaie}} 'a vesibbiletà 'e l'aziune 'e riggistro ncopp' 'a $3",
-       "logentry-suppress-revision-legacy": "$1 {{GENDER:$2|annascunnuto cagnaie|annascunnuta cagnaie}} 'a vesibbiletà d' 'e verziune ncopp' 'a $3",
+       "logentry-suppress-event-legacy": "$1 cagnaie {{GENDER:$2|annascunnuto|annascunnuta}} 'a vesibbiletà 'e l'aziune 'e riggistro ncopp' 'a $3",
+       "logentry-suppress-revision-legacy": "$1 cagnaie {{GENDER:$2|annascunnuto|annascunnuta}} 'a vesibbiletà d' 'e verziune ncopp'a $3",
        "revdelete-content-hid": "cuntenute annascunnute",
        "revdelete-summary-hid": "riepilego 'e cagnamiente annascunnute",
        "revdelete-uname-hid": "nomme utente annascunnuto",
        "log-name-pagelang": "Cagna 'o riggistro d' 'a lengua",
        "log-description-pagelang": "Chest'è nu riggistro 'e cagnamiente 'e lengua d' 'e paggene.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|ave cagnato}} 'a lengua d' 'a paggena $3 'a $4 a $5.",
-       "default-skin-not-found": "Oops! 'A skin predefinta ' 'o wiki vuosto, definita 'n <code dir=\"ltr\">$wgDefaultSkin</code> comme <code>$1</code>, nun se tròva.\n\n'A installazione pare ca tenesse {{PLURAL:$4|'a skin|'e skin}} ccà abbascio. Vedite [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manuale: configurazione skin] pe' n'avè cchiù nfurmaziune ncopp' 'a manera {{PLURAL:$4|'e ll'abbià}} o scegliere chilla predefinita.\n\n$2\n\n; Si avite installato MediaWiki mò mò:\n: Probabbilmente l'avite installato 'a git, o direttamente 'a 'o codece sorgente ausanno cocch'atu metodo. Chesto era permesso. Verite 'e installà cocche skin 'a [https://www.mediawiki.org/wiki/Category:All_skins directory ncoppa mediawiki.org], tramite:\n:* Scarrecanno 'o [https://www.mediawiki.org/wiki/Download programma 'e installazione tarball], ca venesse fornito ch' 'e diverze skin ed estenziune. Putite fare copia-azzecca d' 'a directory <code dir=\"ltr\">skins/</code>.\n:* Scarrecanne 'e tarballs individuale 'e skin 'a [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Ausanno Git pe' scarrecà skin].\n: Facenno accussì nun se mmescasse 'o repository git vuosto si site sviluppatore MediaWiki.\n\n; Si avite MediaWiki agghiurnato MediaWiki mò mò:\n: MediaWiki 1.24 e verziune appriesso nun abbìa automatecamente 'e skin installate (vedite [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manuale: rilevamento automateco skin]). Putite copià {{PLURAL:$5|'a linea|'e linee}} ccà abbascio dint' 'o <code>LocalSettings.php</code> pe' putè appiccià {{PLURAL:$5|'o|tutt' 'e}} {{PLURAL:$5|skin}} installate mò mò:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Si avite cagnato mò mò <code>LocalSettings.php</code>:\n: Cuntrullate 'e nomme d' 'e skin n'ata vota pe' ve sparagnà cocch'errore 'e battitura.",
+       "default-skin-not-found": "Mannàggia! 'A skin predefinta ' 'o wiki vuosto, definita 'n <code dir=\"ltr\">$wgDefaultSkin</code> comme <code>$1</code>, nun se tròva.\n\n'A installazione pare ca tenesse {{PLURAL:$4|'a skin|'e skin}} ccà abbascio. Vedite [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manuale: configurazione skin] pe n'avè cchiù nfurmaziune ncopp' 'a manera {{PLURAL:$4|'e ll'abbià}} o seleziunà chella predefinita.\n\n$2\n\n; Si avite installato MediaWiki mo mo:\n: Probabbilmente l'avite installato 'a git, o direttamente ro codece sorgente ausanno quacch'atu metodo. Ne putiva fà. Verite 'e installà quacche skin 'a [https://www.mediawiki.org/wiki/Category:All_skins directory ncoppa mediawiki.org], tramite:\n:* Scarrecanno 'o [https://www.mediawiki.org/wiki/Download programma 'e installazione tarball], ca venesse dato cu 'e diverze skin e estenziune. Putite fà copia-azzecca d' 'a directory <code dir=\"ltr\">skins/</code>.\n:* Scarrecanne 'e tarballs individuale 'e skin 'a [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Ausanno Git pe' scarrecà skin].\n: Facenno accussì nun se mmescasse 'o repository git vuosto si site sviluppatore MediaWiki.\n\n; Si avite MediaWiki agghiurnato MediaWiki mò mò:\n: MediaWiki 1.24 e verziune appriesso nun abbìa automatecamente 'e skin installate (vedite [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manuale: rilevamento automateco skin]). Putite copià {{PLURAL:$5|'a linea|'e linee}} ccà abbascio dint' 'o <code>LocalSettings.php</code> pe' putè appiccià {{PLURAL:$5|'o|tutt' 'e}} {{PLURAL:$5|skin}} installate mo mmo:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Si avite cagnato mo mo <code>LocalSettings.php</code>:\n: Cuntrullate 'e nomme d' 'e skin n'ata vota pe' ve sparagnà ciert'errure 'e battitura.",
        "default-skin-not-found-no-skins": "oops! 'O skin predefinito p' 'a wiki vuosta, definito int'a <code>$wgDefaultSkin</code> comm'a <code>$1</code>, nun è a disposizione.\n\nVuje nun tenite nisciuno skin installato.\n\n; Si avite installato o agghiurnato MediaWiki mo' mo':\n: È possibbele ca l'avite installato 'a git, o direttamente d' 'o codece sorgente ausanno n'atu metodo. Chesto s'aspettava. Mediawiki 1.24 o cchiù nuova nun include nisciuno skin dint' 'o repositorio prencepale. Tentate 'e installà cocche skin 'a [https://www.mediawiki.org/wiki/Category:All_skins sta cartella 'e mediawiki.org], facenno:\n:* Scarreca 'e [https://www.mediawiki.org/wiki/Download tarball installer], ca venesse cu nu cuofeno 'e skin e estensiune. Vuje putite cupià e azzeccà 'a cartella <code>skins/</code> 'a chiste.\n:* Scarrecanno tarball 'e skin individuale 'a [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Ausanno Git pe' puté scarrecà skin].\n: A ffà chesto nun avesse nteferì c' 'o repositorio d' 'o git vuosto, si vuje site sviluppatore MediaWiki. Vedite [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manuale: Mpustaziona skin] pe' n'avé nfurmaziune ncopp'a comme s'avesser'appiccià skin e scegliere 'o valore predefinito.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (funzione appicciata)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 (<strong>funzione stutata</strong>)",
        "authmanager-authplugin-setpass-denied": "'O plugin autenticazione nun premmettesse 'e cagnà 'e password.",
        "authmanager-authplugin-setpass-bad-domain": "Dominio invalido.",
        "authmanager-autocreate-noperm": "'A criazione automatica 'e ll'utenza nun fosse premmessa.",
-       "authmanager-autocreate-exception": "Criazione 'e cunte automatica mò mò è stutata pe' bbìa 'e ll'errure precedenti.",
+       "authmanager-autocreate-exception": "Criazione 'e cunte automatica stutata pe nu poc'ê tiempo pe vvìa 'e ll'errure precedenti.",
        "authmanager-userdoesnotexist": "'O cunto utente \"$1\" nun è riggistrato.",
        "authmanager-userlogin-remembermypassword-help": "Si 'a pasword adda essere arricurdata cchiù a luongo cu rispett'a tutt' 'a durata d' 'a sessione.",
        "authmanager-username-help": "Nomme utente pe' ll'autenticaziona.",
        "authmanager-provider-password": "Autenticaziona basata ncopp' 'a password",
        "authmanager-provider-password-domain": "Autenticaziona cu' password e basata ncopp'a nu dominio",
        "authmanager-provider-temporarypassword": "Password a tiempo determinato",
-       "authprovider-confirmlink-message": "Verenno 'e tentative d'acciesso mò, l'utente ccà putessero avé nu cullegamento c' 'o cunto wiki d' 'o vuosto. A ffà cullegamento premmettesse appiccià 'o sistema 'e trasuta pe' bbìa 'e sti cunte. Pe' piacere sciglite 'e cunte addò vulite fà cullegamento.",
+       "authprovider-confirmlink-message": "Verenno 'e tentative d'acciesso, chisti cunte ccà putessero avé nu cullegamento c' 'o cunto wiki d' 'o vuosto. Jontanneli premmettesse appiccià 'o sistema 'e trasuta cu sti cunte. Pe piacere sciglite 'e cunte ca vulite jontà.",
        "authprovider-confirmlink-request-label": "Cunte ca s'avesser'a cullegà",
        "authprovider-confirmlink-success-line": "$1: cullegato e apposto.",
        "authprovider-confirmlink-failed": "'O cullegamento 'e ll'utenza nun è ngarrato sano sano: $1",
index 8cb49f4..8b306c4 100644 (file)
        "botpasswords-existing": "Eksisterende robotpassord",
        "botpasswords-createnew": "Opprett et nytt robotpassord",
        "botpasswords-editexisting": "Redigere et eksisterende robotpassord",
+       "botpasswords-label-needsreset": "(passordet må settes på nytt)",
        "botpasswords-label-appid": "Robotnavn:",
        "botpasswords-label-create": "Opprett",
        "botpasswords-label-update": "Oppdater",
        "botpasswords-restriction-failed": "Begrensninger for robotpassord tillater ikke denne innloggingen.",
        "botpasswords-invalid-name": "Det angitte brukernavnet inneholder ikke separasjonstegnet for robotpassord (\"$1\").",
        "botpasswords-not-exist": "Brukeren \"$1\" har ikke noe robotpassord for \"$2\".",
+       "botpasswords-needs-reset": "Botpassordet for botnavnet «$2» for {{GENDER:$1|brukeren}} «$1» må settes på nytt.",
        "resetpass_forbidden": "Passord kan ikke endres",
        "resetpass_forbidden-reason": "Passordene kan ikke endres: $1",
        "resetpass-no-info": "Du må være logget inn for å gå til denne siden direkte",
        "protectedtitles-submit": "Vis titler",
        "listusers": "Brukerliste",
        "listusers-editsonly": "Vis bare brukere med redigeringer",
+       "listusers-temporarygroupsonly": "Vis kun brukere i midlertidige brukergrupper",
        "listusers-creationsort": "Sorter etter opprettelsesdato",
        "listusers-desc": "Sorter i synkende rekkefølge",
        "usereditcount": "{{PLURAL:$1|én redigering|$1 redigeringer}}",
        "whatlinkshere": "Lenker hit",
        "whatlinkshere-title": "Sider som lenker til «$1»",
        "whatlinkshere-page": "Side:",
-       "linkshere": "Følgende sider lenker til '''[[:$1]]''':",
-       "nolinkshere": "Ingen sider lenker til '''[[:$1]]'''.",
-       "nolinkshere-ns": "Ingen sider lenker til '''[[:$1]]''' i valgte navnerom.",
+       "linkshere-2": "Følgende sider lenker til '''$1''':",
+       "nolinkshere-2": "Ingen sider lenker til '''$1'''.",
+       "nolinkshere-ns-2": "Ingen sider lenker til '''$1''' i valgte navnerom.",
        "isredirect": "omdirigeringsside",
        "istemplate": "transklusjon",
        "isimage": "fillenke",
        "authmanager-password-help": "Passord for autentisering.",
        "authmanager-domain-help": "Domene for ekstern autentisering.",
        "authmanager-retype-help": "Passord igjen for å bekrefte.",
-       "authmanager-email-label": "Epost",
+       "authmanager-email-label": "E-post",
        "authmanager-email-help": "Epostadresse",
        "authmanager-realname-label": "Virkelig navn",
        "authmanager-realname-help": "Brukerens virkelige navn",
        "pagedata-title": "Sidedata",
        "pagedata-text": "Denne siden gir et datagrensesnitt til sidene. Oppgi en sidetittel i URL-en, med undersidesyntaks.\n* Innholdsforhandlingen er basert på din klients Accept-header. Dette betyr at data for siden blir angitt på formatet som foretrekkes av din klient.",
        "pagedata-not-acceptable": "Ingen passende format funnet. Støttede MIME-typer: $1",
-       "pagedata-bad-title": "Ugyldig tittel: $1."
+       "pagedata-bad-title": "Ugyldig tittel: $1.",
+       "passwordpolicies-group": "Gruppe",
+       "passwordpolicies-policy-minimalpasswordlength": "Passordet må være på minst $1 {{PLURAL:$1|tegn}}.",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Passordet må være på minst $1 {{PLURAL:$1|tegn}} for å kunne logge inn",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Passordet kan ikke være det samme som brukernavnet",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Passordet kan ikke matche spesifikt svartelistede passord",
+       "passwordpolicies-policy-maximalpasswordlength": "Passordet må være på minst $1 {{PLURAL:$1|tegn}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "Passordet kan ikke være {{PLURAL:$1|det populære passordet|i lista over $1 populære passord}}"
 }
index c023aac..944031d 100644 (file)
        "rc-enhanced-hide": "Details verbargen",
        "rc-old-title": "oorspronkelik an-emaakt as \"$1\"",
        "recentchangeslinked": "Soortgelyke wysigingen",
-       "recentchangeslinked-feed": "Volg verwiezigingen",
-       "recentchangeslinked-toolbox": "Volg verwiezigingen",
+       "recentchangeslinked-feed": "Volg verwysingen",
+       "recentchangeslinked-toolbox": "Volg verwysingen",
        "recentchangeslinked-title": "Wiezigingen verwaant an $1",
        "recentchangeslinked-summary": "Op disse spesiale zied steet n lieste mit de leste wieziginen op ziejen waornaor verwezen wördt. Ziejen op [[Special:Watchlist|joew volglieste]] staon '''vet'''.",
        "recentchangeslinked-page": "Ziednaam:",
        "whatlinkshere": "Verwysingen hyrhinne",
        "whatlinkshere-title": "Ziejen die verwiezen naor \"$1\"",
        "whatlinkshere-page": "Zied:",
-       "linkshere": "Disse ziejen verwiezen naor '''[[:$1]]''':",
-       "nolinkshere": "Gien enkele zied verwis naor '''[[:$1]]'''.",
-       "nolinkshere-ns": "Gien enkele zied verwis naor '''[[:$1]]''' in de ekeuzen naamruumte.",
+       "linkshere-2": "Disse ziejen verwiezen naor '''$1''':",
+       "nolinkshere-2": "Gien enkele zied verwis naor '''$1'''.",
+       "nolinkshere-ns-2": "Gien enkele zied verwis naor '''$1''' in de ekeuzen naamruumte.",
        "isredirect": "deurverwiezing",
        "istemplate": "in-evoegd as mal",
        "isimage": "bestaandsverwiezing",
        "confirm-purge-title": "Herny disse syde",
        "confirm_purge_button": "Bevestig",
        "confirm-purge-top": "Klik up 'bevestig' üm et tüskengehöägen van disse syde te leagen.",
-       "confirm-purge-bottom": "Et leagmaken van et tüskengehöägen sörgt dervöär dat jy de lätste versy van een syde te syn krygen.",
+       "confirm-purge-bottom": "Et leagmaken van et tüskengehöägen sörgt dervöär dat jy de lätste versy van een syde te seen krygen.",
        "confirm-watch-button": "Oké",
        "confirm-watch-top": "Disse zied op joew volglieste zetten?",
        "confirm-unwatch-button": "Oké",
        "fileduplicatesearch-noresults": "Der is gien bestaand mit de naam \"$1\" evunnen.",
        "specialpages": "Speciale syden",
        "specialpages-note-top": "Legenda",
+       "specialpages-note-restricted": "* Normale spesiale ziejen.\n* <span class=\"mw-specialpagerestricted\">Beparkt toegankelike spesiale ziejen.</span>",
        "specialpages-group-maintenance": "Onderhoudsliesten",
        "specialpages-group-other": "Aandere spesiale ziejen",
        "specialpages-group-login": "Anmelden / inschrieven",
index 27d9101..b5b6faa 100644 (file)
        "whatlinkshere": "Wat wiest na disse Siet hen",
        "whatlinkshere-title": "Sieden, de na „$1“ wiest",
        "whatlinkshere-page": "Siet:",
-       "linkshere": "Disse Sieden wiest na '''„[[:$1]]“''':",
-       "nolinkshere": "Kene Siet wiest na '''„[[:$1]]“'''.",
-       "nolinkshere-ns": "Kene Sieden wiest na '''[[:$1]]''' in’n utwählten Naamruum.",
+       "linkshere-2": "Disse Sieden wiest na '''„$1“''':",
+       "nolinkshere-2": "Kene Siet wiest na '''„$1“'''.",
+       "nolinkshere-ns-2": "Kene Sieden wiest na '''$1''' in’n utwählten Naamruum.",
        "isredirect": "Wiederleiden",
        "istemplate": "inbunnen dör Vörlaag",
        "isimage": "Dateilenk",
        "fileduplicatesearch-result-1": "To de Datei „$1“ gifft dat keen Datei, de jüst gliek is.",
        "fileduplicatesearch-result-n": "To de Datei „$1“ gifft dat {{PLURAL:$2|ene Datei, de jüst gliek is|$2 Datein, de jüst gliek sünd}}.",
        "specialpages": "Sünnerliche Sieden",
+       "specialpages-note-restricted": "* Normale Spezialsieden\n* <strong class=\"mw-specialpagerestricted\">Spezialsieden för Brukers mit mehr Rechten</strong>",
        "specialpages-group-maintenance": "Pleeglisten",
        "specialpages-group-other": "Annere Spezialsieden",
        "specialpages-group-login": "Anmellen",
index 914c8f9..1e22e2a 100644 (file)
        "whatlinkshere": "यहाँ के जोडिन्छ",
        "whatlinkshere-title": "$1 सँग जोडिएका पानाहरू",
        "whatlinkshere-page": "पृष्ठ:",
-       "linkshere": "निम्न पृष्ठहरू '''[[:$1]]''' मा जोडिन्छ :",
-       "nolinkshere": " '''[[:$1]]'''मा लिंक भएका कुनै पृष्ठहरू छैनन्",
-       "nolinkshere-ns": "चुनिएको नामस्थानमा '''[[:$1]]''' सित जोडिने पृष्ठहरू छैनन्।",
+       "linkshere-2": "निम्न पृष्ठहरू '''$1''' मा जोडिन्छ :",
+       "nolinkshere-2": " '''$1'''मा लिंक भएका कुनै पृष्ठहरू छैनन्",
+       "nolinkshere-ns-2": "चुनिएको नामस्थानमा '''$1''' सित जोडिने पृष्ठहरू छैनन्।",
        "isredirect": "अनुप्रेषित पृष्ठ",
        "istemplate": "पारदर्शिता",
        "isimage": "फाइल लिङ्क",
        "fileduplicatesearch-noresults": "\"$1\" नामको फाइल पाइएन।",
        "specialpages": "विशेष पृष्ठ",
        "specialpages-note-top": "आदर्श वाक्य",
+       "specialpages-note-restricted": "* साधारण विशेष पृष्ठहरू।\n* <span class=\"mw-specialpagerestricted\">निषेधित विशेष पृष्ठहरू।</span>",
        "specialpages-group-maintenance": "मर्मत प्रतिवेदनहरू",
        "specialpages-group-other": "अरू विशेष पृष्ठहरू",
        "specialpages-group-login": "प्रवेश गर्ने / नयाँ खाता बनाउने",
index 656ef4f..f295c76 100644 (file)
        "tog-enotifminoredits": "Mij e-mailen bij kleine bewerkingen van pagina’s en bestanden op mijn volglijst",
        "tog-enotifrevealaddr": "Mijn e-mailadres weergeven in e-mailberichten",
        "tog-shownumberswatching": "Het aantal gebruikers weergeven dat deze pagina volgt",
-       "tog-oldsig": "Uw bestaande ondertekening:",
+       "tog-oldsig": "Uw bestaande handtekening:",
        "tog-fancysig": "Handtekening als wikitekst behandelen (zonder automatische koppeling)",
        "tog-uselivepreview": "Voorvertoning weergeven zonder de pagina opnieuw te laden",
        "tog-forceeditsummary": "Een melding geven bij een lege bewerkingssamenvatting",
        "botpasswords-existing": "Bestaande botwachtwoorden",
        "botpasswords-createnew": "Een nieuw botwachtwoord aanmaken",
        "botpasswords-editexisting": "Een bestaand botwachtwoord bewerken",
+       "botpasswords-label-needsreset": "(wachtwoord moet opnieuw worden ingesteld)",
        "botpasswords-label-appid": "Naam van bot:",
        "botpasswords-label-create": "Aanmaken",
        "botpasswords-label-update": "Bijwerken",
        "botpasswords-restriction-failed": "Botwachtwoordbeperkingen maken het aanmelden onmogelijk.",
        "botpasswords-invalid-name": "De gebruikersnaam bevat niet het scheidingsteken van het botwachtwoord (\"$1\").",
        "botpasswords-not-exist": "Gebruiker \"$1\" heeft geen botwachtwoord genaamd \"$2\"",
+       "botpasswords-needs-reset": "Het botwachtwoord voor botnaam \"$2\" van {{GENDER:$1|gebruiker}} \"$1\" moet opnieuw worden ingesteld.",
        "resetpass_forbidden": "Wachtwoorden kunnen niet gewijzigd worden",
        "resetpass_forbidden-reason": "Wachtwoorden kunnen niet gewijzigd worden: $1",
        "resetpass-no-info": "U dient aangemeld zijn voordat u deze pagina kunt gebruiken.",
        "subject-preview": "Voorvertoning van het onderwerp:",
        "previewerrortext": "Er is een fout opgetreden tijdens het weergeven van uw wijzigingen.",
        "blockedtitle": "Gebruiker is geblokkeerd",
-       "blockedtext": "'''Uw gebruikersaccount of IP-adres is geblokkeerd.'''\n\nDe blokkade is uitgevoerd door $1.\nDe opgegeven reden is ''$2''.\n\n* Aanvang blokkade: $8\n* Einde blokkade: $6\n* Bedoeld te blokkeren: $7\n\nU kunt contact opnemen met $1 of een andere [[{{MediaWiki:Grouppage-sysop}}|beheerder]] om de blokkade te bespreken.\nU kunt geen gebruik maken van de functie \"Deze gebruiker e-mailen\", tenzij u een geldig e-mailadres hebt opgegeven in uw [[Special:Preferences|voorkeuren]] en het gebruik van deze functie niet geblokkeerd is.\nUw huidige IP-adres is $3 en het blokkadenummer is #$5.\nVermeld alle bovenstaande gegevens als u ergens op deze blokkade reageert.",
-       "autoblockedtext": "Uw IP-adres is automatisch geblokkeerd, omdat het gebruikt is door een andere gebruiker, die geblokkeerd is door $1.\nDe opgegeven reden is:\n\n:''$2''\n\n* Aanvang blokkade: $8\n* Einde blokkade: $6\n* Bedoeld te blokkeren: $7\n\nU kunt contact opnemen met $1 of een andere [[{{MediaWiki:Grouppage-sysop}}|beheerder]] om de blokkade te bespreken.\n\nU kunt geen gebruik maken van de functie \"Deze gebruiker e-mailen\", tenzij u een geldig e-mailadres hebt opgegeven in uw [[Special:Preferences|voorkeuren]], en het gebruik van deze functie niet is geblokkeerd.\n\nUw huidige IP-adres is $3 en het blokkadenummer is #$5.\nVermeld alle bovenstaande gegevens als u ergens op deze blokkade reageert.",
+       "blockedtext": "'''Uw gebruikersaccount of IP-adres is geblokkeerd.'''\n\nDe blokkade is uitgevoerd door $1.\nDe opgegeven reden is ''$2''.\n\n* Aanvang blokkade: $8\n* Einde blokkade: $6\n* Bedoeld te blokkeren: $7\n\nU kunt contact opnemen met $1 of een andere [[{{MediaWiki:Grouppage-sysop}}|beheerder]] om de blokkade te bespreken.\nU kunt geen gebruik maken van de functie \"{{int:emailuser}}\", tenzij u een geldig e-mailadres hebt opgegeven in uw [[Special:Preferences|voorkeuren]] en het gebruik van deze functie niet geblokkeerd is.\nUw huidige IP-adres is $3 en het blokkadenummer is #$5.\nVermeld alle bovenstaande gegevens als u ergens op deze blokkade reageert.",
+       "autoblockedtext": "Uw IP-adres is automatisch geblokkeerd, omdat het gebruikt is door een andere gebruiker, die geblokkeerd is door $1.\nDe opgegeven reden is:\n\n:''$2''\n\n* Aanvang blokkade: $8\n* Einde blokkade: $6\n* Bedoeld te blokkeren: $7\n\nU kunt contact opnemen met $1 of een andere [[{{MediaWiki:Grouppage-sysop}}|beheerder]] om de blokkade te bespreken.\n\nU kunt geen gebruik maken van de functie \"{{int:emailuser}}\", tenzij u een geldig e-mailadres hebt opgegeven in uw [[Special:Preferences|voorkeuren]], en het gebruik van deze functie niet is geblokkeerd.\n\nUw huidige IP-adres is $3 en het blokkadenummer is #$5.\nVermeld alle bovenstaande gegevens als u ergens op deze blokkade reageert.",
        "systemblockedtext": "Uw gebruikersaccount of IP-adres is automatisch geblokkeerd door MediaWiki.\nDe opgegeven reden is:\n\n:<em>$2</em>\n\n* Aanvang blokkade: $8\n* Einde blokkade: $6\n* Bedoeld te blokkeren: $7\n\nUw huidige IP-adres is $3.\nVermeld alle bovenstaande gegevens als u ergens op deze blokkade reageert.",
        "blockednoreason": "geen reden opgegeven",
        "whitelistedittext": "U moet $1 om pagina's te bewerken.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Niet gecontroleerd",
        "rcfilters-filter-reviewstatus-manual-description": "Bewerkingen die handmatig zijn gecontroleerd",
        "rcfilters-filter-reviewstatus-manual-label": "Handmatig gecontroleerd",
-       "rcfilters-filter-reviewstatus-auto-description": "Bewerkingen door geavanceerde gebruikers wiens werk automatisch gecontroleerd is.",
+       "rcfilters-filter-reviewstatus-auto-description": "Bewerkingen door geavanceerde gebruikers wier werk automatisch gecontroleerd wordt.",
        "rcfilters-filter-reviewstatus-auto-label": "Automatisch gecontroleerd",
        "rcfilters-filtergroup-significance": "Belangrijkheid",
        "rcfilters-filter-minor-label": "Kleine bewerkingen",
        "protectedtitles-submit": "Paginanamen weergeven",
        "listusers": "Gebruikerslijst",
        "listusers-editsonly": "Alleen gebruikers met bewerkingen weergeven",
+       "listusers-temporarygroupsonly": "Toon alleen gebruikers in tijdelijke gebruikersgroepen",
        "listusers-creationsort": "Sorteren op registratiedatum",
        "listusers-desc": "Sorteren in aflopende volgorde",
        "usereditcount": "$1 {{PLURAL:$1|bewerking|bewerkingen}}",
        "whatlinkshere": "Verwijzingen naar deze pagina",
        "whatlinkshere-title": "Pagina's die verwijzen naar \"$1\"",
        "whatlinkshere-page": "Pagina:",
-       "linkshere": "De volgende pagina's verwijzen naar '''[[:$1]]''':",
-       "nolinkshere": "Geen enkele pagina verwijst naar '''[[:$1]]'''.",
-       "nolinkshere-ns": "Geen enkele pagina in de gekozen naamruimte verwijst naar '''[[:$1]]'''.",
+       "linkshere-2": "De volgende pagina's verwijzen naar '''$1''':",
+       "nolinkshere-2": "Geen enkele pagina verwijst naar '''$1'''.",
+       "nolinkshere-ns-2": "Geen enkele pagina in de gekozen naamruimte verwijst naar '''$1'''.",
        "isredirect": "doorverwijspagina",
        "istemplate": "ingevoegd als sjabloon",
        "isimage": "bestandskoppeling",
        "thumbnail_dest_directory": "Niet in staat doelmap aan te maken",
        "thumbnail_image-type": "Dit bestandstype wordt niet ondersteund",
        "thumbnail_gd-library": "De instellingen voor de GD-bibliotheek zijn incompleet. De functie $1 ontbreekt",
-       "thumbnail_image-size-zero": "De afbeeldingsbestandsgrootte lijkt nul te zijn.",
+       "thumbnail_image-size-zero": "De grootte van het afbeeldingsbestand lijkt nul te zijn.",
        "thumbnail_image-missing": "Het bestand lijkt niet aanwezig te zijn: $1",
        "thumbnail_image-failure-limit": "Het maken van een miniatuurafbeelding is te vaak mislukt ($1 keer of vaker). Probeer het later nog eens.",
        "import": "Pagina's importeren",
        "pagedata-title": "Paginagegevens",
        "pagedata-text": "Deze pagina biedt een data-interface voor pagina's. Geef een paginatitel op door deze in de URL op te nemen, op de manier van een deelpagina.\n* De inhoud wordt afgestemd op de door de client meegestuurde Accept Header. Dit betekent dat de gegevens voor de pagina worden aangeboden in het voorkeursformaat van uw client.",
        "pagedata-not-acceptable": "Er is geen overeenkomende indeling gevonden. Ondersteunde MIME-typen: $1",
-       "pagedata-bad-title": "Ongeldige titel: $1."
+       "pagedata-bad-title": "Ongeldige titel: $1.",
+       "unregistered-user-config": "Om veiligheidsredenen worden gebruikersdeelpagina's met JavaScript, CSS en JSON niet geladen voor gebruikers die niet zijn geregistreerd.",
+       "passwordpolicies": "Wachtwoordbeleid",
+       "passwordpolicies-summary": "Dit is een lijst met de wachtwoordbeleidvormen die van toepassing zijn op de gebruikersgroepen van deze wiki.",
+       "passwordpolicies-group": "Groep",
+       "passwordpolicies-policies": "Beleid",
+       "passwordpolicies-policy-minimalpasswordlength": "Wachtwoord moet ten minste {{PLURAL:$1|$1 teken|$1 tekens}} bevatten",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Wachtwoord moet ten minste {{PLURAL:$1|$1 teken|$1 tekens}} bevatten om te mogen aanmelden",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Wachtwoord mag niet hetzelfde zijn als de gebruikersnaam",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Wachtwoord mag niet overeenkomen met wachtwoorden op de zwarte lijst",
+       "passwordpolicies-policy-maximalpasswordlength": "Wachtwoord moet minder dan $1 {{PLURAL:$1|teken|tekens}} bevatten",
+       "passwordpolicies-policy-passwordcannotbepopular": "Watchwoord mag niet {{PLURAL:$1|overeenkomen met het bekende wachtwoord|voorkomen in de lijst met $1 bekende wachtwoorden}}"
 }
index fcd18d5..c9862b6 100644 (file)
        "rcfilters-quickfilters-placeholder-description": "For å lagra filterinnstillingane dine og bruka dei på nytt seinare, klikk på bokmerkeikonet i området for aktive filter under.",
        "rcfilters-savedqueries-defaultlabel": "Lagra filter",
        "rcfilters-savedqueries-rename": "Gje nytt namn",
+       "rcfilters-savedqueries-setdefault": "Set som standard",
        "rcfilters-savedqueries-new-name-label": "Namn",
        "rcfilters-savedqueries-new-name-placeholder": "Skildra føremålet med filteret",
        "rcfilters-savedqueries-apply-label": "Lagra innstillingar",
+       "rcfilters-savedqueries-apply-and-setdefault-label": "Opprett standardfilter",
        "rcfilters-savedqueries-add-new-title": "Lagra gjeldande filterinnstillingar",
+       "rcfilters-savedqueries-already-saved": "Desse filtera er alt lagra. Endra innstillingane dine for å oppretta eit nytt lagra filter.",
        "rcfilters-clear-all-filters": "Fjern alle filter",
        "rcfilters-show-new-changes": "Sjå dei nyaste endringane",
        "rcfilters-search-placeholder": "Filtrer endringar (nytt meny eller søk etter filternamn)",
        "rcfilters-invalid-filter": "Ugyldig filter",
        "rcfilters-empty-filter": "Ingen aktive filter. Alle bidrag er viste.",
        "rcfilters-filterlist-title": "Filter",
+       "rcfilters-filterlist-whatsthis": "Korleis verkar desse?",
        "rcfilters-filterlist-feedbacklink": "Gje attendemelding på dei nye (beta)filtera",
        "rcfilters-highlightbutton-title": "Uthev resultat",
        "rcfilters-highlightmenu-title": "Vel ein farge",
        "whatlinkshere": "Lenkjer hit",
        "whatlinkshere-title": "Sider som har lenkje til «$1»",
        "whatlinkshere-page": "Side:",
-       "linkshere": "Desse sidene har lenkjer til '''[[:$1]]''':",
-       "nolinkshere": "Ingen sider har lenkjer til '''[[:$1]]'''.",
-       "nolinkshere-ns": "Ingen sider har lenkje til '''[[:$1]]''' i det valde namnerommet.",
+       "linkshere-2": "Desse sidene har lenkjer til '''$1''':",
+       "nolinkshere-2": "Ingen sider har lenkjer til '''$1'''.",
+       "nolinkshere-ns-2": "Ingen sider har lenkje til '''$1''' i det valde namnerommet.",
        "isredirect": "omdirigeringsside",
        "istemplate": "inkludert som mal",
        "isimage": "fillenkje",
        "fileduplicatesearch-noresults": "Fann inga fil med namnet «$1».",
        "specialpages": "Spesialsider",
        "specialpages-note-top": "Tyding",
+       "specialpages-note-restricted": "* Vanlege spesialsider.\n* <span class=\"mw-specialpagerestricted\">Spesialsider med avgrensa tilgang.</span>",
        "specialpages-group-maintenance": "Vedlikehaldsrapportar",
        "specialpages-group-other": "Andre spesialsider",
        "specialpages-group-login": "Logga inn / oppretta brukarkonto",
index a2a5427..702f91e 100644 (file)
        "whatlinkshere": "Ke eng yeo e hlomaganyago mo",
        "whatlinkshere-title": "Matlakala a go hlomaganya go \"$1\"",
        "whatlinkshere-page": "Letlakala:",
-       "linkshere": "Matlaka a latelago a hlomaganya le '''[[:$1]]''':",
-       "nolinkshere": "Ga go letlakala leo le hlomaganyago go '''[[:$1]]'''.",
+       "linkshere-2": "Matlaka a latelago a hlomaganya le '''$1''':",
+       "nolinkshere-2": "Ga go letlakala leo le hlomaganyago go '''$1'''.",
        "isredirect": "''redirect'' letlakala",
        "istemplate": "tsentšho",
        "isimage": "Hlomaganyo ya Faele",
index a575d20..239d754 100644 (file)
        "whatlinkshere": "natj beda nitja",
        "whatlinkshere-title": "Bibol beda $1",
        "whatlinkshere-page": "Bibol:",
-       "linkshere": "Ngawaliny bibol beda-ang <strong>[[:$1]]</strong>",
-       "nolinkshere": "Uart bibol beda <strong>[[:$1]]</strong>.",
+       "linkshere-2": "Ngawaliny bibol beda-ang <strong>$1</strong>",
+       "nolinkshere-2": "Uart bibol beda <strong>$1</strong>.",
        "isredirect": "Dtallangiritch bibol",
        "istemplate": "transclusion",
        "isimage": "file beda",
index f11e4fd..aa2f766 100644 (file)
        "content-model-css": "CSS",
        "content-json-empty-object": "Objècte void",
        "content-json-empty-array": "Tablèu void",
+       "deprecated-self-close-category": "Paginas qu'utilizan d'etiquetas HTML autotampadas pas validas",
+       "deprecated-self-close-category-desc": "La pagina conten d'etiquetas HTML autotampadas pas validas, coma <code>&lt;b/></code> o <code>&lt;span/></code>. Lo comportament d'aquò cambiarà lèu per respectar l'especificacion HTML5, adonc lor emplec en wikitext es despreciat.",
+       "duplicate-args-warning": "<strong>Attention:</strong> [[:$1]] crida [[:$2]] amb mai d'una valor pel paramètre \"$3\". S'emplegarà solament  la darrièra valor provesida.",
        "duplicate-args-category": "Paginas utilizant d'arguments duplicats dins los apèls de modèl",
+       "duplicate-args-category-desc": "La pagina conten de cridas a patrons qu'emplagan d'arguments duplicats, coma  <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> or <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "expensive-parserfunction-warning": "Atencion : Aquesta pagina conten tròp d’apèls dispendioses de foncions del parser.\n\nI deurià aver mens de {{PLURAL:$2|ampèl|ampèls}}, e actualament {{PLURAL:$1|i a $1 ampèl|i a $1 ampèls}}..",
        "expensive-parserfunction-category": "Paginas amb tròp d’apèls dispendioses de foncions parsaires",
        "post-expand-template-inclusion-warning": "Atencion : Aquesta pagina conten tròp d'inclusions de modèls.\nD'unas inclusions seràn pas efectuadas.",
        "post-expand-template-argument-warning": "Atencion : Aquesta pagina conten al mens un paramètre de modèl que l'inclusion es renduda impossibla. Aprèp extension, aqueste auriá produit un resultat tròp long, doncas, es pas estat inclús.",
        "post-expand-template-argument-category": "Paginas que contenon al mens un paramètre de modèl pas evaluat",
        "parser-template-loop-warning": "Modèl en bocla detectat : [[$1]]",
+       "template-loop-category": "Paginas amb boclas de patron",
+       "template-loop-category-desc": "La pagina conten una bocla dins lo patron, es a dire, un patron que se sona el meteis recursivament.",
+       "template-loop-warning": "<strong>Attencion:</strong> Aquesta pagina sona [[:$1]. Aquò es l'encausa d'una bocla de patron (una sonada infinida resursiva).",
        "parser-template-recursion-depth-warning": "Limit de longor de la recursion del modèl depassat ($1)",
        "language-converter-depth-warning": "Limit de prigondor del convertissor de lenga depassada ($1)",
        "node-count-exceeded-category": "Paginas ont nombre de nosèls es depassat",
        "prefs-watchlist-edits": "Nombre maximal de modificacions d'afichar dins la lista de seguiment :",
        "prefs-watchlist-edits-max": "Nombre maximum : 1000",
        "prefs-watchlist-token": "Geton per la lista de seguiment :",
+       "prefs-watchlist-managetokens": "Administrar los getons",
        "prefs-misc": "Preferéncias divèrsas",
        "prefs-resetpass": "Modificar lo senhal",
        "prefs-changeemail": "Cambiar o suprimir l'adreça electronica",
        "recentchangescount": "Nombre de modificacions d'afichar per defauta dins los cambiaments recents, los istorics e los logs :",
        "prefs-help-recentchangescount": "Nombre maximum : 1000",
        "prefs-help-watchlist-token2": "Aquí la clau secreta del flux Web de vòstra lista de seguiment.\nTota persona que la coneis poirà legir vòstra lista de seguiment, doncas, la comuniquetz pas.\nSe necessari, [[Special:ResetTokens|clicatz aicí per la reïnicializar]].",
+       "prefs-help-tokenmanagement": "Podètz veire e tornar inicializar la clau secreta del vòstre compte que pòt accedir al flux Web de la vòstre lista de seguit. Tota persona que coneis la clau poirà legir la vòstra lista, alara la compartissètz pas",
        "savedprefs": "Las preferéncias son estadas salvadas.",
        "savedrights": "Los dreits d'utilizaire de {{GENDER:$1|$1}} son estats enregistrats.",
        "timezonelegend": "Fus orari :",
        "timezoneregion-pacific": "Ocean Pacific",
        "allowemail": "Autorizar los autres utilizaires a me mandar de corrièls",
        "email-allow-new-users-label": "Autorizar corrièr electronic d'utilizaires nòus",
+       "email-blacklist-label": "Enebís a aqueles usatgièrs de m'enviar de corrièrs electronics:",
        "prefs-searchoptions": "Recèrca",
        "prefs-namespaces": "Noms d’espacis",
        "default": "defaut",
        "prefs-dateformat": "Format de las datas",
        "prefs-timeoffset": "Descalatge orari",
        "prefs-advancedediting": "Opcions generalas",
+       "prefs-developertools": "Aisinas del desvolopaire",
        "prefs-editor": "Editor",
        "prefs-preview": "Apercebut",
        "prefs-advancedrc": "Opcions avançadas",
+       "prefs-opt-out": "Refusar los melhoraments",
        "prefs-advancedrendering": "Opcions avançadas",
        "prefs-advancedsearchoptions": "Opcions avançadas",
        "prefs-advancedwatchlist": "Opcions avançadas",
        "prefs-tokenwatchlist": "Geton",
        "prefs-diffs": "Diferéncias",
        "prefs-help-prefershttps": "Aquesta preferéncia serà efectiva al moment de vòstra connexion que ven.",
+       "prefswarning-warning": "Avètz fach de cambiaments de las vòstras preferéncias que  son  pas encara efectuats.\nS'abandonatz la pagina sens clicar sus «$1», las preferéncias seràn pas mesas a jorn.",
        "prefs-tabs-navigation-hint": "Astúcia : Podètz utilizar las sagetas d'esquèrra e de dreita per navigar entre los onglets.",
        "userrights": "Dreits dels utilizaires",
        "userrights-lookup-user": "Seleccionar un utilizaire",
        "userrights-user-editname": "Entrar un nom d’utilizaire :",
        "editusergroup": "Cargar de gropes d’utilizaires",
        "editinguser": "Modificacion dels dreits de l’{{GENDER:$1|utilizaire|utilizaira}} <strong>[[User:$1|$1]]</strong> $2",
+       "viewinguserrights": "Afichatge dels dreches de {{GENDER:$1|user}} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "Modificar los gropes de l'utilizai{{GENDER:$1|e|a}}",
        "userrights-viewusergroup": "Afichar los gropes de l'utilizair{{GENDER:$1|e|a}}",
        "saveusergroups": "Enregistrar los gropes de l’{{GENDER:$1|utilizaire|utilizaira}}",
        "userrights-expiry-existing": "Data d'expiracion existenta : $2 à $3",
        "userrights-expiry-othertime": "Autre temps :",
        "userrights-expiry-options": "1 jorn:1 day,1 setmana:1 week,1 mes:1 month,3 meses:3 months,6 meses:6 months,1 an:1 year",
+       "userrights-invalid-expiry": "La data d'expiracion pel grop \"$1\" es pas valida.",
+       "userrights-expiry-in-past": "Lo temps d'expiracion pel grop  \"$1\" es trespassat.",
+       "userrights-cannot-shorten-expiry": "Podètz pas acorchar la durada d'expiracion dels membres del grop \"$1\".Sonque los usatgièrs amb de permissions per apondre e levar aqueste grop o pòdon far.",
        "userrights-conflict": "Conflicte de modificacion de dreits d'utilizaire ! Relegissètz e confirmatz vòstras modificacions.",
        "group": "Grop :",
        "group-user": "Utilizaires",
        "right-createpage": "Crear de paginas (que son pas de paginas de discussion)",
        "right-createtalk": "Crear de paginas de discussion",
        "right-createaccount": "Crear de comptes d'utilizaire novèls",
+       "right-autocreateaccount": "Comença una session automaticament amb un compte d'usatgièr extèrne",
        "right-minoredit": "Marcar de cambiaments coma menors",
        "right-move": "Renomenar de paginas",
        "right-move-subpages": "Desplaçar de paginas amb lor sospaginas",
        "right-siteadmin": "Verrolhar e desverrolhar la basa de donadas",
        "right-override-export-depth": "Exportar las paginas en incluent las paginas ligadas fins a una prigondor de 5 nivèls",
        "right-sendemail": "Mandar un corrièl als autres utilizaires",
+       "right-managechangetags": "Crear, activar e desactivar [[Special:Tags|tags]]",
        "right-applychangetags": "Aplicar [[Special:Tags|las balisas]] amb sas pròprias modificacions",
+       "right-changetags": "Apondre e suprimir arbitràriament [[Special:Tags|tags]] sus de revisions individualas e d'intradas de jornal",
+       "right-deletechangetags": "Suprimir [[Special:Tags|tags]] dempuèi la basa de donadas",
        "grant-generic": "ensemble de dreits « $1 »",
        "grant-group-page-interaction": "Interagir amb de paginas",
        "grant-group-file-interaction": "Interagir amb de mèdias",
        "grant-group-watchlist-interaction": "Interagir amb vòstra lista de seguiment",
        "grant-group-email": "Mandar un corrièr electronic",
+       "grant-group-high-volume": "Realizar una activitat de volum naut",
        "grant-group-customization": "Personalizacion e preferéncias",
        "grant-group-administration": "Efectuar d'accions administrativas",
        "grant-group-private-information": "Accedir a vòstras donadas privadas",
        "grant-blockusers": "Blocar e desblocar d'utilizaires",
        "grant-createaccount": "Crear de comptes",
        "grant-createeditmovepage": "Crear, modificar e desplaçar de paginas",
+       "grant-delete": "Suprimir paginas, revisions e dintradas de jornal",
        "grant-editinterface": "Modificar l'espaci de noms de MediaWiki e lo CSS/JSON/Javascript",
        "grant-editmycssjs": "Modificar vòstre CSS/JSON/JavaScript utilizator",
        "grant-editmyoptions": "Modificar vòstras preferéncias d'utilizaire",
+       "grant-editmywatchlist": "Modificar la vòstra lista de seguiment",
        "grant-editpage": "Modificar de paginas existentas",
        "grant-editprotected": "Modificar de paginas protegidas",
+       "grant-highvolume": "Modificacion de volum naut",
+       "grant-oversight": "Amagar los usatgièrs e suprimir las revisions",
        "grant-patrol": "Verificar las modificacions de paginas",
        "grant-privateinfo": "Accedir a las informacions privadas",
+       "grant-protect": "Protegir e desprotegir paginas",
+       "grant-rollback": "Anullar modificacions sus de paginas",
        "grant-sendemail": "Mandar de corriers electronics als autres utilizaires",
        "grant-uploadeditmovefile": "Telecargar, remplaçar e renomenar de fichièrs",
        "grant-uploadfile": "Importar de fichièrs novèls",
        "grant-basic": "Dreits de basa",
        "grant-viewdeleted": "Afichar los fichièrs e paginas suprimits",
        "grant-viewmywatchlist": "Afichar vòstra lista de seguiment",
+       "grant-viewrestrictedlogs": "Afichar las entradas del jornal confidencialas",
        "newuserlogpage": "Istoric de las creacions de comptes",
        "newuserlogpagetext": "Jornal de las creacions de comptes d'utilizaires.",
        "rightslog": "Istoric de las modificacions d'estatut",
        "action-createpage": "crear aquesta pagina",
        "action-createtalk": "crear aquesta pagina de discussion",
        "action-createaccount": "crear aqueste compte d'utilizaire",
+       "action-autocreateaccount": "Crear automaticament aquel compte d'usatgièr extèrne",
        "action-history": "afichar l’istoric d'aquesta pagina",
        "action-minoredit": "marcar aqueste cambiament coma menor",
        "action-move": "renomenar aquesta pagina",
        "action-deleterevision": "suprimir las revisions",
        "action-deletelogentry": "suprimir las entradas del jornal",
        "action-deletedhistory": "veire l’istoric suprimit d'una pagina",
+       "action-deletedtext": "Afichar lo tèxte de la revision suprimida",
        "action-browsearchive": "recercar de paginas suprimidas",
        "action-undelete": "restablir de paginas",
        "action-suppressrevision": "visionar e restablir de revisions suprimidas",
        "action-viewmywatchlist": "afichar vòstra pròpria lista de seguiment",
        "action-viewmyprivateinfo": "veire vòstras informacions personalas",
        "action-editmyprivateinfo": "modificar vòstras informacions personalas",
+       "action-editcontentmodel": "Editar lo modèl de contengut d'una pagina",
+       "action-managechangetags": "Crear e (des)activar d'etiquetas",
+       "action-applychangetags": "Aplicar las etiquetas amb los vòstres cambiaments",
+       "action-changetags": "Apondre e suprimir arbitràriament d'etiquetas  a las revisions individualas e a las entradas de jornal.",
+       "action-deletechangetags": "Suprimir d'etiquetas dempuèi la basa de donadas",
        "action-purge": "purgar aquesta pagina",
        "nchanges": "$1 {{PLURAL:$1|cambiament|cambiaments}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|dempuèi la darrièra visita}}",
        "recentchanges-legend": "Opcions dels darrièrs cambiaments",
        "recentchanges-summary": "Vaquí sus aquesta pagina, los darrièrs cambiaments de {{SITENAME}}.",
        "recentchanges-noresult": "Pas cap de modificacion que correspond a aqueles critèris sul periòde indicat.",
+       "recentchanges-timeout": "Aquesta cerca dura tròp de temps. Podètz ensajar de paramètres de cerca diferents",
+       "recentchanges-network": "Se pòt pas afichar pas cap de resultat en causa d'una error tecnica. Ensajatz de tornar cargar la pagina.",
+       "recentchanges-notargetpage": "Dintrar lo nom d'una pagina per veire los cambiaments relatius a aquesta pagina.",
        "recentchanges-feed-description": "Seguissètz los darrièrs cambiaments d'aqueste wiki dins un flux.",
        "recentchanges-label-newpage": "Aquesta modificacion a creat una pagina novèla",
        "recentchanges-label-minor": "Aqueste cambiament es menor",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (veire tanben la [[Special:NewPages|lista de las paginas novèlas]]).",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Afichar",
+       "rcfilters-tag-remove": "Suprimir '$1'",
+       "rcfilters-legend-heading": "<strong>Lista de las abreviacions:</strong>",
+       "rcfilters-other-review-tools": "Autras aisinas de supervision",
+       "rcfilters-group-results-by-page": "Agropar los resultats per pagina",
        "rcfilters-activefilters": "Filtres actius",
+       "rcfilters-advancedfilters": "Filtres avançats",
+       "rcfilters-limit-title": "Resultats d'affichar",
+       "rcfilters-days-title": "Darrièrs jorns",
        "rcfilters-hours-title": "Darrièras oras",
        "rcfilters-days-show-days": "($1 {{PLURAL:$1|jorn|jorns}})",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|ora|oras}}",
+       "rcfilters-highlighted-filters-list": "Mes en evidéncia: $1",
        "rcfilters-quickfilters": "Filtres salvats",
+       "rcfilters-quickfilters-placeholder-title": "Pas encara de filtre salvagardat",
+       "rcfilters-quickfilters-placeholder-description": "Per salvagardar los paramètres de los vòstres filtres e tornar los utilizar mai tard , clicatz sus l'icòna dels favorits dins l'airal de Filtres Actius, dejós.",
        "rcfilters-savedqueries-defaultlabel": "Filtres salvats",
        "rcfilters-savedqueries-rename": "Renomenar",
        "rcfilters-savedqueries-setdefault": "Activar per defaut",
        "rcfilters-savedqueries-apply-label": "Crear un filtre",
        "rcfilters-savedqueries-apply-and-setdefault-label": "Crear lo filtre per defaut",
        "rcfilters-savedqueries-cancel-label": "Anullar",
+       "rcfilters-savedqueries-add-new-title": "Salvagardar los paramètres del filtre actual",
+       "rcfilters-savedqueries-already-saved": "Aquestes filtres son ja salvagardats. Vos cal modificar de paramètres  per crear un novèl filtre salvagardat.",
+       "rcfilters-restore-default-filters": "Restaurar los filtres per defaut",
+       "rcfilters-clear-all-filters": "Escafar totes los filtres",
+       "rcfilters-show-new-changes": "Veire los cambiaments los mai recents",
+       "rcfilters-search-placeholder": "Filtrar los cambiaments (utilizatz lo menu o cercatz lo nom d'un filtre)",
        "rcfilters-invalid-filter": "Filtre pas valid",
+       "rcfilters-empty-filter": "I a pas cap de filtre actiu. Se mòstran totas las contribucions.",
        "rcfilters-filterlist-title": "Filtres",
+       "rcfilters-filterlist-whatsthis": "Cossí fonciona aquò ?",
+       "rcfilters-filterlist-feedbacklink": "Digatz nos que pensatz d'aquestas aisinas (novelas) per filtrar",
+       "rcfilters-highlightbutton-title": "Valorar los resultats",
        "rcfilters-highlightmenu-title": "Causir una color",
+       "rcfilters-highlightmenu-help": "Causir una color per valorar aquesta proprietat",
        "rcfilters-filterlist-noresults": "Cap de filtre pas trobat",
+       "rcfilters-noresults-conflict": "S'es pas trobat cap de resultat perque los critèris de cèrca son en conflicte",
+       "rcfilters-state-message-subset": "Aquel filtre fonciona pas perque los seus resultats son inclús dins los resultats de la cerca seguenta , {{PLURAL:$2|filtre mai larg |filtres mai larges}} (ensajatz de los destriar amb la mesa en forma): $1",
+       "rcfilters-state-message-fullcoverage": "Seleccionar totes los filtres d'aquel grop es equivalent a una seleccion voida, doncas aquel filtre a pas d'efèit. Lo grop compren: $1",
        "rcfilters-filtergroup-authorship": "Paternitat de las contribucions",
        "rcfilters-filter-editsbyself-label": "Modificacions faitas per vos",
        "rcfilters-filter-editsbyself-description": "Vòstras pròprias contribucions.",
        "rcfilters-filter-editsbyother-label": "Modificacions faitas pels autres.",
+       "rcfilters-filter-editsbyother-description": "Totes los cambiaments a l'excepcion de los vòstres.",
+       "rcfilters-filtergroup-userExpLevel": "Registrament dels usatgièrs e experiéncia",
        "rcfilters-filter-user-experience-level-registered-label": "Connectat",
        "rcfilters-filter-user-experience-level-registered-description": "Editors connectats.",
        "rcfilters-filter-user-experience-level-unregistered-label": "Pas connectat",
        "rcfilters-filter-user-experience-level-unregistered-description": "Editors que son pas connectats.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Novèls arribants",
+       "rcfilters-filter-user-experience-level-newcomer-description": "Editors registrats qu'an fait mens de 10 cambiaments o que son actius dempuèi mens de 4 jorns.",
        "rcfilters-filter-user-experience-level-learner-label": "Aprenents",
+       "rcfilters-filter-user-experience-level-learner-description": "Editors registrats, que lor nivèl d'experiéncia es entre \"Utilizaire novelari\" e \"Utilizaire experimentat.\"",
        "rcfilters-filter-user-experience-level-experienced-label": "Utilizaires experimentats",
+       "rcfilters-filter-user-experience-level-experienced-description": "Editors registrats amb mai de 500 cambiaments e 30 jorns d'activitat.",
        "rcfilters-filtergroup-automated": "Contribucions automatizadas",
        "rcfilters-filter-bots-label": "Robòt",
+       "rcfilters-filter-bots-description": "Cambiaments faits per d'aisinas automaticas",
        "rcfilters-filter-humans-label": "Èsser uman (pas robòt)",
        "rcfilters-filter-humans-description": "Modificacions faitas per d'editors umans.",
+       "rcfilters-filtergroup-reviewstatus": "Estat de revision",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Cambiaments que son pas marcats coma revisats manualament o automaticament.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Pas patrolhat",
+       "rcfilters-filter-reviewstatus-manual-description": "Cambiaments manuals marcats coma revisats",
+       "rcfilters-filter-reviewstatus-manual-label": "Verificat manualament",
+       "rcfilters-filter-reviewstatus-auto-description": "Edicions per d'usatgièrs experimentats que lor trabalh es marcat automaticament coma verificat.",
+       "rcfilters-filter-reviewstatus-auto-label": "Verificat automaticament",
        "rcfilters-filtergroup-significance": "Significacion",
        "rcfilters-filter-minor-label": "Cambiaments menors",
        "rcfilters-filter-minor-description": "Modificacions que l'autor a marcadas coma menoras.",
        "rcfilters-filter-major-label": "Modificacions pas menoras",
        "rcfilters-filter-major-description": "Modificacions pas marcadas coma menoras.",
+       "rcfilters-filtergroup-watchlist": "Paginas de la lista de seguiment",
+       "rcfilters-filter-watchlist-watched-label": "Sus la lista de seguiment",
+       "rcfilters-filter-watchlist-watched-description": "Cambiaments faits sus las paginas de la vòstra lista de seguiment.",
+       "rcfilters-filter-watchlist-watchednew-label": "Cambiaments novèls dins la lista de seguiment",
+       "rcfilters-filter-watchlist-watchednew-description": "Cambiaments dins las paginas en seguiment qu'avètz pas vistas dempuèi que de cambiaments foguèron faits.",
+       "rcfilters-filter-watchlist-notwatched-label": "Es pas sus la lista de seguiment",
+       "rcfilters-filter-watchlist-notwatched-description": "Tot a l'excepcion de cambiaments faits sus las vòstras paginas de seguiment.",
+       "rcfilters-filtergroup-watchlistactivity": "Activitat sus la lista de seguiment",
+       "rcfilters-filter-watchlistactivity-unseen-label": "Cambiaments pas vists",
+       "rcfilters-filter-watchlistactivity-unseen-description": "Cambiaments dins las paginas en seguiment qu'avètz pas vistas dempuèi que de cambiaments foguèron faits.",
+       "rcfilters-filter-watchlistactivity-seen-label": "Cambiaments qu'avètz ja vistes",
+       "rcfilters-filter-watchlistactivity-seen-description": "Cambiaments dins las paginas  qu'avètz vistas dempuèi que de cambiaments foguèron faits.",
        "rcfilters-filtergroup-changetype": "Tipe de cambiament",
        "rcfilters-filter-pageedits-label": "Modificacions de pagina",
        "rcfilters-filter-pageedits-description": "Modificacions del contengut del wiki, de las discussions, de las descripcions de las categorias...",
        "rcfilters-filter-newpages-label": "Creacions de pagina",
        "rcfilters-filter-newpages-description": "Modificacions a l'origina de paginas novèlas.",
        "rcfilters-filter-categorization-label": "Cambiaments de categoria",
+       "rcfilters-filter-categorization-description": "Registraments de paginas apondudas o suprimidas de las categorias.",
        "rcfilters-filter-logactions-label": "Accions traçadas",
        "rcfilters-filter-logactions-description": "Accions dels administrators, creacions de comptes, supressions de paginas, telecargaments...",
        "rcnotefrom": "Çaijós {{PLURAL:$5|la modificacion efectuada|las modificacions efectuadas}} dempuèi lo <strong>$3, $4</strong> (afichadas fins a <strong>$1</strong>).",
        "whatlinkshere": "Paginas ligadas a aquesta",
        "whatlinkshere-title": "Paginas que puntan cap a « $1 »",
        "whatlinkshere-page": "Pagina :",
-       "linkshere": "Las paginas çaijós contenon un ligam cap a '''[[:$1]]''':",
-       "nolinkshere": "Cap de pagina conten pas de ligam cap a '''[[:$1]]'''.",
-       "nolinkshere-ns": "Cap de pagina conten pas de ligam cap a '''[[:$1]]''' dins l’espaci de nom causit.",
+       "linkshere-2": "Las paginas çaijós contenon un ligam cap a '''$1''':",
+       "nolinkshere-2": "Cap de pagina conten pas de ligam cap a '''$1'''.",
+       "nolinkshere-ns-2": "Cap de pagina conten pas de ligam cap a '''$1''' dins l’espaci de nom causit.",
        "isredirect": "pagina de redireccion",
        "istemplate": "inclusion",
        "isimage": "ligam cap al fichièr",
        "fileduplicatesearch-noresults": "Cap de fichièr nomenat « $1 » es pas estat trobat.",
        "specialpages": "Paginas especialas",
        "specialpages-note-top": "Legenda",
+       "specialpages-note-restricted": "* Paginas especialas normalas.\n* <span class=\"mw-specialpagerestricted\">Paginas especialas restrentas.</span>",
        "specialpages-group-maintenance": "Rapòrts de mantenença",
        "specialpages-group-other": "Autras paginas especialas",
        "specialpages-group-login": "S'identificar / s'inscriure",
index e6412b9..f2433a8 100644 (file)
        "whatlinkshere": "Linkit tänne",
        "whatlinkshere-title": "Sivut, kudamat kosketah sivuu \"$1\"",
        "whatlinkshere-page": "Sivu:",
-       "linkshere": "Nämmä sivut linkittiäkseh sivuh <strong>[[:$1]]</strong>:",
+       "linkshere-2": "Nämmä sivut linkittiäkseh sivuh <strong>$1</strong>:",
        "isredirect": "uvvellehohjavussivu",
        "istemplate": "sizällyttämine",
        "isimage": "failan linku",
index b7503ec..06aa815 100644 (file)
        "whatlinkshere": "ଏଠାରେ ଥିବା ଲିଙ୍କ",
        "whatlinkshere-title": "\"$1\" କୁ ପୃଷ୍ଠା ଲିଙ୍କ",
        "whatlinkshere-page": "ପୃଷ୍ଠା:",
-       "linkshere": "ଏହି ପୃଷ୍ଠା ସବୁ  <strong>[[:$1]]</strong> ସହ ଯୋଡ଼ା ଯାଇଅଛି:",
-       "nolinkshere": "'''[[:$1]]''' ସହିତ କୌଣସିଟି ପୃଷ୍ଠା ଯୋଡ଼ାଯାଇନାହିଁ ।",
-       "nolinkshere-ns": "ବଛା ଯାଇଥିବା ନେମସ୍ପେସରେ '''[[:$1]]''' ନାଆଁ ସହ କୌଣସି ବି ପୃଷ୍ଠା ଯୋଡ଼ାଯାଇନାହିଁ ।",
+       "linkshere-2": "ଏହି ପୃଷ୍ଠା ସବୁ  <strong>$1</strong> ସହ ଯୋଡ଼ା ଯାଇଅଛି:",
+       "nolinkshere-2": "'''$1''' ସହିତ କୌଣସିଟି ପୃଷ୍ଠା ଯୋଡ଼ାଯାଇନାହିଁ ।",
+       "nolinkshere-ns-2": "ବଛା ଯାଇଥିବା ନେମସ୍ପେସରେ '''$1''' ନାଆଁ ସହ କୌଣସି ବି ପୃଷ୍ଠା ଯୋଡ଼ାଯାଇନାହିଁ ।",
        "isredirect": "ଆଉଥରେ ଫେରିବା ପୃଷ୍ଠା",
        "istemplate": "ଆଧାର ସହ ଭିତରେ ରଖିବା",
        "isimage": "ଫାଇଲର ଲିଙ୍କ",
        "fileduplicatesearch-noresults": "\"$1\" ନାମରେ ଗୋଟିଏ ବି ଫାଇଲ ମିଳିଲା ନାହିଁ ।",
        "specialpages": "ବିଶେଷ ପୃଷ୍ଠା",
        "specialpages-note-top": "ଲିଜେଣ୍ଡ",
+       "specialpages-note-restricted": "* ସାଧାରଣ ବିଶେଷ ପୃଷ୍ଠାମାନ ।\n* <span class=\"mw-specialpagerestricted\">କିଳାଯାଇଥିବା ବିଶେଷ ପୃଷ୍ଠାମାନ ।</span>",
        "specialpages-group-maintenance": "ରକ୍ଷଣାବେକ୍ଷଣା ବିବରଣୀ",
        "specialpages-group-other": "ବାକି ବିଶେଷ ପୃଷ୍ଠା",
        "specialpages-group-login": "ଲଗ-ଇନ (Log in)/ ନୂଆ ଖାତା ଖୋଲିବେ (Sign up)",
index 554b2b4..dea5c69 100644 (file)
        "whatlinkshere": "Чи æрвиты ардæм",
        "whatlinkshere-title": "Фæрстæ, кæдон æрвитынц ардæм: «$1»",
        "whatlinkshere-page": "Фарс:",
-       "linkshere": "Ацы фæрстæ æрвитынц '''[[:$1|{{grammar:allative|$1}}]]''':",
-       "nolinkshere": "Никæцы фарс æрвиты ардæм: '''[[:$1]]'''.",
-       "nolinkshere-ns": "Амынд номдоны мидæг никæцы фарс æрвиты ардæм <strong>[[:$1]]</strong>.",
+       "linkshere-2": "Ацы фæрстæ æрвитынц '''$1''':",
+       "nolinkshere-2": "Никæцы фарс æрвиты ардæм: '''$1'''.",
+       "nolinkshere-ns-2": "Амынд номдоны мидæг никæцы фарс æрвиты ардæм <strong>$1</strong>.",
        "isredirect": "æрвитæн фарс",
        "istemplate": "æфтыдæй",
        "isimage": "файлмæ æрвитæн",
index 32fbc0b..af9527f 100644 (file)
        "whatlinkshere": "ਇੱਥੇ ਕੀ ਆ ਕੇ ਜੁੜਦਾ ਹੈ",
        "whatlinkshere-title": "$1 ਨਾਲ ਜੋੜਨ ਵਾਲੇ ਸਫ਼ੇ",
        "whatlinkshere-page": "ਸਫ਼ਾ:",
-       "linkshere": "ਇਹ ਪੰਨੇ '''[[:$1]]''' ਨਾਲ ਜੋੜਦੇ ਹਨ:",
-       "nolinkshere": "ਕੋਈ ਵੀ ਸਫ਼ਾ '''[[:$1]]''' ਨਾਲ ਨਹੀਂ ਜੋੜਦਾ।",
+       "linkshere-2": "ਇਹ ਪੰਨੇ '''$1''' ਨਾਲ ਜੋੜਦੇ ਹਨ:",
+       "nolinkshere-2": "ਕੋਈ ਵੀ ਸਫ਼ਾ '''$1''' ਨਾਲ ਨਹੀਂ ਜੋੜਦਾ।",
        "isredirect": "ਰੀਡਿਰੈਕਟ ਸਫ਼ਾ",
        "istemplate": "ਟਾਕਰਾ ਕਰੋ",
        "isimage": "ਫ਼ਾਈਲ ਲਿੰਕ",
index e8d4495..4b23940 100644 (file)
        "whatlinkshere": "Deng pakasuglung keti",
        "whatlinkshere-title": "Deng bulung a makasuglung king \"$1\"",
        "whatlinkshere-page": "Bulung:",
-       "linkshere": "Pakasuglung la king '''[[:$1]]''' deng makatuking bulung:",
-       "nolinkshere": "Alang bulung a makasuglung king '''[[:$1]]'''.",
-       "nolinkshere-ns": "Alang bulung a makatuglung king '''[[:$1]]''' ketang mepiling pirinan lagyu (namespace).",
+       "linkshere-2": "Pakasuglung la king '''$1''' deng makatuking bulung:",
+       "nolinkshere-2": "Alang bulung a makasuglung king '''$1'''.",
+       "nolinkshere-ns-2": "Alang bulung a makatuglung king '''$1''' ketang mepiling pirinan lagyu (namespace).",
        "isredirect": "Bulung ning pamanaliling direksiun",
        "istemplate": "misingit",
        "isimage": "Isuglung king larawan",
index 089fc13..ca5abff 100644 (file)
        "whatlinkshere": "Cha lie quoé ichi",
        "whatlinkshere-title": "Paches qu'il ont des loïens aveuc \"$1\"",
        "whatlinkshere-page": "Pache:",
-       "linkshere": "Chés paches-lo il sont érliées à '''[[:$1]]''':",
-       "nolinkshere": "i n'y o poin d'pache aveuc un loïen vers  '''[[:$1]]'''.",
-       "nolinkshere-ns": "i n'y o poin d'pache aveuc un loïen vers '''[[:$1]]''' dins echl'éspace d'noms coési.",
+       "linkshere-2": "Chés paches-lo il sont érliées à '''$1''':",
+       "nolinkshere-2": "i n'y o poin d'pache aveuc un loïen vers  '''$1'''.",
+       "nolinkshere-ns-2": "i n'y o poin d'pache aveuc un loïen vers '''$1''' dins echl'éspace d'noms coési.",
        "isredirect": "pache érdirigée",
        "istemplate": "transclusion",
        "isimage": "Loïen aveuc l'fichié",
        "version-specialpages": "Paches éspéchiales",
        "fileduplicatesearch": "Dénicher chés doublons",
        "specialpages": "Paches éspéchiales",
+       "specialpages-note-restricted": "* Paches éspéchiales conformes.\n* <span class=\"mw-specialpagerestricted\">Paches éspéchiales réstrintes.</span>\n* <span class=\"mw-specialpagecached\">Paches éspéchiales seulemint in muche (pétète des viuseries).</span>",
        "specialpages-group-maintenance": "Rapports d'maintenanche",
        "specialpages-group-other": "Eutes paches éspéchiales",
        "specialpages-group-changes": "Darins canjemints pi gazètes",
index fd24862..b421a6a 100644 (file)
        "whatlinkshere": "Was dohea zaische dud",
        "whatlinkshere-title": "Saide wu uff \"$1\" valing'gn",
        "whatlinkshere-page": "Said:",
-       "linkshere": "Die Saide valing'gn uff '''[[:$1]]''':",
-       "nolinkshere": "Kä Said zaischd uff '''[[:$1]]'''.",
+       "linkshere-2": "Die Saide valing'gn uff '''$1''':",
+       "nolinkshere-2": "Kä Said zaischd uff '''$1'''.",
        "isredirect": "Waidalaidungsaid",
        "istemplate": "Vorlacheoibindung",
        "isimage": "Dadailing'g",
index ab4d43a..70e089a 100644 (file)
        "botpasswords-restriction-failed": "Logowanie nie powiodło się z powodu ograniczeń na hasło bota.",
        "botpasswords-invalid-name": "Określona nazwa użytkownika nie zawiera separatora hasła bota (\"$1\").",
        "botpasswords-not-exist": "Użytkownik \"$1\" nie ma hasła dla bota o nazwie \"$2\".",
+       "botpasswords-needs-reset": "Hasło dla bota o nazwie „$2” {{GENDER:$1|użytkownika|użytkowniczki}} „$1” musi zostać zresetowane.",
        "resetpass_forbidden": "Hasła nie mogą zostać zmienione",
        "resetpass_forbidden-reason": "Hasła nie mogą zostać zmienione: $1",
        "resetpass-no-info": "Musisz być zalogowany, by uzyskać bezpośredni dostęp do tej strony.",
        "subject-preview": "Podgląd tematu:",
        "previewerrortext": "Wystąpił błąd podczas próby podglądu Twoich zmian.",
        "blockedtitle": "Użytkownik jest zablokowany",
-       "blockedtext": "'''Twoje konto lub adres IP zostały zablokowane.'''\n\nBlokada została nałożona przez $1.\nPodany powód to: ''$2''.\n\n* Początek blokady: $8\n* Wygaśnięcie blokady: $6\n* Zablokowany został: $7\n\nW celu wyjaśnienia przyczyny zablokowania możesz się skontaktować z $1 lub innym [[{{MediaWiki:Grouppage-sysop}}|administratorem]].\nNie możesz użyć funkcji „Wyślij e‐mail do tego użytkownika”, jeśli brak jest poprawnego adresu e‐mail w Twoich [[Special:Preferences|preferencjach]] lub jeśli taka możliwość została Ci zablokowana.\nTwój obecny adres IP to $3, a numer identyfikacyjny blokady to $5.\nProsimy o podanie obu tych informacji przy wyjaśnianiu blokady.",
-       "autoblockedtext": "Ten adres IP został zablokowany automatycznie, gdyż korzysta z niego inny użytkownik, zablokowany przez administratora $1.\nPowód blokady:\n\n:''$2''\n\n* Początek blokady: $8\n* Wygaśnięcie blokady: $6\n* Zablokowany został: $7\n\nMożesz skontaktować się z $1 lub jednym z pozostałych [[{{MediaWiki:Grouppage-sysop}}|administratorów]] w celu uzyskania informacji o blokadzie.\n\nNie możesz użyć funkcji „Wyślij e‐mail do tego użytkownika”, jeśli brak jest poprawnego adresu e‐mail w Twoich [[Special:Preferences|preferencjach]] lub jeśli taka możliwość została Ci zablokowana.\n\nTwój obecny adres IP to $3, a numer identyfikacyjny blokady to $5.\nProsimy o podanie obu tych numerów przy wyjaśnianiu blokady.",
+       "blockedtext": "<strong>Twoje konto lub adres IP zostały zablokowane.</strong>\n\nBlokada została nałożona przez $1.\nPodany powód to: <em>$2</em>.\n\n* Początek blokady: $8\n* Wygaśnięcie blokady: $6\n* Zablokowany został: $7\n\nW celu wyjaśnienia przyczyny zablokowania możesz się skontaktować z $1 lub innym [[{{MediaWiki:Grouppage-sysop}}|administratorem]].\nNie możesz użyć funkcji „{{int:emailuser}}”, jeśli brak jest poprawnego adresu e‐mail w Twoich [[Special:Preferences|preferencjach]] lub jeśli taka możliwość została Ci zablokowana.\nTwój obecny adres IP to $3, a numer identyfikacyjny blokady to #$5.\nProsimy o podanie obu tych informacji przy wyjaśnianiu blokady.",
+       "autoblockedtext": "Ten adres IP został zablokowany automatycznie, gdyż korzysta z niego inny użytkownik, zablokowany przez administratora $1.\nPowód blokady:\n\n:<em>$2</em>\n\n* Początek blokady: $8\n* Wygaśnięcie blokady: $6\n* Zablokowany został: $7\n\nMożesz skontaktować się z $1 lub jednym z pozostałych [[{{MediaWiki:Grouppage-sysop}}|administratorów]] w celu uzyskania informacji o blokadzie.\n\nNie możesz użyć funkcji „{{int:emailuser}}”, jeśli brak jest poprawnego adresu e‐mail w Twoich [[Special:Preferences|preferencjach]] lub jeśli taka możliwość została Ci zablokowana.\n\nTwój obecny adres IP to $3, a numer identyfikacyjny blokady to #$5.\nProsimy o podanie obu tych numerów przy wyjaśnianiu blokady.",
        "systemblockedtext": "Twoja nazwa użytkownika lub adres IP zostały automatycznie zablokowane przez MediaWiki.\nPodany powód to:\n\n:<em>$2</em>\n\n* Początek blokady: $8\n* Wygaśnięcie blokady: $6\n* Zamierzano zablokować: $7\n\nTwój obecny adres IP to $3.\nProsimy o dołączenie powyższych szczegółów w jakichkolwiek zadawanych pytaniach.",
        "blockednoreason": "nie podano przyczyny",
        "whitelistedittext": "Musisz $1, by edytować strony.",
        "recentchangescount": "Domyślna liczba wyświetlanych edycji w ostatnich zmianach, historii i rejestrach:",
        "prefs-help-recentchangescount": "Maksymalna liczba: 1000",
        "prefs-help-watchlist-token2": "To jest tajny klucz umożliwiający dostęp do kanału internetowego zmian w obserwowanych przez ciebie stronach.\nKażdy, kto go zna, będzie mógł je zobaczyć, więc zachowaj go dla siebie.\n[[Special:ResetTokens|Kliknij tu, jeśli chcesz go zresetować]].",
-       "prefs-help-tokenmanagement": "Możesz zobaczyć i zresetować sekretny klucz przypisany do konta, służący do uzyskania dostępu do kanału internetowego zmian w obserwowanych przez ciebie stronach. Każdy, kto go zna, będzie mógł je zobaczyć, więc nie udostępniaj go.",
+       "prefs-help-tokenmanagement": "Możesz zobaczyć i zresetować tajny klucz przypisany do Twojego konta, służący do uzyskania dostępu do kanału internetowego zmian w obserwowanych przez ciebie stronach. Każdy, kto go zna, będzie mógł je zobaczyć, więc nie udostępniaj go.",
        "savedprefs": "Twoje preferencje zostały zapisane.",
        "savedrights": "Zapisano grupy {{GENDER:$1|użytkownika $1|użytkowniczki $1}}.",
        "timezonelegend": "Strefa czasowa:",
        "protectedtitles-submit": "Wyświetl tytuły",
        "listusers": "Lista użytkowników",
        "listusers-editsonly": "Pokaż tylko użytkowników z edycjami",
+       "listusers-temporarygroupsonly": "Pokaż tylko użytkowników w tymczasowych grupach użytkowników",
        "listusers-creationsort": "Sortuj według daty utworzenia",
        "listusers-desc": "Sortuj w kolejności malejącej",
        "usereditcount": "$1 {{PLURAL:$1|edycja|edycje|edycji}}",
        "whatlinkshere": "Linkujące",
        "whatlinkshere-title": "Strony linkujące do „$1”",
        "whatlinkshere-page": "Strona:",
-       "linkshere": "Następujące strony odwołują się do '''[[:$1]]''':",
-       "nolinkshere": "Żadna strona nie odwołuje się do '''[[:$1]]'''.",
-       "nolinkshere-ns": "Żadna strona nie odwołuje się do '''[[:$1]]''' w wybranej przestrzeni nazw.",
+       "linkshere-2": "Następujące strony odwołują się do '''$1''':",
+       "nolinkshere-2": "Żadna strona nie odwołuje się do '''$1'''.",
+       "nolinkshere-ns-2": "Żadna strona nie odwołuje się do '''$1''' w wybranej przestrzeni nazw.",
        "isredirect": "strona przekierowująca",
        "istemplate": "dołączony szablon",
        "isimage": "link do pliku",
        "pagedata-title": "Dane ze strony",
        "pagedata-text": "Ta strona udostępnia interfejs danych do stron. Podaj tytuł strony w adresie URL, używając składni podstrony.\n* Negocjacja treści obowiązuje w oparciu o nagłówek Accept Twojego klienta. Oznacza to, że dane strony będą dostarczane w formacie preferowanym przez klienta.",
        "pagedata-not-acceptable": "Nie znaleziono pasującego formatu. Obsługiwane typy MIME: $1",
-       "pagedata-bad-title": "Niepoprawny tytuł: $1."
+       "pagedata-bad-title": "Niepoprawny tytuł: $1.",
+       "unregistered-user-config": "Ze względów bezpieczeństwa podstrony użytkownika: JavaScript, CSS i JSON nie mogą być załadowane dla niezarejestrowanych użytkowników.",
+       "passwordpolicies": "Zasady dotyczące haseł",
+       "passwordpolicies-group": "Grupa",
+       "passwordpolicies-policies": "Zasady",
+       "passwordpolicies-policy-minimalpasswordlength": "Hasło musi mieć co najmniej $1 {{PLURAL:$1|znak|znaki|znaków}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Aby się zalogować, hasło musi mieć co najmniej $1 {{PLURAL:$1|znak|znaki|znaków}}",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Hasło nie może być takie samo jak nazwa użytkownika",
+       "passwordpolicies-policy-maximalpasswordlength": "Hasło musi mieć mniej niż $1 {{PLURAL:$1|znak|znaki|znaków}}"
 }
index 0b9c96a..5a88383 100644 (file)
@@ -18,7 +18,8 @@
                        "Purodha",
                        "Macofe",
                        "Matma Rex",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Paolo Castellina"
                ]
        },
        "tog-underline": "Anliure con la sotliniadura",
@@ -46,7 +47,7 @@
        "tog-shownumberswatching": "Smon-e ël nùmer d'utent che as ten-o la pàgina sot-euj",
        "tog-oldsig": "Firma esistenta:",
        "tog-fancysig": "Traté la firma com dël test wiki (sensa n'anliura automàtica)",
-       "tog-uselivepreview": "Dovré la fonsion ''Preuva dal viv''",
+       "tog-uselivepreview": "Dovré la fonsion ''Preuva dal viv'' sensa carié la pàgina",
        "tog-forceeditsummary": "Ciamé conferma se ël resumé dla modìfica a l'é veujd",
        "tog-watchlisthideown": "Stërmé mie modìfiche ant la ròba che im ten-o sot-euj",
        "tog-watchlisthidebots": "Stërmé le modìfiche fàite daj trigomiro ant la lista dle ròbe che im ten-o sot-euj",
@@ -59,7 +60,7 @@
        "tog-showhiddencats": "Smon-e le categorìe stërmà",
        "tog-norollbackdiff": "Fé nen vëdde le diferense apress d'avèj ripristinà",
        "tog-useeditwarning": "Aviseme quand che i chito na pàgina ëd modìfiche con dle modìfiche nen salvà",
-       "tog-prefershttps": "Dovré sempe na conession sigura pr'ësté andrinta al sistema",
+       "tog-prefershttps": "Dovré sempe na conession sicura quand ch'a l'é intrà ant ël sistema",
        "underline-always": "Sempe",
        "underline-never": "Mai",
        "underline-default": "Stàndard dël navigator o dël tema",
        "newwindow": "(as deurb ant na fnestra neuva)",
        "cancel": "Anulé",
        "moredotdotdot": "Ëd pì...",
-       "morenotlisted": "Costa lista a l'é nen completa.",
+       "morenotlisted": "Costa lista a podrìa esse nen completa.",
        "mypage": "Pàgina",
        "mytalk": "Ciaciarade",
-       "anontalk": "Ciaciarade për st'adrëssa IP-sì",
+       "anontalk": "Discussion",
        "navigation": "Navigassion",
        "and": "&#32;e",
        "faq": "Chestion frequente",
        "searcharticle": "Andé",
        "history": "Version pì veje",
        "history_short": "Stòria",
+       "history_small": "stòria",
        "updatedmarker": "agiornà da l'ùltima vira che i son passà",
        "printableversion": "Version bon-a për stampé",
        "permalink": "Anliura fissa",
        "redirectedfrom": "(Ridiression da $1)",
        "redirectpagesub": "Pàgina ëd ridiression",
        "redirectto": "Ridiression a:",
-       "lastmodifiedat": "Modificà l'ùltima vira ai $1 a $2.",
+       "lastmodifiedat": "Modificà l'ùltima vira dël $1, al $2.",
        "viewcount": "St'artìcol-sì a l'é stàit lesù {{PLURAL:$1|na vira|$1 vire}}.",
        "protectedpage": "Pàgina proteta",
        "jumpto": "Andé a:",
        "viewsource": "Vardé la sorgiss",
        "viewsource-title": "Vëdde la sorgiss ëd $1",
        "actionthrottled": "Assion limità",
-       "actionthrottledtext": "Për evité che 'd gent ò 'd màchine an carìo dla rumenta, st'assion-sì as peul nen fesse tròp ëd soèns, e chiel a l'ha arpetula tròpe vire. Ch'a sia gentil, ch'a preuva torna antra dontré minute.",
+       "actionthrottledtext": "Për evité che 'd gent ò 'd màchine an carìo dla rumenta, st'assion-sì as peul nen fesse tròp ëd soèns, e ti 't l'has arpetula tròpe vire. Sie gentil, preuva torna antra dontré minute.",
        "protectedpagetext": "Sta pàgina-sì a l'è stàita blocà për evité 'd modìfiche o d'àutre assion.",
        "viewsourcetext": "A peul vardé e copié la sorgiss dë sta pàgina.",
        "viewyourtext": "A peul vëdde e copié la sorgiss ëd <strong>soe modìfiche</strong> a costa pàgina-sì.",
        "createacct-reason": "Rason",
        "createacct-reason-ph": "Përchè a crea n'àutr cont",
        "createacct-submit": "Ch'a crea sò cont",
-       "createacct-another-submit": "Creé n'àutr cont",
+       "createacct-another-submit": "Creé un cont",
        "createacct-benefit-heading": "{{SITENAME}} a l'é fàit da 'd gent coma chiel.",
        "createacct-benefit-body1": "{{PLURAL:$1|modìfica|modìfiche}}",
        "createacct-benefit-body2": "{{PLURAL:$1|pàgina|pàgine}}",
        "noname": "A l'ha nen ëspessificà në stranòm vàlid.",
        "loginsuccesstitle": "Compliment! A l'é pen-a rintrà ant ël sistema.",
        "loginsuccess": "'''Adess a l'é colegà a {{SITENAME}} con lë stranòm «$1».'''",
-       "nosuchuser": "A-i é pa gnun utent con lë stranòm «$1».\nJë stranòm ëd j'utent a son sensìbij a le majùscole.\nCh'a contròla ël nòm che a l'ha batù, o [[Special:CreateAccount|ch'a crea un neuv cont]].",
+       "nosuchuser": "A-i é pa gnun utent con lë stranòm «$1».\nJë stranòm ëd j'utent a son sensìbij a le majùscole.\nContròla ël nòm ch'it l'has batù, o [[Special:CreateAccount|crea un cont neuv]].",
        "nosuchusershort": "A-i é pa gnun utent che as ciama «$1». Për piasì, che a contròla se a l'ha scrit tut giust.",
        "nouserspecified": "A venta che a specìfica në stranòm d'utent",
        "login-userblocked": "St'utent-sì a l'é blocà. A peul pa intré ant ël sistema.",
        "eauthentsent": "A l'adrëssa che a l'ha dane i l'oma mandaje un mëssagi ëd pòsta eletrònica për conferma.\nAnans che qualsëssìa àutr messagi ëd pòsta a ven-a mandà a 's cont-sì, a venta che a a fasa coma che a-j diso dë fé ant ël mëssagi, për confermé che ës cont a l'é da bon sò.",
        "throttled-mailpassword": "Na ciav neuva a l'é gia stàita mandà da manch che {{PLURAL:$1|n'ora|$1 ore}}. Për evité dj'abus, mach un mëssagi ëd ri-inissialisassion ëd ciav a sarà mandà minca {{PLURAL:$1|ora|$1 ore}}.",
        "mailerror": "Eror ën mandand via un mëssagi ëd pòsta eletrònica: $1",
-       "acct_creation_throttle_hit": "Dij visitador ëd costa wiki, an dovrand soa adrëssa IP a l'han creà {{PLURAL:$1|1 cont|$1 cont}} ant l'ùltim di, che a l'é tut lòn che as peul fesse ant cost temp.\nËd conseguensa, ij visitador che a deuvro costa adrëssa IP a peulo pì nen fé dij cont al moment.",
+       "acct_creation_throttle_hit": "Dij visitador ëd costa wiki, an dovrand soa adrëssa IP a l'han creà {{PLURAL:$1|1 cont|$1 cont}} ant l'ùltim $2, che a l'é tut lòn che as peul fesse ant cost temp.\nËd conseguensa, ij visitador che a deuvro costa adrëssa IP a peulo pì nen fé dij cont al moment.",
        "emailauthenticated": "Soa adrëssa ëd pòsta eletrònica a l'é stàita confirmà ël $2 a $3.",
        "emailnotauthenticated": "Soa adrëssa ëd pòsta eletrònica a l'é pa ancó stàita confirmà.\nPër qualsëssìa ëd coste funsion a sarà mandà gnun mëssagi.",
        "noemailprefs": "Che a specìfica n'adrëssa ëd pòsta eletrònica se a veul dovré coste funsion-sì.",
        "createaccount-title": "Creassion d'un cont për {{SITENAME}}",
        "createaccount-text": "Cheidun a l'ha duvertà un cont për soa adrëssa ëd pòsta eletrònica ansima a {{SITENAME}} ($4) butand da stranòm «$2» e da ciav «$3». A dovrìa rintré ant ël sistema e cambiesse soa ciav pì ampressa ch'a peul.\n\nSe sòn a l'é rivà për eror, a peul lassé perde e fé gnente sensa problema.",
        "login-throttled": "A l'ha fàit tròpi tentativ recent d'intré ant ël sistema.\nPër piasì, ch'a speta $1 prima ëd prové torna.",
-       "login-abort-generic": "Sò tentitiv d'intré ant ël sistema a l'é falì - Abortì",
+       "login-abort-generic": "Sò tentativ d'intré ant ël sistema a l'é falì - Abortì",
        "login-migrated-generic": "Sò cont a l'ha emigrà, e sò stranòm a esist pi nen su costa wiki.",
        "loginlanguagelabel": "Lenga: $1",
        "suspicious-userlogout": "Soa arcesta ëd seurte dal sistema a l'é stàita arfudà përchè a smija com s'a fussa stàita mandà da 'n navigador rot o da l'archiviassion an local d'un prëstanòm.",
        "passwordreset-emailtext-user": "L'utent $1 ansima a {{SITENAME}} a l'ha ciamà na riampostassion ëd soa ciav për {{SITENAME}} ($4). {{PLURAL:$3|Ël cont utent sì-sota a l'é|Ij cont utent sì-sota a son}} associà a st'adrëssa ëd pòsta eletrònica:\n\n$2\n\n{{PLURAL:$3|Costa ciav provisòria|Coste ciav provisòrie}} a scadran da-sì {{PLURAL:$5|un di|$5 di}}.\nA dovrìa intré ant ël sistema e serne na ciav neuva adess. Se quaidun d'àutr a l'ha fàit costa arcesta, o s'a l'é arcordasse soa ciav original, e a veul pa pi cangela, a peul ignoré ës mëssagi e continué a dovré soa veja ciav.",
        "passwordreset-emailelement": "Stranòm: \n$1\n\nCiav provisòria: \n$2",
        "passwordreset-emailsentemail": "Un mëssagi ëd riampostassion ëd la ciav a l'é stàit spedì.",
-       "changeemail": "Cangé l'adrëssa ëd pòsta eletrònica",
+       "changeemail": "Cangé o dëscancelé l'adrëssa ëd pòsta eletrònica",
        "changeemail-header": "Cangé l'adrëssa ëd pòsta eletrònica dël cont",
        "changeemail-no-info": "A dev esse intrà ant ël sistema për andé diretament a costa pàgina.",
        "changeemail-oldemail": "Adrëssa ëd pòsta eletrònica atual:",
        "anonpreviewwarning": "''A l'é nen rintrà ant ël sistema. An salvand a sarà memorisà soa adrëssa IP ant la stòria dle modìfiche ëd sa pàgina.''",
        "missingsummary": "'''Nòta:''' a l'ha butà gnun resumé dla modìfica. Se a sgnaca «$1» n'àutra vira, soa modìfica a resterà salvà sensa resumé.",
        "selfredirect": "<strong>Atension:</strong> A l'é an camin ch'a ridiression-a sa pàgina a chila-midema.\nMiraco a l'ha spessificà ël bërsaj sbalià për la ridiression, opura a l'é an camin ch'a modìfica la pàgina sbalià.\nS'a sgnaca torna ansima a «$1», la ridiression a sarà creà istess.",
-       "missingcommenttext": "Për piasì, che a buta un coment sì-sota.",
+       "missingcommenttext": "Për piasì, buta un coment sì-sota.",
        "missingcommentheader": "'''Ch'a ten-a da ment:''' A l'ha pa dàit ëd soget o d'intestassion për cost coment.\nSe a sgnaca torna «$1», soa modìfica a sarà salvà sensa gnun-a intestassion.",
-       "summary-preview": "Preuva dël resumé:",
-       "subject-preview": "Preuva dl'oget/intestassion:",
+       "summary-preview": "Preuva dla compilassion dël resumé:",
+       "subject-preview": "Previsualisassion dl'oget:",
        "previewerrortext": "A l'é rivaje n'eror durant ël tentativ ëd previsualisassion ëd soe modìfiche.",
        "blockedtitle": "L'utent a l'é blocà.",
        "blockedtext": "'''Sò stranòm ò pura adrëssa IP a l'é stàit blocà.'''\n\nËl blocagi a l'é stàit fàit da $1.\nComa rason a l'ha butà ''$2''.\n\n* Blocà a parte dal: $8\n* Fin al: $6\n* As veul blochesse: $7\n\nA peul butesse an contat con $1 ò pura n'àotr [[{{MediaWiki:Grouppage-sysop}}|aministrator]] për discute ëd sò blocagi.\nCh'a ten-a present ch'a podrà dovré la fonsion «mandeje un messagi ëd pòsta eletrònica a l'utent» mach s'a l'ha specificà n'adrëssa ëd vàlida ant [[Special:Preferences|sò gust]] e se sta fonsion a l'é nen ëstàita blocà 'cò chila.\nSoa adrëssa IP corenta a l'é $3, e l'identificativ dël blocagi a l'é #$5.\nPër piasì, ch'a-j buta tut e doj ant soe comunicassion ant sta question-sì.",
        "search-file-match": "(a corëspond al contnù d'archivi)",
        "search-suggest": "Vorìi-lo pa dì: $1",
        "search-rewritten": "Visualisassion dj'arzultà për $1. Sërché nopà $2.",
-       "search-interwiki-caption": "Proget frej",
+       "search-interwiki-caption": "Arzultà dij proget frej",
        "search-interwiki-default": "Arzultà da $1:",
        "search-interwiki-more": "(ëd pì)",
        "search-relatedarticle": "Corelà",
        "prefs-watchlist-token": "Geton ëd lòn che as ten sot euj:",
        "prefs-misc": "Sòn e lòn",
        "prefs-resetpass": "Cangé la ciav",
-       "prefs-changeemail": "Cangé l'adrëssa ëd pòsta eletrònica",
+       "prefs-changeemail": "Cangé o dëscancelé l'adrëssa ëd pòsta eletrònica",
        "prefs-setemail": "Amposté n'adrëssa ëd pòsta eletrònica",
        "prefs-email": "Opsion ëd pòsta eletrònica",
        "prefs-rendering": "Sembiansa",
        "group-bot": "Trigomiro",
        "group-sysop": "Aministrator",
        "group-bureaucrat": "Mangiapapé",
-       "group-suppress": "Supervisor",
+       "group-suppress": "Ancarià dle sopression",
        "group-all": "(utent)",
        "group-user-member": "{{GENDER:$1|utent}}",
        "group-autoconfirmed-member": "{{GENDER:$1|utent ch'a l'é convalidasse daspërchiel|utent ch'a l'é convalidasse daspërchila}}",
        "group-bot-member": "{{GENDER:$1|trigomiro}}",
        "group-sysop-member": "{{GENDER:$1|aministrator|aministratris}}",
        "group-bureaucrat-member": "{{GENDER:$1|mangiapapé}}",
-       "group-suppress-member": "{{GENDER:$1|supervisor}}",
+       "group-suppress-member": "{{GENDER:$1|ancarià dle sopression}}",
        "grouppage-user": "{{ns:project}}:Utent",
        "grouppage-autoconfirmed": "{{ns:project}}:Utent ch'a son convalidasse daspërlor",
        "grouppage-bot": "{{ns:project}}:Trigomiro",
        "grouppage-sysop": "{{ns:project}}:Aministrator",
        "grouppage-bureaucrat": "{{ns:project}}:Mangiapapé",
-       "grouppage-suppress": "{{ns:project}}:Supervisor",
+       "grouppage-suppress": "{{ns:project}}:Fà la sopression",
        "right-read": "Lese le pàgine",
        "right-edit": "Modifiché le pàgine",
        "right-createpage": "Creé dle pàgine (che a son pa dle pàgine ëd discussion)",
        "whatlinkshere": "Pàgine con dj'anliure che a men-o a costa-sì",
        "whatlinkshere-title": "Pàgine ch'a men-o a «$1»",
        "whatlinkshere-page": "Pàgina:",
-       "linkshere": "Le pàgine sì-sota a l'han andrinta dj'anliure che a men-o a '''[[:$1]]''':",
-       "nolinkshere": "A-i é pa gnun-a pàgina che a l'abia dj'anliure che a men-o a '''[[:$1]]'''.",
-       "nolinkshere-ns": "An cost ëspassi nominal-sì a-i é gnun-e pàgine con dj'anliure ch'a men-o a '''[[:$1]]'''.",
+       "linkshere-2": "Le pàgine sì-sota a l'han andrinta dj'anliure che a men-o a '''$1''':",
+       "nolinkshere-2": "A-i é pa gnun-a pàgina che a l'abia dj'anliure che a men-o a '''$1'''.",
+       "nolinkshere-ns-2": "An cost ëspassi nominal-sì a-i é gnun-e pàgine con dj'anliure ch'a men-o a '''$1'''.",
        "isredirect": "ridiression",
        "istemplate": "inclusion",
        "isimage": "anliura a l'archivi",
        "fileduplicatesearch-noresults": "Gnun archivi ciamà «$1» a l'é stàit trovà.",
        "specialpages": "Pàgine Speciaj",
        "specialpages-note-top": "Legenda",
+       "specialpages-note-restricted": "* Pàgine speciaj normaj.\n* <span class=\"mw-specialpagerestricted\">Pàgine speciaj riservà.</span>",
        "specialpages-group-maintenance": "Rapòrt ëd manutension",
        "specialpages-group-other": "Àutre pàgine speciaj",
        "specialpages-group-login": "Intré ant ël sistema / creé un cont",
index c8aa579..4519eca 100644 (file)
        "whatlinkshere": "ایتھے کیدا جوڑ اے",
        "whatlinkshere-title": "او صفے جہڑے \"$1\" نال جڑے نیں",
        "whatlinkshere-page": "صفہ:",
-       "linkshere": "تھلے دتے گۓ صفے اس دے نال جڑدے نے '''[[:$1]]''':",
-       "nolinkshere": "'''[[:$1]]''' دے نال کسے دا جوڑ نہیں",
-       "nolinkshere-ns": "چنے ناں چ کسے صفے دا '''[[:$1]]''' نال جوڑ نئیں۔",
+       "linkshere-2": "تھلے دتے گۓ صفے اس دے نال جڑدے نے '''$1''':",
+       "nolinkshere-2": "'''$1''' دے نال کسے دا جوڑ نہیں",
+       "nolinkshere-ns-2": "چنے ناں چ کسے صفے دا '''$1''' نال جوڑ نئیں۔",
        "isredirect": "ریڈائرکٹ صفہ",
        "istemplate": "ملن",
        "isimage": "مورت دا جوڑ",
        "fileduplicatesearch-result-n": "فائل ''$1'' چ {{PLURAL:$2|1 رلدی نقل|$2 رلدیاں نقلں}} نیں۔",
        "fileduplicatesearch-noresults": "\"$1\" ناں دی کوئی فائل نئیں لبی۔",
        "specialpages": "خاص صفے",
+       "specialpages-note-restricted": "* نارمل خاص صفے.\n* <span class=\"mw-specialpagerestricted\">روکے گۓ خاص صفے.</span>\n* <span class=\"mw-specialpagecached\">کاشے خاص صفے (پرانے ہوگۓ ہون).</span>",
        "specialpages-group-maintenance": "مرمت رپورٹ",
        "specialpages-group-other": "ہور خاص صفے",
        "specialpages-group-login": "لاگان / کھاتہ کھولو",
index c28659a..ba2addf 100644 (file)
        "whatlinkshere": "Ντο δεκνίζ' αδακές",
        "whatlinkshere-title": "Σελίδας ντο συνδέουν ση σελίδαν $1",
        "whatlinkshere-page": "Σελίδαν:",
-       "linkshere": "Αβούτα τα σελίδας δεκνίζνε σο '''[[:$1]]''':",
-       "nolinkshere": "'Κ ευρέθεν σελίδα το δεκνίζ' ση σελίδαν '''[[:$1]]'''.",
+       "linkshere-2": "Αβούτα τα σελίδας δεκνίζνε σο '''$1''':",
+       "nolinkshere-2": "'Κ ευρέθεν σελίδα το δεκνίζ' ση σελίδαν '''$1'''.",
        "isredirect": "σελίδαν διπλού σύνδεσμονος",
        "istemplate": "ενσωμάτωση",
        "isimage": "σύνδεσμον εικόνας",
index 74a5fea..1f6ca9e 100644 (file)
        "whatlinkshere": "Ka autenginna stwi",
        "whatlinkshere-title": "Pāusan autengināntei prei \"$1\"",
        "whatlinkshere-page": "Pāusan:",
-       "linkshere": "Ripīntei pāusai autenginna prei '''[[:$1]]''':",
-       "nolinkshere": "Niaīnan pāusan ni autenginna prei '''[[:$1]]'''.",
-       "nolinkshere-ns": "Niaīnan pāusan ni autenginna prei '''[[:$1]]''' en etrīnktai tītelin plattibin.",
+       "linkshere-2": "Ripīntei pāusai autenginna prei '''$1''':",
+       "nolinkshere-2": "Niaīnan pāusan ni autenginna prei '''$1'''.",
+       "nolinkshere-ns-2": "Niaīnan pāusan ni autenginna prei '''$1''' en etrīnktai tītelin plattibin.",
        "isredirect": "prawesnas pāusan",
        "istemplate": "entensīsenis",
        "isimage": "autengīnsenis prei bildin",
        "fileduplicatesearch-result-1": "Zūrbrukis \"$1\" ni turri idēntiskan kōpijan.",
        "fileduplicatesearch-result-n": "Zūrbrukis \"$1\" turri {{PLURAL:$2|1 idēntiskan kōpijan|$2 idēntiskans kōpijans}}.",
        "specialpages": "Speciālai pāusai",
+       "specialpages-note-restricted": "* Nōrmalai speciālai pāusai.\n* <strong class=\"mw-specialpagerestricted\">Speciālai pāusai sen arāikintan preiēisenin.</strong>",
        "specialpages-group-maintenance": "Kōnserwaciōnis repōrtai",
        "specialpages-group-other": "Kitāi speciālai pāusai",
        "specialpages-group-login": "Enēis / registrīs si",
index d856230..62206cb 100644 (file)
        "whatlinkshere": "د دې مخ تړنې",
        "whatlinkshere-title": "هغه مخونه چې د \"$1\" سره تړنې لري",
        "whatlinkshere-page": "مخ:",
-       "linkshere": "دغه لانديني مخونه د '''[[:$1]]''' سره تړنې لري:",
-       "nolinkshere": "د '''[[:$1]]''' سره هېڅ يو مخ هم تړنې نه لري .",
+       "linkshere-2": "دغه لانديني مخونه د '''$1''' سره تړنې لري:",
+       "nolinkshere-2": "د '''$1''' سره هېڅ يو مخ هم تړنې نه لري .",
        "isredirect": "د مخ گرځونې مخ",
        "istemplate": "ورگډېدنه",
        "isimage": "د دوتنې تړنه",
        "fileduplicatesearch-noresults": "د \"$1\" په نوم دوتنه و نه موندل شوه.",
        "specialpages": "ځانگړي مخونه",
        "specialpages-note-top": "څرگندونې",
+       "specialpages-note-restricted": "* نورماله ځانگړي مخونه.\n* <strong class=\"mw-specialpagerestricted\">محدوده ځانگړي مخونه.</strong>",
        "specialpages-group-maintenance": "د څارنې راپورونه",
        "specialpages-group-other": "نور ځانگړي مخونه",
        "specialpages-group-login": "ننوتل / گڼون جوړول",
index 877184c..4bcde5e 100644 (file)
        "botpasswords-existing": "Senhas de robôs existentes",
        "botpasswords-createnew": "Crie uma nova senha de robô",
        "botpasswords-editexisting": "Editar uma senha de robô existente",
+       "botpasswords-label-needsreset": "(senha precisa ser redefinida)",
        "botpasswords-label-appid": "Nome do robô:",
        "botpasswords-label-create": "Criar",
        "botpasswords-label-update": "Atualizar",
        "botpasswords-restriction-failed": "Restrições de senha de robô evitam esta autenticação.",
        "botpasswords-invalid-name": "O nome de usuário especificado não contém o separador de senha de robô (\"$1\").",
        "botpasswords-not-exist": "O usuário \"$1\" não possui uma senha de robô \"$2\".",
+       "botpasswords-needs-reset": "A senha do robô de nome \"$2\" {{GENDER:$1|do usuário|da usuária}} \"$1\" deve ser redefinida.",
        "resetpass_forbidden": "As senhas não podem ser alteradas",
        "resetpass_forbidden-reason": "Senhas não podem ser alteradas: $1",
        "resetpass-no-info": "Você precisa estar autenticado para acessar esta página diretamente.",
        "subject-preview": "Previsão do assunto/título:",
        "previewerrortext": "Ocorreu um erro ao tentar pré-visualizar suas alterações.",
        "blockedtitle": "O usuário está bloqueado",
-       "blockedtext": "'''O seu nome de usuário ou endereço de IP foi bloqueado.'''\n\nO bloqueio foi realizado por $1.\nO motivo apresentado foi ''$2''.\n\n* Início do bloqueio: $8\n* Expiração do bloqueio: $6\n* Destino do bloqueio: $7\n\nVocê pode contatar $1 ou outro [[{{MediaWiki:Grouppage-sysop}}|administrador]] para discutir sobre o bloqueio.\n\nVocê só poderá utilizar a funcionalidade \"Contatar usuário\" se um endereço de ''e-mail'' válido estiver especificado em suas [[Special:Preferences|preferências de usuário]] e você não tiver sido bloqueado de utilizar tal recurso.\nO seu endereço de IP atual é $3 e a ID de bloqueio é #$5.\nPor favor, inclua todos os detalhes acima em quaisquer tentativas de esclarecimento.",
-       "autoblockedtext": "O seu endereço de IP foi bloqueado de forma automática, uma vez que foi utilizado recentemente por outro usuário, o qual foi bloqueado por $1.\nO motivo apresentado foi:\n\n:''$2''\n\n* Início do bloqueio: $8\n* Expiração do bloqueio: $6\n* Destino do bloqueio: $7\n\nVocê pode contatar $1 ou outro [[{{MediaWiki:Grouppage-sysop}}|administrador]] para discutir sobre o bloqueio.\n\nNote que não poderá utilizar a funcionalidade \"Contatar usuário\" se não possuir uma conta nesta wiki ({{SITENAME}}) com um endereço de ''e-mail'' válido indicado nas suas [[Special:Preferences|preferências de usuário]] ou se tiver sido bloqueado de utilizar tal recurso.\n\nSeu endereço de IP no momento é $3 e sua ID de bloqueio é #$5.\nPor favor, inclua tais dados em qualquer tentativa de esclarecimentos que for realizar.",
+       "blockedtext": "<strong>O seu nome de usuário ou endereço IP foram bloqueados.</strong>\n\nO bloqueio foi realizado por $1.\nO motivo apresentado foi <em>$2</em>.\n\n* Início do bloqueio: $8\n* Expiração do bloqueio: $6\n* Destinatário do bloqueio: $7\n\nPode contactar $1 ou outro [[{{MediaWiki:Grouppage-sysop}}|administrador]] para discutir o bloqueio.\nNote que para utilizar a funcionalidade \"{{int:emailuser}}\" precisa de ter um endereço de e-mail válido nas suas [[Special:Preferences|preferências]] e de não lhe ter sido bloqueado o uso desta funcionalidade.\nO seu endereço IP neste momento é $3 e a identificação (ID) do bloqueio é #$5.\nInclua todos os detalhes acima em quaisquer contatos relacionados com este bloqueio, por favor.",
+       "autoblockedtext": "O seu endereço IP foi bloqueado de forma automática porque foi utilizado recentemente por outro usuário, o qual foi bloqueado por $1.\nO motivo apresentado foi:\n\n:<em>$2</em>\n\n* Início do bloqueio: $8\n* Expiração do bloqueio: $6\n* Destinatário do bloqueio: $7\n\nPode contactar $1 ou outro [[{{MediaWiki:Grouppage-sysop}}|administrador]] para discutir o bloqueio.\n\nNote que para utilizar a funcionalidade \"{{int:emailuser}}\" precisa de ter um endereço de e-mail válido nas suas [[Special:Preferences|preferências]] e de não lhe ter sido bloqueado o uso desta funcionalidade.\n\nO seu endereço IP neste momento é $3 e a identificação (ID) do bloqueio é #$5.\nInclua todos os detalhes acima em quaisquer contatos relacionados com este bloqueio, por favor.",
        "systemblockedtext": "O seu nome de usuário ou endereço IP foram bloqueados automaticamente pelo MediaWiki.\nO motivo fornecido é:\n\n:<em>$2</em>\n\n* Início do bloqueio: $8\n* Expiração do bloqueio: $6\n* Destinatário do bloqueio: $7\n\nO seu endereço IP atual é $3.\nInclua todos os detalhes acima em quaisquer contatos sobre este assunto, por favor.",
        "blockednoreason": "sem motivo especificado",
        "whitelistedittext": "Você precisa $1 para poder editar páginas.",
        "recentchangescount": "Número de edições a apresentar por omissão nas mudanças recentes, nos historiais de páginas e nos registos:",
        "prefs-help-recentchangescount": "Número máximo: 1000",
        "prefs-help-watchlist-token2": "Esta é a senha secreta para o feed da Web com sua lista de tokens vigiados.\nQualquer pessoa que descobrir esta senha será capaz de ler sua lista, então não a compartilhe.\nSe você precisar [[Special:ResetTokens|você pode redefini-lo]].",
-       "prefs-help-tokenmanagement": "Você pode ver e redefinir a chave secreta para sua conta que pode acessar o feed da Web da sua lista de vigilância. Qualquer pessoa que conheça a chave poderá ler sua lista de observação, então não compartilhe.",
+       "prefs-help-tokenmanagement": "Pode ver e repor a chave secreta da sua conta que permite aceder ao feed da sua lista de páginas vigiadas. Qualquer pessoa que conheça a chave será capaz de ler a sua lista de páginas vigiadas, por isso não a partilhe.",
        "savedprefs": "As suas preferências foram salvas.",
        "savedrights": "Os grupos {{GENDER:$1|do usuário|da usuária}} $1 foram gravados.",
        "timezonelegend": "Fuso horário:",
        "prefs-custom-json": "JSON personalizado",
        "prefs-custom-js": "JS personalizado",
        "prefs-common-config": "CSS/JSON/JavaScript compartilhado por todos os temas:",
-       "prefs-reset-intro": "Você pode usar esta página para restaurar as suas preferências para os valores predefinidos do sítio.\nEsta ação não pode ser desfeita.",
+       "prefs-reset-intro": "Pode usar esta página para repor as configurações padrão das preferências.\nAs suas preferências serão modificadas para os valores predefinidos do site.\nEsta operação não pode ser desfeita.",
        "prefs-emailconfirm-label": "Confirmação do e-mail:",
        "youremail": "Seu e-mail:",
        "username": "Nome de {{GENDER:$1|usuário|usuária|usuário(a)}}:",
        "recentchangeslinked-feed": "Mudanças relacionadas",
        "recentchangeslinked-toolbox": "Mudanças relacionadas",
        "recentchangeslinked-title": "Mudanças relacionadas com “$1”",
-       "recentchangeslinked-summary": "Digite um nome de página para ver as alterações nas páginas vinculadas ou a partir dessa página. (Para ver membros de uma categoria, digite Categoria: Nome da categoria). Mudanças nas páginas em [[Special:Watchlist|lista de páginas vigiadas]] são exibidas em <strong>negrito<strong>",
+       "recentchangeslinked-summary": "Introduza o nome de uma página para ver as mudanças a todas as páginas que contêm hiperligações para ela ou para as quais a página fornecida contém hiperligações (para ver as que pertencem a uma categoria, introduza {{ns:category}}:Nome da categoria). As mudanças às suas [[Special:Watchlist|páginas vigiadas]] aparecem a <strong>negrito</strong>.",
        "recentchangeslinked-page": "Nome da página:",
        "recentchangeslinked-to": "Inversamente, mostrar mudanças nas páginas que contêm ligações para esta",
        "recentchanges-page-added-to-category": "[[:$1]]adicionada à categoria",
        "protectedtitles-submit": "Mostrar títulos",
        "listusers": "Lista de usuários",
        "listusers-editsonly": "Mostrar apenas usuários com edições",
+       "listusers-temporarygroupsonly": "Mostrar apenas usuários em grupos de usuários temporários",
        "listusers-creationsort": "Ordenar por data de criação",
        "listusers-desc": "Listar em ordem decrescente",
        "usereditcount": "$1 {{PLURAL:$1|edição|edições}}",
        "apisandbox-dynamic-parameters-add-label": "Parâmetro adicional",
        "apisandbox-dynamic-parameters-add-placeholder": "Nome do parâmetro",
        "apisandbox-dynamic-error-exists": "Um parâmetro chamado \"$1\" já existe.",
+       "apisandbox-templated-parameter-reason": "Este [[Special:ApiHelp/main#main/templatedparams|parâmetro de predefinição]] é oferecido com base {{PLURAL:$1|no valor|nos valores}} de $2.",
        "apisandbox-deprecated-parameters": "Parâmetros obsoletos",
        "apisandbox-fetch-token": "Preencher automaticamente o token",
        "apisandbox-add-multi": "Adicionar",
        "whatlinkshere": "Páginas afluentes",
        "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á afluentes para '''[[:$1]]''' com as condições especificadas.",
-       "nolinkshere-ns": "Não há links para '''[[:$1]]''' no espaço nominal selecionado.",
+       "linkshere-2": "As seguintes páginas possuem links para '''$1''':",
+       "nolinkshere-2": "Não há afluentes para '''$1''' com as condições especificadas.",
+       "nolinkshere-ns-2": "Não há links para '''$1''' no espaço nominal selecionado.",
        "isredirect": "página de redirecionamento",
        "istemplate": "transclusão",
        "isimage": "link para o arquivo",
        "pagedata-title": "Dados de página",
        "pagedata-text": "Esta página fornece uma interface de dados para páginas. Forneça o título da página no URL, usando a sintaxe de subpáginas, por favor.\n* Aplica-se a negociação de conteúdo com base no cabeçalho Accept do seu cliente. Isto significa que os dados da página serão fornecidos no formato preferido do seu cliente.",
        "pagedata-not-acceptable": "Nenhum formato correspondente encontrado. Tipos MIME suportados: $1",
-       "pagedata-bad-title": "Título inválido: $1."
+       "pagedata-bad-title": "Título inválido: $1.",
+       "unregistered-user-config": "Por razões de segurança as subpáginas de utilizador com JavaScript, CSS e JSON não podem ser carregadas para usuários não registados.",
+       "passwordpolicies": "Políticas de senha",
+       "passwordpolicies-summary": "Esta é uma lista da senha efetiva para os grupos de usuários definidos neste wiki.",
+       "passwordpolicies-group": "Grupo",
+       "passwordpolicies-policies": "Políticas",
+       "passwordpolicies-policy-minimalpasswordlength": "A senha deve ter pelo menos $1 {{PLURAL:$1|caráter|caracteres}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "A senha deve ter pelo menos $1 {{PLURAL:$1|caráter|caracteres}} para poder entrar",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Senha não pode ser o mesmo que nome de usuário",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "A senha não pode corresponder senhas especificamente na lista negra",
+       "passwordpolicies-policy-maximalpasswordlength": "A senha deve ser menor que $1 {{PLURAL:$1|caráter|caracteres}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "A senha não pode {{PLURAL:$1|ser a mais popular|estar na lista das $1 palavras-passe mais populares}}"
 }
index 9a67d6f..011b3cf 100644 (file)
@@ -76,7 +76,8 @@
                        "Ngl2016",
                        "RadiX",
                        "MokaAkashiyaPT",
-                       "Athena in Wonderland"
+                       "Athena in Wonderland",
+                       "Fitoschido"
                ]
        },
        "tog-underline": "Sublinhar hiperligações:",
        "botpasswords-existing": "Palavras-passe de robô existentes",
        "botpasswords-createnew": "Criar uma nova palavra-passe para robô",
        "botpasswords-editexisting": "Editar uma palavra-passe de robô existente",
+       "botpasswords-label-needsreset": "(a palavra-passe precisa ser redefinida)",
        "botpasswords-label-appid": "Nome do robô:",
        "botpasswords-label-create": "Criar",
        "botpasswords-label-update": "Atualizar",
        "botpasswords-restriction-failed": "Restrições da palavra-passe de robô impedem esta autenticação.",
        "botpasswords-invalid-name": "O nome de utilizador especificado não contém o separador de palavra-passe de robô (\"$1\").",
        "botpasswords-not-exist": "O utilizador \"$1\" não tem uma palavra-passe para o robô chamado \"$2\".",
+       "botpasswords-needs-reset": "A palavra-passe do robô de nome \"$2\" {{GENDER:$1|do utilizador|da utilizadora}} \"$1\" deve ser redefinida.",
        "resetpass_forbidden": "As palavras-passe não podem ser alteradas",
        "resetpass_forbidden-reason": "As palavras-passe não podem ser alteradas: $1",
        "resetpass-no-info": "Precisa de iniciar sessão para aceder diretamente a esta página.",
        "subject-preview": "Antevisão do assunto:",
        "previewerrortext": "Ocorreu um erro enquanto tentava antever as suas alterações.",
        "blockedtitle": "O utilizador está bloqueado",
-       "blockedtext": "<strong>O seu nome de utilizador ou endereço IP foram bloqueados.</strong>\n\nO bloqueio foi realizado por $1.\nO motivo apresentado foi <em>$2</em>.\n\n* Início do bloqueio: $8\n* Expiração do bloqueio: $6\n* Destinatário do bloqueio: $7\n\nPode contactar $1 ou outro [[{{MediaWiki:Grouppage-sysop}}|administrador]] para discutir o bloqueio.\nNote que para utilizar a funcionalidade \"Contactar utilizador\" precisa de ter um endereço de correio eletrónico válido nas suas [[Special:Preferences|preferências]] e de não lhe ter sido bloqueado o uso desta funcionalidade.\nO seu endereço IP neste momento é $3 e a identificação (ID) do bloqueio é #$5.\nInclua todos os detalhes acima em quaisquer contactos relacionados com este bloqueio, por favor.",
-       "autoblockedtext": "O seu endereço IP foi bloqueado de forma automática porque foi utilizado recentemente por outro utilizador, o qual foi bloqueado por $1.\nO motivo apresentado foi:\n\n:<em>$2</em>\n\n* Início do bloqueio: $8\n* Expiração do bloqueio: $6\n* Destinatário do bloqueio: $7\n\nPode contactar $1 ou outro [[{{MediaWiki:Grouppage-sysop}}|administrador]] para discutir o bloqueio.\n\nNote que para utilizar a funcionalidade \"Contactar utilizador\" precisa de ter um endereço de correio eletrónico válido nas suas [[Special:Preferences|preferências]] e de não lhe ter sido bloqueado o uso desta funcionalidade.\n\nO seu endereço IP neste momento é $3 e a identificação (ID) do bloqueio é #$5.\nInclua todos os detalhes acima em quaisquer contactos relacionados com este bloqueio, por favor.",
+       "blockedtext": "<strong>O seu nome de utilizador ou endereço IP foram bloqueados.</strong>\n\nO bloqueio foi realizado por $1.\nO motivo apresentado foi <em>$2</em>.\n\n* Início do bloqueio: $8\n* Expiração do bloqueio: $6\n* Destinatário do bloqueio: $7\n\nPode contactar $1 ou outro [[{{MediaWiki:Grouppage-sysop}}|administrador]] para discutir o bloqueio.\nNote que para utilizar a funcionalidade \"{{int:emailuser}}\" precisa de ter um endereço de correio eletrónico válido nas suas [[Special:Preferences|preferências]] e de não lhe ter sido bloqueado o uso desta funcionalidade.\nO seu endereço IP neste momento é $3 e a identificação (ID) do bloqueio é #$5.\nInclua todos os detalhes acima em quaisquer contactos relacionados com este bloqueio, por favor.",
+       "autoblockedtext": "O seu endereço IP foi bloqueado de forma automática porque foi utilizado recentemente por outro utilizador, o qual foi bloqueado por $1.\nO motivo apresentado foi:\n\n:<em>$2</em>\n\n* Início do bloqueio: $8\n* Expiração do bloqueio: $6\n* Destinatário do bloqueio: $7\n\nPode contactar $1 ou outro [[{{MediaWiki:Grouppage-sysop}}|administrador]] para discutir o bloqueio.\n\nNote que para utilizar a funcionalidade \"{{int:emailuser}}\" precisa de ter um endereço de correio eletrónico válido nas suas [[Special:Preferences|preferências]] e de não lhe ter sido bloqueado o uso desta funcionalidade.\n\nO seu endereço IP neste momento é $3 e a identificação (ID) do bloqueio é #$5.\nInclua todos os detalhes acima em quaisquer contactos relacionados com este bloqueio, por favor.",
        "systemblockedtext": "O seu nome de utilizador ou endereço IP foram bloqueados automaticamente pelo MediaWiki.\nO motivo fornecido é:\n\n:<em>$2</em>\n\n* Início do bloqueio: $8\n* Expiração do bloqueio: $6\n* Destinatário do bloqueio: $7\n\nO seu endereço IP atual é $3.\nInclua todos os detalhes acima em quaisquer contactos sobre este assunto, por favor.",
        "blockednoreason": "sem motivo especificado",
        "whitelistedittext": "Precisa de $1 para poder editar páginas.",
        "recentchangeslinked-feed": "Alterações relacionadas",
        "recentchangeslinked-toolbox": "Alterações relacionadas",
        "recentchangeslinked-title": "Alterações relacionadas com \"$1\"",
-       "recentchangeslinked-summary": "Introduza o nome de uma página para ver as mudanças a todas as páginas que contêm hiperligações para ela ou para as quais a página fornecida contém hiperligações (para ver as que pertencem a uma categoria, introduza Categoria:Nome da categoria). As mudanças às suas [[Special:Watchlist|páginas vigiadas]] aparecem a <strong>negrito</strong>.",
+       "recentchangeslinked-summary": "Introduza o nome de uma página para ver as mudanças a todas as páginas que contêm hiperligações para ela ou para as quais a página fornecida contém hiperligações (para ver as que pertencem a uma categoria, introduza {{ns:category}}:Nome da categoria). As mudanças às suas [[Special:Watchlist|páginas vigiadas]] aparecem a <strong>negrito</strong>.",
        "recentchangeslinked-page": "Nome da página:",
        "recentchangeslinked-to": "Inversamente, mostrar mudanças às páginas que contêm hiperligações para esta",
        "recentchanges-page-added-to-category": "[[:$1]] foi adicionada à categoria",
        "protectedtitles-submit": "Mostrar títulos",
        "listusers": "Utilizadores",
        "listusers-editsonly": "Mostrar apenas utilizadores com edições",
+       "listusers-temporarygroupsonly": "Mostrar apenas os utilizadores em grupos de utilizadores temporários",
        "listusers-creationsort": "Ordenar por data de criação",
        "listusers-desc": "Ordenar de forma decrescente",
        "usereditcount": "$1 {{PLURAL:$1|edição|edições}}",
        "apisandbox-dynamic-parameters-add-label": "Adicionar parâmetro:",
        "apisandbox-dynamic-parameters-add-placeholder": "Nome do parâmetro",
        "apisandbox-dynamic-error-exists": "Um parâmetro com o nome \"$1\" já existe.",
+       "apisandbox-templated-parameter-reason": "Este [[Special:ApiHelp/main#main/templatedparams|parâmetro modelado]] é oferecido com base {{PLURAL:$1|no valor|nos valores}} de $2.",
        "apisandbox-deprecated-parameters": "Parâmetros obsoletos",
        "apisandbox-fetch-token": "Auto-preencher o token",
        "apisandbox-add-multi": "Adicionar",
        "trackingcategories-disabled": "A categoria está desativada.",
        "mailnologin": "Não existe endereço de envio",
        "mailnologintext": "Precisa de estar [[Special:UserLogin|autenticado]] e ter um endereço de correio válido nas suas [[Special:Preferences|preferências]], para poder enviar correio eletrónico a outros utilizadores.",
-       "emailuser": "Enviar correio eletrónico a {{GENDER:{{BASEPAGENAME}}|este utilizador|esta utilizadora|este(a) utilizador(a)}}",
+       "emailuser": "Enviar correio eletrónico a {{GENDER:{{BASEPAGENAME}}|este utilizador|esta utilizadora}}",
        "emailuser-title-target": "Enviar correio eletrónico a {{GENDER:$1|este utilizador|esta utilizadora}}",
        "emailuser-title-notarget": "Enviar correio eletrónico ao utilizador",
        "emailpagetext": "Pode usar o formulário abaixo para enviar uma mensagem por correio eletrónico para {{GENDER:$1|este utilizador|esta utilizadora}}.\nO endereço de correio que introduziu nas [[Special:Preferences|suas preferências]] irá aparecer no campo do remetente da mensagem \"De:\", para que o destinatário lhe possa responder diretamente.",
        "whatlinkshere": "Páginas afluentes",
        "whatlinkshere-title": "Páginas com hiperligações para \"$1\"",
        "whatlinkshere-page": "Página:",
-       "linkshere": "As seguintes páginas têm hiperligações para <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Não existem afluentes para <strong>[[:$1]]</strong> com as condições especificadas.",
-       "nolinkshere-ns": "Não existem afluentes para <strong>[[:$1]]</strong> no espaço nominal selecionado.",
+       "linkshere-2": "As seguintes páginas têm hiperligações para <strong>$1</strong>:",
+       "nolinkshere-2": "Não existem afluentes para <strong>$1</strong> com as condições especificadas.",
+       "nolinkshere-ns-2": "Não existem afluentes para <strong>$1</strong> no espaço nominal selecionado.",
        "isredirect": "página de redirecionamento",
        "istemplate": "inclusão",
        "isimage": "hiperligação para ficheiro",
        "pagedata-title": "Dados de página",
        "pagedata-text": "Esta página fornece uma interface de dados para páginas. Forneça o título da página no URL, usando a sintaxe de subpáginas, por favor.\n* Aplica-se a negociação de conteúdo com base no cabeçalho Accept do seu cliente. Isto significa que os dados da página serão fornecidos no formato preferido do seu cliente.",
        "pagedata-not-acceptable": "Não foi encontrado nenhum formato correspondente. Tipos MIME suportados: $1",
-       "pagedata-bad-title": "Título inválido: $1."
+       "pagedata-bad-title": "Título inválido: $1.",
+       "unregistered-user-config": "Por razões de segurança as subpáginas de utilizador com JavaScript, CSS e JSON não podem ser carregadas para utilizadores não registados.",
+       "passwordpolicies": "Regras para palavras-passe",
+       "passwordpolicies-summary": "Esta lista contém as normas efetivas para palavras-passe dos grupos de utilizadores definidos nesta wiki.",
+       "passwordpolicies-group": "Grupo",
+       "passwordpolicies-policies": "Normas e recomendações",
+       "passwordpolicies-policy-minimalpasswordlength": "A palavra-passe tem de ter pelo menos $1 {{PLURAL:$1|carácter|caracteres}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "A palavra-passe tem de ter pelo menos $1 {{PLURAL:$1|carácter|caracteres}} para poder iniciar sessão",
+       "passwordpolicies-policy-passwordcannotmatchusername": "A palavra-passe não pode ser igual ao nome de utilizador",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "A palavra-passe não pode corresponder às especificamente bloqueadas pela lista negra",
+       "passwordpolicies-policy-maximalpasswordlength": "A palavra-passe tem de ter menos de $1 {{PLURAL:$1|carácter|caracteres}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "A palavra-passe não pode {{PLURAL:$1|ser a mais popular|estar na lista das $1 palavras-passe mais populares}}"
 }
index 17e26ae..139c91c 100644 (file)
                        "Trizek (WMF)",
                        "Acamicamacaraca",
                        "Avatar6",
-                       "Akapochtli"
+                       "Akapochtli",
+                       "ديفيد"
                ]
        },
        "sidebar": "{{notranslate}}",
        "pool-servererror": "Error message. Parameters:\n* $1 - list of server addresses\n\nSee e.g. {{msg-mw|Poolcounter-desc}} (and the Pool Counter extension in general) for translation hints for “pool counter service”.",
        "poolcounter-usage-error": "Used as error message. Parameters:\n* $1 - non-localized string describing usage mistake.",
        "aboutsite": "Used as the label of the link that appears at the footer of every page on the wiki (in most of  the skins) and leads to the page that contains the site description. The link target is {{msg-mw|aboutpage}}.\n\n[[mw:Manual:Interface/Aboutsite|MediaWiki manual]].\n\n{{doc-important|Do not change <nowiki>{{SITENAME}}</nowiki>.}}\n\n{{Identical|About}}",
-       "aboutpage": "Used as the target of the link that appears at the footer of every page on the wiki (in most of  the skins) and leads to the page that contains the site description. Therefore the content should be the same with the page name of the site description page. Only the message in the [[mw:Manual:$wgLanguageCode|site language]]  ([[MediaWiki:Aboutpage]]) is used. The link label is {{msg-mw|aboutsite}}.\n\n{{doc-important|Do not translate \"Project:\" part, for this is the namespace prefix.}}",
+       "aboutpage": "{{doc-important|Do not translate \"Project:\" part, for this is the namespace prefix.}}\n\nUsed as the target of the link that appears at the footer of every page on the wiki (in most of  the skins) and leads to the page that contains the site description. Therefore the content should be the same with the page name of the site description page. Only the message in the [[mw:Manual:$wgLanguageCode|site language]]  ([[MediaWiki:Aboutpage]]) is used. The link label is {{msg-mw|aboutsite}}.",
        "copyright": "Parameters:\n* $1 - license name\n'''See also'''\n* {{msg-mw|Mobile-frontend-copyright}}",
        "copyrightpage": "{{doc-important|Do not change <nowiki>{{ns:project}}</nowiki>}}\n\n{{Identical|Copyright}}",
        "currentevents": "Standard link in the sidebar, for news.\n\nSee also {{msg-mw|Currentevents-url}} for the link URL.\n\nSee also:\n* {{msg-mw|Currentevents}}\n* {{msg-mw|Accesskey-n-currentevents}}\n* {{msg-mw|Tooltip-n-currentevents}}",
        "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-category-desc": "Expansion depth exceeded category description. Shown on [[Special:TrackingCategories]].\n\nSee also:\n* {{msg-mw|Expansion-depth-exceeded-category}}",
        "expansion-depth-exceeded-warning": "Error message shown when a page exceeded the [[meta:Help:Expansion_depth|expansion depth limit]] of the preprocessor.\n\nParameters:\n* $1 - (Unused) the value of the depth limit\n* $2 - (Unused) the value of the max depth limit\nSee also:\n* {{msg-mw|Expansion-depth-exceeded-category}}",
-       "parser-unstrip-loop-warning": "{{Doc-important|Do not translate function name <code>unstrip</code>.}}\nThis error is shown when a parser extension tag such as <code><nowiki><pre></nowiki></code> includes a reference to itself in its own output.\n\nThe reference must be to the exact same invocation of the tag at the same location in the source, merely writing <code><nowiki><pre><pre></pre></pre></nowiki></code> will not do it.\n\nThis is usually impossible and unlikely to happen by accident, so translation is not essential.\n\n\"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.\n\nSee also:\n*{{msg-mw|Parser-unstrip-recursion-limit}}",
-       "unstrip-depth-warning": "{{doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is shown when the recursion limit for nested parser extension tags is exceeded.\n\nThis warning may be encountered due to input text like <code><nowiki><ref><ref><ref>...</ref></ref></ref></nowiki></code>.\n\nParameters:\n* $1 - the depth limit\n\n\"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.\n\nSee also:\n* {{msg-mw|Parser-unstrip-loop-warning}}",
-       "unstrip-depth-category": "This message is used as the category name of a [[mw:Help:Tracking categories|tracking category]] in which pages are placed automatically if the unstrip recursion depth limit is exceeded.",
-       "unstrip-size-warning": "{{doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is shown when the maximum expansion size for nested parser extension tags is exceeded.\n\nParameters:\n* $1 - the size limit\n\n\"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.\n\nSee also:\n* {{msg-mw|Parser-unstrip-loop-warning}}",
-       "unstrip-size-category": "This message is used as the category name of a [[mw:Help:Tracking categories|tracking category]] in which pages are placed automatically if the unstrip expansion size limit is exceeded.",
+       "parser-unstrip-loop-warning": "{{Doc-important|Do not translate function name <code>unstrip</code>.}}\nThis error is shown when a parser extension tag such as <code><nowiki><pre></nowiki></code> includes a reference to itself in its own output.\n\nThe reference must be to the exact same invocation of the tag at the same location in the source, merely writing <code><nowiki><pre><pre></pre></pre></nowiki></code> will not do it.\n\nThis is usually impossible and unlikely to happen by accident, so translation is not essential.\n\n\"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.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-depth}}\n*{{msg-mw|Limitreport-unstrip-size}}\n*{{msg-mw|Unstrip-depth-category}}\n*{{msg-mw|Unstrip-depth-warning}}\n*{{msg-mw|Unstrip-size-category}}\n*{{msg-mw|Unstrip-size-warning}}",
+       "unstrip-depth-warning": "{{doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is shown when the recursion limit for nested parser extension tags is exceeded.\n\nThis warning may be encountered due to input text like <code><nowiki><ref><ref><ref>...</ref></ref></ref></nowiki></code>.\n\nParameters:\n* $1 - the depth limit\n\n\"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.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-depth}}\n*{{msg-mw|Limitreport-unstrip-size}}\n*{{msg-mw|Parser-unstrip-loop-warning}}\n*{{msg-mw|Unstrip-depth-category}}\n*{{msg-mw|Unstrip-size-category}}\n*{{msg-mw|Unstrip-size-warning}}",
+       "unstrip-depth-category": "{{Doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is used as the category name of a [[mw:Help:Tracking categories|tracking category]] in which pages are placed automatically if the unstrip recursion depth limit is exceeded.\n\n\"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.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-depth}}\n*{{msg-mw|Limitreport-unstrip-size}}\n*{{msg-mw|Parser-unstrip-loop-warning}}\n*{{msg-mw|Unstrip-depth-warning}}\n*{{msg-mw|Unstrip-size-category}}\n*{{msg-mw|Unstrip-size-warning}}",
+       "unstrip-size-warning": "{{doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is shown when the maximum expansion size for nested parser extension tags is exceeded.\n\nParameters:\n* $1 - the size limit\n\n\"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.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-depth}}\n*{{msg-mw|Limitreport-unstrip-size}}\n*{{msg-mw|Parser-unstrip-loop-warning}}\n*{{msg-mw|Unstrip-depth-category}}\n*{{msg-mw|Unstrip-depth-warning}}\n*{{msg-mw|Unstrip-size-category}}",
+       "unstrip-size-category": "{{Doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is used as the category name of a [[mw:Help:Tracking categories|tracking category]] in which pages are placed automatically if the unstrip expansion size limit is exceeded.\n\n\"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.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-depth}}\n*{{msg-mw|Limitreport-unstrip-size}}\n*{{msg-mw|Parser-unstrip-loop-warning}}\n*{{msg-mw|Unstrip-depth-category}}\n*{{msg-mw|Unstrip-depth-warning}}\n*{{msg-mw|Unstrip-size-warning}}",
        "converter-manual-rule-error": "Used as error message when a manual conversion rule for the [[mw:Language_converter|language converter]] has errors. For example it's not using the correct syntax, or not supplying text in all variants.",
        "undo-success": "Text on special page to confirm edit revert. You arrive on this page by clicking on the \"undo\" link on a revision history special page.\n\n{{Identical|Undo}}",
        "undo-failure": "Message appears if an attempt to revert an edit by clicking the \"undo\" link on the page history fails.\n\nSee also:\n* {{msg-mw|Undo-norev}}\n* {{msg-mw|Undo-nochange}}\n{{Identical|Undo}}",
        "listusers": "{{doc-special|ListUsers}}",
        "listusers-summary": "{{notranslate}}\nThe summary displayed at the top of [[Special:Listusers]]. [[mw:Manual:Interface/Special pages summary|mw manual]].",
        "listusers-editsonly": "Option in [[Special:ListUsers]].",
+       "listusers-temporarygroupsonly": "Option in [[Special:ListUsers]].",
        "listusers-creationsort": "Option in [[Special:ListUsers]].",
        "listusers-desc": "Used as label for the checkbox on [[Special:ListUsers]].",
        "usereditcount": "Shown behind every username on [[Special:ListUsers]]. Parameters:\n* $1 - number of edits",
        "apisandbox-dynamic-parameters-add-label": "JavaScript label for the widget to add a new arbitrary parameter.",
        "apisandbox-dynamic-parameters-add-placeholder": "JavaScript text field placeholder for the widget to add a new arbitrary parameter.",
        "apisandbox-dynamic-error-exists": "Displayed as an error message from JavaScript when trying to add a new arbitrary parameter with a name that already exists. Parameters:\n* $1 - Parameter name that failed.",
+       "apisandbox-templated-parameter-reason": "Displayed (from JavaScript) on each instance of a templated parameter.\n\nParameters:\n* $1 - Number of fields in $2.\n* $2 - List of targeted fields, combined using {{msg-mw|comma-separator}} and {{msg-mw|and}}.",
        "apisandbox-deprecated-parameters": "JavaScript button label and fieldset legend for separating deprecated parameters in the UI.",
        "apisandbox-fetch-token": "Label for the button that fetches a CSRF token.",
        "apisandbox-add-multi": "Label for the button to add another value to a field that accepts multiple values\n{{Identical|Add}}",
        "whatlinkshere-title": "Title of the special page [[Special:WhatLinksHere]]. This page appears when you click on the 'What links here' button in the toolbox. $1 is the name of the page concerned.",
        "whatlinkshere-summary": "{{doc-specialpagesummary|whatlinkshere}}",
        "whatlinkshere-page": "{{Identical|Page}}",
-       "linkshere": "This message is the header line of the [[Special:WhatLinksHere/$1]] page generated by clicking \"What links here\" in the sidebar toolbox.\n\nIt is followed by a navigation bar built using {{msg-mw|Viewprevnext}}.\n\nParameters:\n* $1 - page title",
-       "nolinkshere": "Used in [[Special:WhatLinksHere]] if empty. Parameters:\n* $1 - page title\nSee also:\n* {{msg-mw|Nolinkshere-ns}}",
-       "nolinkshere-ns": "Used in [[Special:WhatLinksHere]] if empty. Parameters:\n* $1 - page title\nSee also:\n* {{msg-mw|Nolinkshere}}",
+       "linkshere-2": "This message is the header line of the [[Special:WhatLinksHere/$1]] page generated by clicking \"What links here\" in the sidebar toolbox.\n\nIt is followed by a navigation bar built using {{msg-mw|Viewprevnext}}.\n\nParameters:\n* $1 - HTML link to the page.",
+       "nolinkshere-2": "Used in [[Special:WhatLinksHere]] if empty. Parameters:\n* $1 - HTML link to the page\nSee also:\n* {{msg-mw|Nolinkshere-ns-html}}",
+       "nolinkshere-ns-2": "Used in [[Special:WhatLinksHere]] if empty. Parameters:\n* $1 - HTML link to the page\nSee also:\n* {{msg-mw|Nolinkshere-html}}",
        "isredirect": "Displayed in [[Special:WhatLinksHere]] (see [{{fullurl:Special:WhatLinksHere/Project:Translator|hidelinks=1}} Special:WhatLinksHere/Project:Translator] for example).\n\n{{Identical|Redirect page}}",
        "istemplate": "Means that a page (a template, specifically) is used as <code><nowiki>{{Page name}}</nowiki></code>.\nDisplayed in [[Special:WhatLinksHere]] (see [[Special:WhatLinksHere/Template:New portal]] for example).\nIf you are not sure how to translate this term, think of something like \"inclusion\", \"embedding\", or \"insertion\".\n{{Identical|Transclusion}}",
        "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).\n{{Identical|File link}}",
        "limitreport-expansiondepth-value": "{{optional}}\nFormat for the \"Highest expansion depth\" row in the limit report table.\n\nParameters:\n* $1 - the depth\n* $2 - the maximum",
        "limitreport-expensivefunctioncount": "Label for the \"Expensive parser function count\" row in the limit report table",
        "limitreport-expensivefunctioncount-value": "{{optional}}\nFormat for the \"Expensive parser function count\" row in the limit report table.\n\nParameters:\n* $1 - the usage\n* $2 - the maximum",
-       "limitreport-unstrip-depth": "Label for the \"unstrip depth\" row in the limit report table. \"Unstrip\" is a MediaWiki function name and as such does not need to be translated.",
+       "limitreport-unstrip-depth": "{{Doc-important|Do not translate function name <code>unstrip</code>.}}\nLabel for the \"unstrip depth\" row in the limit report table.\n\n\"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.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-size}}\n*{{msg-mw|Parser-unstrip-loop-warning}}\n*{{msg-mw|Unstrip-depth-category}}\n*{{msg-mw|Unstrip-depth-warning}}\n*{{msg-mw|Unstrip-size-category}}\n*{{msg-mw|Unstrip-size-warning}}",
        "limitreport-unstrip-depth-value": "{{optional}}\nFormat for the \"unstrip depth\" row in the limit report table.\n\nParameters:\n* $1 - the usage\n* $2 - the maximum",
-       "limitreport-unstrip-size": "Label for the \"unstrip size\" row in the limit report table. \"Unstrip\" is a MediaWiki function name and as such does not need to be translated.",
+       "limitreport-unstrip-size": "{{Doc-important|Do not translate function name <code>unstrip</code>.}}\nLabel for the \"unstrip size\" row in the limit report table.\n\n\"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.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-depth}}\n*{{msg-mw|Parser-unstrip-loop-warning}}\n*{{msg-mw|Unstrip-depth-category}}\n*{{msg-mw|Unstrip-depth-warning}}\n*{{msg-mw|Unstrip-size-category}}\n*{{msg-mw|Unstrip-size-warning}}",
        "limitreport-unstrip-size-value": "Format for the \"unstrip size\" row in the limit report table.\n\nParameters:\n* $1 - the usage\n* $2 - the maximum\n{{Identical|Byte}}",
        "expandtemplates": "{{doc-special|ExpandTemplates}}\nThe name of the [[mw:Extension:ExpandTemplates|Expand Templates extension]].",
        "expand_templates_intro": "This is the explanation given in the heading of the [[Special:ExpandTemplates]] page; it describes its functionality to the users.\nFor more information, see [[mw:Extension:ExpandTemplates]]",
        "mediastatistics-header-3d": "Header on [[Special:MediaStatistics]] for file types that are in the 3D category. Includes STL files.",
        "mediastatistics-header-total": "Header on [[Special:MediaStatistics]] for a summary of all file types.",
        "json-warn-trailing-comma": "A warning message notifying that JSON text was automatically corrected by removing erroneous commas.\n\nParameters:\n* $1 - number of commas that were removed\n{{Related|Json-error}}",
-       "json-error-unknown": "User error message when there’s an unknown error.\n\nThis error is shown if we received an unexpected value from PHP. See http://php.net/manual/en/function.json-last-error.php\n\nParameters:\n* $1 - integer error code\n{{Related|Json-error}}",
-       "json-error-depth": "User error message when the maximum stack depth is exceeded.\nSee http://php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
-       "json-error-state-mismatch": "User error message when underflow or the modes mismatch.\n\n'''Underflow''': A data-processing error arising when the absolute value of a computed quantity is smaller than the limits of precision of the computing device, retaining at least one significant digit.\n\nSee http://php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
-       "json-error-ctrl-char": "User error message when an unexpected control character has been found.\nSee http://php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
-       "json-error-syntax": "User error message when there is a syntax error; a malformed JSON.\nSee http://php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}\n{{Identical|Syntax error}}",
-       "json-error-utf8": "User error message when there are malformed UTF-8 characters, possibly incorrectly encoded.\nSee http://php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
-       "json-error-recursion": "PHP JSON encoding/decoding error. See http://php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
-       "json-error-inf-or-nan": "PHP JSON encoding/decoding error. See http://php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
-       "json-error-unsupported-type": "PHP JSON encoding/decoding error. See http://php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
+       "json-error-unknown": "User error message when there’s an unknown error.\n\nThis error is shown if we received an unexpected value from PHP. See https://secure.php.net/manual/en/function.json-last-error.php\n\nParameters:\n* $1 - integer error code\n{{Related|Json-error}}",
+       "json-error-depth": "User error message when the maximum stack depth is exceeded.\nSee https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
+       "json-error-state-mismatch": "User error message when underflow or the modes mismatch.\n\n'''Underflow''': A data-processing error arising when the absolute value of a computed quantity is smaller than the limits of precision of the computing device, retaining at least one significant digit.\n\nSee https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
+       "json-error-ctrl-char": "User error message when an unexpected control character has been found.\nSee https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
+       "json-error-syntax": "User error message when there is a syntax error; a malformed JSON.\nSee https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}\n{{Identical|Syntax error}}",
+       "json-error-utf8": "User error message when there are malformed UTF-8 characters, possibly incorrectly encoded.\nSee https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
+       "json-error-recursion": "PHP JSON encoding/decoding error. See https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
+       "json-error-inf-or-nan": "PHP JSON encoding/decoding error. See https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
+       "json-error-unsupported-type": "PHP JSON encoding/decoding error. See https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
        "headline-anchor-title": "Title tooltip for the section anchor symbol, which is a link to the current section. Can be interpreted both as a noun (\"this is a link\") or as a verb (\"use this to link\").",
        "special-characters-group-latin": "This is the name of a script, or alphabet, not a language.",
        "special-characters-group-latinextended": "The name of the Latin Extended character set.",
        "pagedata-title": "Title shown on the special page when a form or text is presented",
        "pagedata-text": "Error shown when none of the formats acceptable to the client is supported (HTTP error 406). Parameters:\n* $1 - the list of supported MIME types",
        "pagedata-not-acceptable": "No matching format found. Supported MIME types: $1",
-       "pagedata-bad-title": "Error shown when the requested title is invalid. Parameters:\n* $1: the malformed ID"
+       "pagedata-bad-title": "Error shown when the requested title is invalid. Parameters:\n* $1: the malformed ID",
+       "unregistered-user-config": "Shown when viewing a user JS, CSS or JSON subpage with ?action=raw&ctype=<mime type> where there is no such user. It is shown as a paragraph after a header saying 'Forbidden'.",
+       "passwordpolicies": "The name of the special page [[Special:PasswordPolicies]].",
+       "passwordpolicies-summary": "The description used on [[Special:PasswordPolicies]].\n\nRefers to {{msg-mw|Passwordpolicies-helppage}}.",
+       "passwordpolicies-group": "The title of the column in the table, about user groups (like you are in the ''translator'' group).\n\n{{Identical|Group}}\n{{Related|Passwordpolicies}}",
+       "passwordpolicies-policies": "The title of the column in the table, about password policies.\n{{Related|Passwordpolicies}}",
+       "passwordpolicies-policy-display": "{{optional}}\nParameters:\n* $1 - the text from the \"passwordpolicies-policy-...\" messages, i.e. {{msg-mw|passwordpolicies-policy-minimalpasswordlength}}\n* $2 - the name of this password policy",
+       "passwordpolicies-policy-minimalpasswordlength": "Password policy that enforces a minimum number of characters a password must be. $1 - minimum number of characters that a password can be",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Password policy that enforces a minimum number of characters a password must be to be able to login to the wiki. $1 - minimum number of characters that a password can be to be able to login",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Password policy that enforces that the password of the account cannot be the same as the username",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Password policy that enforces that passwords are not on a list of blacklisted passwords (often previously used during MediaWiki automated testing)",
+       "passwordpolicies-policy-maximalpasswordlength": "Password policy that enforces a maximum number of characters a password must be. $1 - maximum number of characters that a password can be",
+       "passwordpolicies-policy-passwordcannotbepopular": "Password policy that enforces that a password is not in a list of $1 number of \"popular\" passwords. $1 - number of popular passwords the password will be checked against"
 }
index b4baa72..9d090ba 100644 (file)
        "whatlinkshere": "Kayman t'inkimuq",
        "whatlinkshere-title": "$1 sutiyuq p'anqaman t'inkimuqkuna",
        "whatlinkshere-page": "P'anqa:",
-       "linkshere": "'''[[:$1]]''' sutiyuq p'anqamanqa kay qatiq p'anqakunam t'inkimun:",
-       "nolinkshere": "Manam kachkanchu '''[[:$1]]'''-man t'inkiq p'anqa.",
-       "nolinkshere-ns": "Manam kachkanchu '''[[:$1]]'''-man t'inkiq p'anqa akllasqa suti k'itipi.",
+       "linkshere-2": "'''$1''' sutiyuq p'anqamanqa kay qatiq p'anqakunam t'inkimun:",
+       "nolinkshere-2": "Manam kachkanchu '''$1'''-man t'inkiq p'anqa.",
+       "nolinkshere-ns-2": "Manam kachkanchu '''$1'''-man t'inkiq p'anqa akllasqa suti k'itipi.",
        "isredirect": "pusapusqa p'anqa",
        "istemplate": "ch'aqtasqa",
        "isimage": "willañiqi t'inki",
        "fileduplicatesearch-noresults": "\"$1\" sutiyuq willañiqiqa manam tarisqachu.",
        "specialpages": "Sapaq p'anqakuna",
        "specialpages-note-top": "Sut'ichana",
+       "specialpages-note-restricted": "* Sapsipaq sapaq p'anqakuna.\n* <span class=\"mw-specialpagerestricted\">Sapaqkunallapaq sapaq p'anqakuna.</span>",
        "specialpages-group-maintenance": "Hatalliy willaykuna",
        "specialpages-group-other": "Huk sapaq p'anqakuna",
        "specialpages-group-login": "Yaykuy / rakiqunata kamariy",
index 8507825..0f24732 100644 (file)
        "whatlinkshere": "Kayman tinkikuna",
        "whatlinkshere-title": "$1-man tinkiyuk pankakuna",
        "whatlinkshere-page": "Panka:",
-       "linkshere": "Chay pankakunaka '''[[:$1]]'''-man tinkiyukmi kan:",
-       "nolinkshere": "Mana pankaka '''[[:$1]]'''-man tinkikunchu.",
+       "linkshere-2": "Chay pankakunaka '''$1'''-man tinkiyukmi kan:",
+       "nolinkshere-2": "Mana pankaka '''$1'''-man tinkikunchu.",
        "isredirect": "pushashka panka",
        "istemplate": "Ukupi tiyak panka (''inclusión'')",
        "isimage": "rikcha tinki",
index 905a618..a9adaa9 100644 (file)
        "whatlinkshere": "ⵎⵉⵏ ⵉⵇⵇⵏⴻⵏ ⵖⵔ ⴷⴰ",
        "whatlinkshere-title": "Tasniwin id-izedyen ɣar \"$1\"",
        "whatlinkshere-page": "ⵜⴰⵙⵏⴰ:",
-       "linkshere": "Tasna ya tzedi ɣa '''[[:$1]]''':",
-       "nolinkshere": "war tlli ca n Tasna tqqen-d da '''[[:$1]]'''.",
+       "linkshere-2": "Tasna ya tzedi ɣa '''$1''':",
+       "nolinkshere-2": "war tlli ca n Tasna tqqen-d da '''$1'''.",
        "isredirect": "Tasna n (redirect)",
        "istemplate": "Asidef",
        "isimage": "amaqqan usatul",
index b89d6f8..0a894b1 100644 (file)
        "whatlinkshere": "Colliaziuns sin questa pagina",
        "whatlinkshere-title": "Paginas ch'èn colliadas cun \"$1\"",
        "whatlinkshere-page": "Pagina:",
-       "linkshere": "Suandantas paginas èn colliadas cun '''[[:$1]]''':",
-       "nolinkshere": "Naginas paginas èn colliadas cun '''[[:$1]]'''.",
-       "nolinkshere-ns": "Naginas paginas èn colliadas cun '''[[:$1]]''' en il tip da pagina tschernì.",
+       "linkshere-2": "Suandantas paginas èn colliadas cun '''$1''':",
+       "nolinkshere-2": "Naginas paginas èn colliadas cun '''$1'''.",
+       "nolinkshere-ns-2": "Naginas paginas èn colliadas cun '''$1''' en il tip da pagina tschernì.",
        "isredirect": "Pagina che renviescha",
        "istemplate": "Integraziun da models",
        "isimage": "colliaziun da datoteca",
        "fileduplicatesearch-noresults": "Betg chattà ina datoteca cun il num \"$1\".",
        "specialpages": "Paginas spezialas",
        "specialpages-note-top": "Legenda",
+       "specialpages-note-restricted": "* Paginas spezialas normalas.\n* <span class=\"mw-specialpagerestricted\">Paginas spezialas restrenschidas.</span>",
        "specialpages-group-maintenance": "Rapports da mantegnamant",
        "specialpages-group-other": "Autras paginas spezialas",
        "specialpages-group-login": "S'annunziar / crear in conto",
index fc930a1..939d795 100644 (file)
        "whatlinkshere": "Ce trimite aici",
        "whatlinkshere-title": "Pagini care conțin legături spre „$1”",
        "whatlinkshere-page": "Pagină:",
-       "linkshere": "Următoarele pagini conțin legături către <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Nici o pagină nu trimite la '''[[:$1]]'''.",
-       "nolinkshere-ns": "Nici o pagină din spațiul de nume ales nu trimite la '''[[:$1]]'''.",
+       "linkshere-2": "Următoarele pagini conțin legături către <strong>$1</strong>:",
+       "nolinkshere-2": "Nici o pagină nu trimite la '''$1'''.",
+       "nolinkshere-ns-2": "Nici o pagină din spațiul de nume ales nu trimite la '''$1'''.",
        "isredirect": "pagină de redirecționare",
        "istemplate": "prin includerea formatului",
        "isimage": "legătură către fișier",
index b5677df..cb006f0 100644 (file)
@@ -9,7 +9,8 @@
                        "C.R.",
                        "Macofe",
                        "Purodha",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Ruthven"
                ]
        },
        "tog-underline": "Collegaminde sottolinèate:",
        "subject-preview": "Andeprime de l'oggette:",
        "previewerrortext": "'N'errore ha assute quanne ste facive l'andeprime de le cangiaminde.",
        "blockedtitle": "L'utende è blocchete",
-       "blockedtext": "''''U nome de l'utende o l'indirizze IP ha state bloccate.'''\n\n'U blocche ha state fatte da $1.\n'U mutive date jè ''$2''.\n\n* 'U Blocche accumenze: $8\n* 'U Blocche spicce: $6\n* Tipe de blocche: $7\n\nTu puè condatta $1 o n'otre [[{{MediaWiki:Grouppage-sysop}}|amministratore]] pe 'ngazzarte sus a 'u blocche.\nTu non ge puè ausà 'u strumende 'manne 'na mail a stu utende' senza ca mitte n'indirizze e-mail valide jndr'à le\n[[Special:Preferences|preferenze tue]] e ce è state blocchete sus 'a l'use sue.\nL'IP ca tine mò jè $3 e 'u codece d'u blocche jè #$5.\nPe piacere mitte ste doje 'mbormaziune ce manne 'na richieste de sblocche.",
+       "blockedtext": "<strong>'U nome de l'utende o l'indirizze IP ha state bloccate.</strong>\n\n'U blocche ha state fatte da $1.\n'U mutive date jè <em>$2</em>.\n\n* 'U Blocche accumenze: $8\n* 'U Blocche spicce: $6\n* Tipe de blocche: $7\n\nTu puè condatta $1 o n'otre [[{{MediaWiki:Grouppage-sysop}}|amministratore]] pe 'ngazzarte sus a 'u blocche.\nTu non ge puè ausà 'u strumende \"{{int:emailuser}}\" senza ca mitte n'indirizze email valide jndr'à le\n[[Special:Preferences|preferenze tune]] e ce è state bloccate sus a l'use sue.\nL'IP ca tine mò jè $3 e 'u codece d'u blocche jè #$5.\nPe piacere mitte ste doje 'mbormaziune ce manne 'na richieste de sblocche.",
        "autoblockedtext": "L'indirizze IP tue ha state automaticamende blocchete purcè ha state ausete da n'otre utende, ca avère state blocchete da $1.\n'U mutive date jè 'u seguende:\n\n:''$2''\n\n* Inizie d'u blocche: $8\n* Scadenze d'u blocche: $6\n* Blocche 'ndise: $7\n\nTu puè cundattà $1 o une de l'otre [[{{MediaWiki:Grouppage-sysop}}|amministrature]] pe parà de stu probbleme.\n\nVide Bbuene ca tu non ge puè ausà 'a funziona \"manne n'e-mail a stu utende\" senze ca tu tìne 'n'indirizze e-mail valide e reggistrete jndr'à seziona [[Special:Preferences|me piace accussì]] e tu non ge sinde blocchete da ausarle.\n\nL'indirizze IP corrende jè $3, e 'u codece d'u blocche jè #$5.\nPe piacere mitte tutte le dettaglie ca ponne essere utile pe le richieste tue.",
        "blockednoreason": "nisciune mutive",
        "whitelistedittext": "Tu ha $1 pàggene da cangià.",
        "recentchangeslinked-feed": "Cangiaminde culleghete",
        "recentchangeslinked-toolbox": "Cangiaminde culleghete",
        "recentchangeslinked-title": "Cangiaminde culleghete a \"$1\"",
-       "recentchangeslinked-summary": "Mitte 'u nome de 'na pàgene pe 'ndrucà le cangiaminde a le pàggene ca sò collegate o ca appondane a sta pàgene. (Pe 'ndrucà le membre de 'na categorije, mitte Categoria:Nome d'a categorije). Le cangiaminde a le pàggene ca stonne jndr'à l'elenghe de [[Special:Watchlist|le Pàggene condrollate]] stonne in <strong>grascette</strong>.",
+       "recentchangeslinked-summary": "Mitte 'u nome de 'na pàgene pe 'ndrucà le cangiaminde a le pàggene ca sò collegate o ca appondane a sta pàgene. (Pe 'ndrucà le membre de 'na categorije, mitte {{ns:category}}:Nome d'a categorije). Le cangiaminde a le pàggene ca stonne jndr'à l'elenghe de [[Special:Watchlist|le Pàggene condrollate]] stonne in <strong>grascette</strong>.",
        "recentchangeslinked-page": "Nome d'a vôsce:",
        "recentchangeslinked-to": "Fa vedè le cangiaminde de le pàggene colleghete a 'na certa pàgene",
        "recentchanges-page-added-to-category": "[[:$1]] aggiunde a categorije",
        "whatlinkshere": "Appondene aqquà",
        "whatlinkshere-title": "Pàggene ca appondene a \"$1\"",
        "whatlinkshere-page": "Pàgene:",
-       "linkshere": "Le pàggene ca avènene appondene a '''[[:$1]]''':",
-       "nolinkshere": "Nisciuna pàgene apponde a '''[[:$1]]'''.",
-       "nolinkshere-ns": "Nisciuna pàgene apponde a '''[[:$1]]''' jndr'à 'u namespace scacchiete.",
+       "linkshere-2": "Le pàggene ca avènene appondene a '''$1''':",
+       "nolinkshere-2": "Nisciuna pàgene apponde a '''$1'''.",
+       "nolinkshere-ns-2": "Nisciuna pàgene apponde a '''$1''' jndr'à 'u namespace scacchiete.",
        "isredirect": "pàgene de ridirezionamende",
        "istemplate": "inclusione",
        "isimage": "collegamende a 'u file",
index 99d0548..25063c8 100644 (file)
                        "Movses",
                        "Patrick Star",
                        "Happy13241",
-                       "Vcohen"
+                       "Vcohen",
+                       "AttemptToCallNil"
                ]
        },
        "tog-underline": "Подчёркивание ссылок:",
        "pagetitle-view-mainpage": "{{SITENAME}}",
        "backlinksubtitle": "← $1",
        "retrievedfrom": "Источник — «$1»",
-       "youhavenewmessages": "Вы получили $1 ($2).",
+       "youhavenewmessages": "{{PLURAL:$3|Вы получили}} $1 ($2).",
        "youhavenewmessagesfromusers": "{{PLURAL:$4|Вы получили}} $1 от {{PLURAL:$3|$3 участника|$3 участников|1=другого участника}} ($2).",
        "youhavenewmessagesmanyusers": "Вы получили $1 от множества пользователей ($2).",
        "newmessageslinkplural": "{{PLURAL:$1|1=новое сообщение|999=новые сообщения}}",
        "botpasswords-existing": "Существующие пароли бота",
        "botpasswords-createnew": "Создать новый пароль бота",
        "botpasswords-editexisting": "Редактировать существующий пароль бота",
+       "botpasswords-label-needsreset": "(пароль должен быть сброшен)",
        "botpasswords-label-appid": "Название бота:",
        "botpasswords-label-create": "Создать",
        "botpasswords-label-update": "Обновить",
        "botpasswords-restriction-failed": "Из-за ограничений, связанных с паролем бота, вход не произведён.",
        "botpasswords-invalid-name": "Указанное имя участника не содержит разделителя для пароля бота («$1»).",
        "botpasswords-not-exist": "У участника «$1» нет пароля для бота с названием «$2».",
+       "botpasswords-needs-reset": "Пароль для бота «$1» {{GENDER:$2|участника|участницы}} «$2» должен быть сброшен.",
        "resetpass_forbidden": "Пароль не может быть изменён",
        "resetpass_forbidden-reason": "Пароли не могут быть изменены: $1",
        "resetpass-no-info": "Чтобы обращаться непосредственно к этой странице, вам следует представиться системе.",
        "subject-preview": "Предпросмотр темы/заголовка:",
        "previewerrortext": "При попытке отобразить предварительный просмотр ваших изменений произошла ошибка.",
        "blockedtitle": "Участник заблокирован",
-       "blockedtext": "<strong>Ваша учётная запись или IP-адрес заблокированы.</strong>\n\nБлокировка произведена администратором $1.\nУказана следующая причина: «<em>$2</em>».\n\n* Начало блокировки: $8\n* Окончание блокировки: $6\n* Цель блокировки: $7\n\nВы можете связаться с $1 или любым другим [[{{MediaWiki:Grouppage-sysop}}|администратором]], чтобы обсудить блокировку.\nОбратите внимание, что вы не сможете использовать функцию «письмо участнику», если в своих [[Special:Preferences|персональных настройках]] не задали или не подтвердили корректный адрес электронной почты, или если ваша блокировка включает запрет отправки писем подобным образом.\nВаш IP-адрес — $3, идентификатор блокировки — $5.\nПожалуйста, указывайте эти сведения в любых своих обращениях.",
-       "autoblockedtext": "Ваш IP-адрес автоматически заблокирован в связи с тем, что он ранее использовался кем-то из участников, заблокированных {{GENDER:$4|участником|участницей}} $1. \nБыла указана следующая причина блокировки:\n\n: «$2».\n\n* Начало блокировки: $8\n* Окончание блокировки: $6\n* Цель блокировки: $7\n\nВы можете связаться с $1 или любым другим [[{{MediaWiki:Grouppage-sysop}}|администратором]], чтобы обсудить блокировку.\n\nОбратите внимание, что вы не сможете использовать функцию «письмо участнику», если в своих [[Special:Preferences|персональных настройках]] не задали или не подтвердили корректный адрес электронной почты, или если ваша блокировка включает запрет отправки писем подобным образом.\n\nВаш IP-адрес — $3, идентификатор блокировки — #$5.\nПожалуйста, указывайте эти сведения в любых своих обращениях.",
+       "blockedtext": "<strong>Ваша учётная запись или IP-адрес заблокированы.</strong>\n\nБлокировка произведена администратором $1.\nУказана следующая причина: <em>$2</em>.\n\n* Начало блокировки: $8\n* Окончание блокировки: $6\n* Цель блокировки: $7\n\nВы можете связаться с $1 или любым другим [[{{MediaWiki:Grouppage-sysop}}|администратором]], чтобы обсудить блокировку.\nОбратите внимание, что вы не сможете использовать функцию «{{int:emailuser}}», если в своих [[Special:Preferences|персональных настройках]] не задали или не подтвердили корректный адрес электронной почты, или если ваша блокировка включает запрет отправки писем подобным образом.\nВаш IP-адрес — $3, идентификатор блокировки — $5.\nПожалуйста, указывайте эти сведения в любых своих обращениях.",
+       "autoblockedtext": "Ваш IP-адрес автоматически заблокирован в связи с тем, что он ранее использовался кем-то из участников, заблокированных администратором $1. \nБыла указана следующая причина блокировки:\n\n: «$2».\n\n* Начало блокировки: $8\n* Окончание блокировки: $6\n* Цель блокировки: $7\n\nВы можете связаться с $1 или любым другим [[{{MediaWiki:Grouppage-sysop}}|администратором]], чтобы обсудить блокировку.\n\nОбратите внимание, что вы не сможете использовать функцию «{{int:emailuser}}», если в своих [[Special:Preferences|персональных настройках]] не задали или не подтвердили корректный адрес электронной почты, или если ваша блокировка включает запрет отправки писем подобным образом.\n\nВаш IP-адрес — $3, идентификатор блокировки — #$5.\nПожалуйста, указывайте эти сведения в любых своих обращениях.",
        "systemblockedtext": "Ваше имя участника или IP-адрес были автоматически заблокированы MediaWiki.\nУказана следующая причина:\n\n:<em>$2</em>\n\n* Начало блокировки: $8\n* Окончание блокировки: $6\n* Цель блокировки: $7\n\nВаш текущий IP-адрес $3.\nПожалуйста, указывайте все эти сведения в любых своих обращениях.",
        "blockednoreason": "причина не указана",
        "whitelistedittext": "Вы должны $1 для изменения страниц.",
        "nextn-title": "{{PLURAL:$1|Следующая $1 запись|Следующие $1 записи|Следующие $1 записей}}",
        "shown-title": "Показывать $1 {{PLURAL:$1|запись|записи|записей}} на странице",
        "viewprevnext": "Просмотреть ($1 {{int:pipe-separator}} $2) ($3)",
-       "searchmenu-exists": "'''В этой вики есть страница «[[:$1]]»'''",
+       "searchmenu-exists": "<strong>В этой вики есть страница «[[:$1]]».</strong> {{PLURAL:$2|0=|См. также другие результаты поиска.}}",
        "searchmenu-new": "<strong>Создать страницу «[[:$1]]» в этом вики-проекте!</strong>\n{{PLURAL:$2|0=|См. также страницу, найденную по результатами вашего поиска.|См. также найденные результаты поиска.}}",
        "searchprofile-articles": "Основные страницы",
        "searchprofile-images": "Мультимедиа",
        "rcfilters-restore-default-filters": "Восстановить фильтры по умолчанию",
        "rcfilters-clear-all-filters": "Очистить все фильтры",
        "rcfilters-show-new-changes": "Последние изменения",
-       "rcfilters-search-placeholder": "Ð\98зменениÑ\8f Ñ\84илÑ\8cÑ\82Ñ\80ов (используйте меню или ищите по названию фильтра)",
+       "rcfilters-search-placeholder": "ФилÑ\8cÑ\82Ñ\80оваÑ\82Ñ\8c Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ\8f (используйте меню или ищите по названию фильтра)",
        "rcfilters-invalid-filter": "Недопустимый фильтр",
        "rcfilters-empty-filter": "Нет активных фильтров. Показываются все правки.",
        "rcfilters-filterlist-title": "Фильтры",
        "protectedtitles-submit": "Показывать заголовки",
        "listusers": "Список участников",
        "listusers-editsonly": "Показать только тех участников, кто сделал хотя бы одну правку",
+       "listusers-temporarygroupsonly": "Показывать только участников, временно отнесённых к группе участников",
        "listusers-creationsort": "Упорядочить по дате создания",
        "listusers-desc": "Сортировать в обратном порядке",
        "usereditcount": "$1 {{PLURAL:$1|правка|правки|правок}}",
        "apisandbox-dynamic-parameters-add-label": "Добавить параметр:",
        "apisandbox-dynamic-parameters-add-placeholder": "Имя параметра",
        "apisandbox-dynamic-error-exists": "Параметр с именем «$1» уже существует.",
+       "apisandbox-templated-parameter-reason": "Этот [[Special:ApiHelp/main#main/templatedparams|шаблонный параметр]] предлагается на основе {{PLURAL:$1|значения|значений}} $2.",
        "apisandbox-deprecated-parameters": "Устаревшие параметры",
        "apisandbox-fetch-token": "Автозаполнение токена",
        "apisandbox-add-multi": "Добавить",
        "whatlinkshere": "Ссылки сюда",
        "whatlinkshere-title": "Страницы, ссылающиеся на «$1»",
        "whatlinkshere-page": "Страница:",
-       "linkshere": "Следующие страницы ссылаются на «'''[[:$1]]'''»:",
-       "nolinkshere": "На страницу '''[[:$1]]''' отсутствуют ссылки с других страниц.",
-       "nolinkshere-ns": "В выбранном пространстве имён нет страниц, ссылающихся на '''[[:$1]]'''.",
+       "linkshere-2": "Следующие страницы ссылаются на «'''$1'''»:",
+       "nolinkshere-2": "На страницу '''$1''' отсутствуют ссылки с других страниц.",
+       "nolinkshere-ns-2": "В выбранном пространстве имён нет страниц, ссылающихся на '''$1'''.",
        "isredirect": "страница-перенаправление",
        "istemplate": "включение",
        "isimage": "файловая ссылка",
        "movenosubpage": "У этой страницы нет подстраниц.",
        "movereason": "Причина:",
        "revertmove": "возврат",
-       "delete_and_move_text": "Страница с именем «[[:$1]]» уже существует. \nХотите удалить её, чтобы сделать возможным переименование?",
+       "delete_and_move_text": "ЦелеваÑ\8f Ñ\81траница с именем «[[:$1]]» уже существует. \nХотите удалить её, чтобы сделать возможным переименование?",
        "delete_and_move_confirm": "Да, удалить эту страницу",
        "delete_and_move_reason": "Удалено для возможности переименования «[[$1]]»",
        "selfmove": "Невозможно переименовать страницу: исходное и новое имя страницы совпадают.",
        "tag-mw-changed-redirect-target-description": "Правки, которые изменяют цель перенаправления",
        "tag-mw-blank": "очистка",
        "tag-mw-blank-description": "Правки, очищающие страницу",
-       "tag-mw-replace": "заменено",
+       "tag-mw-replace": "замена",
        "tag-mw-replace-description": "Правки, которые удаляют более 90 % содержимого страницы",
        "tag-mw-rollback": "откат",
        "tag-mw-rollback-description": "Правки, которые откатывают предыдущие правки по нажатию ссылки отката",
        "limitreport-expensivefunctioncount-value": "$1/$2",
        "limitreport-unstrip-depth": "Глубинная рекурсия Unstrip",
        "limitreport-unstrip-depth-value": "$1/$2",
-       "limitreport-unstrip-size": "Ð\9fоÑ\81ле Ñ\80аÑ\81Ñ\88иÑ\80ениÑ\8f Ñ\80азмеÑ\80 Unstrip",
+       "limitreport-unstrip-size": "РазмеÑ\80 Unstrip Ð¿Ð¾Ñ\81ле Ñ\80аÑ\81кÑ\80Ñ\8bÑ\82иÑ\8f Ð²ÐºÐ»Ñ\8eÑ\87ений",
        "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|байт|байта|байт}}",
        "expandtemplates": "Развёртка шаблонов",
        "expand_templates_intro": "Эта служебная страница преобразует текст, рекурсивно разворачивая все шаблоны в нём.\nТакже развёртке подвергаются функции парсера\n<code><nowiki>{{#language:…}}</nowiki></code> и переменные вида\n<code><nowiki>{{CURRENTDAY}}</nowiki></code> — в общем, всё внутри двойных фигурных скобок.",
        "mediastatistics-header-audio": "Аудио",
        "mediastatistics-header-video": "Видео",
        "mediastatistics-header-multimedia": "Мультимедиа",
-       "mediastatistics-header-office": "Ð\9eÑ\84иÑ\81нÑ\8bе",
+       "mediastatistics-header-office": "Ð\94окÑ\83менÑ\82Ñ\8b",
        "mediastatistics-header-text": "Текстовые",
        "mediastatistics-header-executable": "Исполняемые",
        "mediastatistics-header-archive": "Сжатые форматы",
        "pagedata-title": "Данные страницы",
        "pagedata-text": "Эта страница предоставляет интерфейс к данным страниц. Пожалуйста, введите заголовок страницы в URL, используя синтаксис подстраниц.\n* Согласование содержимого применяется основываясь на заголовке Accept вашего клиента. Это означает, что данные страницы будут предоставлены в формате, предпочитаемом вашим клиентом.",
        "pagedata-not-acceptable": "Соответствующий формат не найден. Поддерживаемые MIME-типы: $1",
-       "pagedata-bad-title": "Некорректный заголовок: $1."
+       "pagedata-bad-title": "Некорректный заголовок: $1.",
+       "unregistered-user-config": "По соображениям безопасности пользовательские подстраницы JavaScript, CSS и JSON не могут быть загружены для незарегистрированных участников.",
+       "passwordpolicies": "Политика паролей",
+       "passwordpolicies-summary": "На этой странице перечисляются действующие на этой вики ограничения на пароли участников. Ограничения, действующие для какого-либо участника, зависят от групп, в которые он входит.",
+       "passwordpolicies-group": "Группа",
+       "passwordpolicies-policies": "Ограничения",
+       "passwordpolicies-policy-minimalpasswordlength": "Пароль должен быть длиной не менее $1 {{PLURAL:$1|символа|символов}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Пароль должен быть длиной не менее $1 {{PLURAL:$1|символа|символов}}, чтобы участник мог войти в свою учётную запись",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Пароль не может совпадать с названием учётной записи",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Пароль не может совпадать ни с одним паролем, внесённым в чёрный список",
+       "passwordpolicies-policy-maximalpasswordlength": "Пароль должен быть короче $1 {{PLURAL:$1|символа|символов}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "Пароль не может соответствовать {{PLURAL:$1|самому часто используемому паролю|какому-либо из $1 самых часто используемых паролей}}"
 }
index fc487f7..0b1f038 100644 (file)
        "whatlinkshere": "Одказы на тоту сторінку",
        "whatlinkshere-title": "Сторінкы, што ся одказують на \"$1\"",
        "whatlinkshere-page": "Сторінка:",
-       "linkshere": "Наслїдуючі сторінкы ся одказують на '''[[:$1]]''':",
-       "nolinkshere": "Жадна сторінка на '''[[:$1]]''' не одказує.",
-       "nolinkshere-ns": "У выбранім просторї назв на '''[[:$1]]''' не одказує жадна сторінка.",
+       "linkshere-2": "Наслїдуючі сторінкы ся одказують на '''$1''':",
+       "nolinkshere-2": "Жадна сторінка на '''$1''' не одказує.",
+       "nolinkshere-ns-2": "У выбранім просторї назв на '''$1''' не одказує жадна сторінка.",
        "isredirect": "сторінка напрямлена",
        "istemplate": "вложіня",
        "isimage": "Одказ на файл",
        "fileduplicatesearch-noresults": "Файл з назвов «$1» ненайдженый.",
        "specialpages": "Шпеціалны сторінкы",
        "specialpages-note-top": "Леґенда",
+       "specialpages-note-restricted": "* Звычайны шпеціалны сторінкы.\n* <span class=\"mw-specialpagerestricted\">Шпеціалны сторінкы з&nbsp;обмедженым приступом</span>\n* <span class=\"mw-specialpagecached\">Кешованы шпеціалны сторінкы</span>",
        "specialpages-group-maintenance": "Технічны репорты",
        "specialpages-group-other": "Іншы",
        "specialpages-group-login": "Приголошіня / створїня конта",
index 857ba29..6b9a08a 100644 (file)
        "whatlinkshere": "अनेन सह सम्बद्धाः",
        "whatlinkshere-title": "\"$1\" सम्बद्धानि पृष्ठानि",
        "whatlinkshere-page": "पृष्ठम्:",
-       "linkshere": "'''[[:$1]]''' इत्यनेन सह अधो लिखितानां पृष्ठानां परिसन्धिं करोतु:",
-       "nolinkshere": "'''[[:$1]]''' इत्यनेन सह न किमपि पृष्ठं परिसन्धितम्",
-       "nolinkshere-ns": "चितनामस्थानात्  '''[[:$1]]''' इत्येनं योजनयोग्यं पृष्ठं नास्ति  ।",
+       "linkshere-2": "'''$1''' इत्यनेन सह अधो लिखितानां पृष्ठानां परिसन्धिं करोतु:",
+       "nolinkshere-2": "'''$1''' इत्यनेन सह न किमपि पृष्ठं परिसन्धितम्",
+       "nolinkshere-ns-2": "चितनामस्थानात्  '''$1''' इत्येनं योजनयोग्यं पृष्ठं नास्ति  ।",
        "isredirect": "अनुप्रेषण-पृष्ठम्",
        "istemplate": "अन्यलेखभागः (transclusion)",
        "isimage": "सञ्चिकासम्बन्धः",
        "fileduplicatesearch-noresults": "\"$1\" इति नाम्ना सञ्चिका न दृष्टा ।",
        "specialpages": "विशिष्टपृष्ठानि",
        "specialpages-note-top": "तालिका",
+       "specialpages-note-restricted": "* विशिष्टपृष्ठानि । \n* <span class=\"mw-specialpagerestricted\"> प्रतिबन्धितानि विशिष्टपृष्ठानि ।</span>",
        "specialpages-group-maintenance": "निर्वहणवृत्तानि ।",
        "specialpages-group-other": "अन्यविशेषपुटानि ।",
        "specialpages-group-login": "प्रविश्यताम् / लेखा सृज्यताम्",
index 3f6a245..3dc7eb0 100644 (file)
        "whatlinkshere": "Манна сигэнэллэр",
        "whatlinkshere-title": "Сирэй манна сигэнэр \"$1\"",
        "whatlinkshere-page": "Сирэй:",
-       "linkshere": "'''[[:$1]]''' билэҕэ манна көрдөрүллүбүт сирэйдэр сигэнэллэр:",
-       "nolinkshere": "'''[[:$1]]''' сирэйгэ сигэнэр сирэйдэр суохтар.",
-       "nolinkshere-ns": "Талыллыбыт бөлөххө (namespace) бу '''[[:$1]]''' сирэйгэ сигэнэр сирэйдэр суохтар.",
+       "linkshere-2": "'''$1''' билэҕэ манна көрдөрүллүбүт сирэйдэр сигэнэллэр:",
+       "nolinkshere-2": "'''$1''' сирэйгэ сигэнэр сирэйдэр суохтар.",
+       "nolinkshere-ns-2": "Талыллыбыт бөлөххө (namespace) бу '''$1''' сирэйгэ сигэнэр сирэйдэр суохтар.",
        "isredirect": "көлбөрүтэр сирэй",
        "istemplate": "иһинээҕи",
        "isimage": "билэ сигэтэ",
index 65f27f6..16618df 100644 (file)
        "userlogin-helplink2": "ᱵᱚᱞᱚᱜ ᱠᱷᱟᱹᱛᱤᱨ ᱜᱚᱸᱲᱚᱸ",
        "userlogin-createanother": "ᱮᱴᱟᱜ ᱠᱷᱟᱛᱟ ᱛᱮᱭᱟᱨᱢᱮ",
        "createacct-emailrequired": "ᱤᱢᱮᱞ ᱵᱩᱴᱟᱹ",
-       "createacct-emailoptional": "Email ᱴᱷᱤᱠᱱᱟ (ᱵᱟᱹᱲᱛᱤᱛᱮ)",
-       "createacct-email-ph": "ᱟᱢᱟᱜ email ᱴᱷᱤᱠᱱᱟ ᱵᱚᱞᱚᱭᱢᱮ",
+       "createacct-emailoptional": "ᱤᱢᱮᱞ ᱴᱷᱤᱠᱱᱟ (ᱟᱢᱠᱩᱥᱤ)",
+       "createacct-email-ph": "ᱟᱢᱟᱜ ᱤᱢᱮᱞ ᱵᱩᱴᱟᱹ ᱟᱫᱮᱨᱢᱮ",
        "createacct-another-email-ph": "ᱤᱢᱮᱞ ᱵᱩᱴᱟᱹ ᱟᱫᱮᱨᱢᱮ",
        "createaccountmail": "E-mail hotete",
        "createacct-realname": "ᱥᱚᱛ ᱧᱩᱛᱩᱢ (ᱚᱯᱥᱱᱟᱞ)",
        "createacct-another-submit": "ᱠᱷᱟᱛᱟ ᱛᱮᱭᱟᱨᱢᱮ",
        "createacct-continue-submit": "ᱠᱷᱟᱛᱟ ᱛᱮᱭᱟᱨ ᱛᱚᱝᱜᱮᱢᱮ",
        "createacct-another-continue-submit": "ᱠᱷᱟᱛᱟ ᱛᱮᱭᱟᱨ ᱛᱚᱝᱜᱮᱢᱮ",
-       "createacct-benefit-heading": "{{SITENAME}} ᱟᱢ ᱞᱮᱠᱟᱱ ᱦᱚᱲ ᱦᱚᱛᱮᱛᱮ ᱛᱮᱭᱟᱨ ᱟᱠᱟᱱ᱾",
+       "createacct-benefit-heading": "{{SITENAME}} á±«á±\9a á±\9fá±¢ á±\9eᱮᱠá±\9fá±± á±¦á±\9aá±² á±¦á±\9aá±\9bá±®á±\9bá±® á±\9bᱮᱭá±\9fᱨ á±\9fá± á±\9fᱱ᱾",
        "createacct-benefit-body1": "{{PLURAL:$1|ᱥᱟᱯᱲᱟᱣ|ᱥᱟᱯᱲᱟᱣᱠᱚ}}",
        "createacct-benefit-body2": "{{PLURAL:$1|ᱥᱟᱦᱴᱟ|ᱥᱟᱦᱴᱟᱠᱳ}}",
        "createacct-benefit-body3": "ᱱᱮᱛᱟᱨ {{PLURAL:$1|ᱮᱱᱮᱢᱤᱭᱟᱹ|ᱮᱱᱮᱢᱤᱭᱟᱹᱠᱚ}}",
        "summary-preview": "ᱜᱩᱴ ᱠᱟᱛᱷᱟ ᱩᱱᱩᱫᱩᱜ:",
        "subject-preview": "ᱜᱩᱴᱠᱟᱛᱷᱟ ᱩᱱᱩᱫᱩᱜ:",
        "blockedtitle": "ᱵᱮᱵᱷᱟᱨᱤᱡ ᱫᱚ ᱮᱥᱮᱫ ᱚᱪᱚᱣᱟᱠᱟᱱᱟᱭ",
-       "blockedtext": "<strong>ᱟᱢᱟᱜ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱧᱩᱛᱩᱢ ᱟᱨᱵᱟᱝ IP ᱵᱩᱴᱟᱹ ᱫᱚ ᱵᱚᱸᱫᱽ ᱟᱠᱟᱱᱟ ᱾ </strong>\n\nᱱᱚᱶᱟ ᱵᱚᱸᱫᱽ ᱫᱚ $1 ᱫᱟᱨᱟᱭᱛᱮ ᱦᱩᱭᱟᱠᱱᱟ ᱾\nᱱᱚᱶᱟ ᱨᱮᱱᱟᱜ ᱚᱡᱮ ᱫᱚ ᱮᱢᱮᱱᱟ <em>$2</em>.\n\n* ᱵᱚᱸᱫᱽ ᱮᱦᱚᱵ: $8\n* ᱵᱚᱸᱫᱽ ᱢᱩᱪᱟᱹᱫ: $6\n* ᱟᱥᱟᱦᱟᱱ ᱵᱚᱸᱫᱽᱠᱚ: $7\n\nᱟᱢ $1 ᱮᱢ ᱥᱟᱹᱜᱟᱹᱭ ᱫᱟᱲᱮᱭᱟᱭᱟ ᱵᱟᱝᱠᱷᱟᱱ ᱮᱴᱟᱜ [[{{MediaWiki:Grouppage-sysop}}|ᱟᱰᱢᱤᱱᱤᱥᱴᱨᱮᱴᱚᱨ]] ᱵᱚᱸᱫᱽ ᱵᱟᱵᱚᱫᱽ ᱛᱮ ᱜᱟᱞᱚᱪ ᱞᱟᱹᱜᱤᱫ ᱾\nᱟᱢ ᱵᱟᱢ ᱵᱮᱵᱷᱟᱨ ᱫᱟᱲᱮᱭᱟᱜ \"email this user\" ᱥᱩᱵᱤᱫᱷᱟ ᱡᱚᱛᱷᱟᱛ ᱤᱢᱮᱞ ᱵᱩᱴᱟᱹ ᱛᱟᱢ ᱵᱟᱝ ᱛᱟᱦᱮᱸᱱ ᱠᱷᱟᱱ ᱟᱨ ᱱᱚᱶᱟ ᱫᱚ ᱪᱤᱱᱦᱟᱹᱣ-ᱟ [[Special:Preferences|ᱠᱷᱟᱛᱟ ᱧᱮᱞᱚᱚᱜ]] ᱠᱷᱚᱱ ᱟᱨ ᱟᱢ ᱫᱚ ᱵᱟᱢ ᱵᱚᱸᱫᱽ ᱟᱠᱟᱱᱟ ᱱᱚᱶᱟ ᱵᱮᱵᱷᱟᱨ ᱠᱷᱚᱱ ᱾\nᱟᱢᱟᱜ ᱱᱤᱛᱚᱜᱟᱜ IP ᱵᱩᱴᱟᱹ ᱫᱚ $3, ᱟᱨ ᱵᱚᱸᱫᱽ ID ᱫᱚ #$5  \nᱫᱟᱭᱟᱠᱟᱛᱮ ᱥᱮᱞᱮᱫᱽ ᱢᱮ ᱪᱮᱛᱟᱱᱟᱜ ᱠᱟᱛᱷᱟᱠᱚ ᱡᱚᱛᱚ ᱞᱮᱠᱟᱱ ᱠᱩᱠᱞᱤ ᱨᱮ ᱾",
+       "blockedtext": "<strong>ᱟᱢᱟᱜ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱧᱩᱛᱩᱢ ᱟᱨᱵᱟᱝ IP ᱵᱩᱴᱟᱹ ᱫᱚ ᱵᱚᱸᱫᱽ ᱟᱠᱟᱱᱟ ᱾ </strong>\n\nᱱᱚᱶᱟ ᱵᱚᱸᱫᱽ ᱫᱚ $1 ᱫᱟᱨᱟᱭᱛᱮ ᱦᱩᱭᱟᱠᱱᱟ ᱾\nᱱᱚᱶᱟ ᱨᱮᱱᱟᱜ ᱚᱡᱮ ᱫᱚ ᱮᱢᱮᱱᱟ <em>$2</em>.\n\n* ᱵᱚᱸᱫᱽ ᱮᱦᱚᱵ: $8\n* ᱵᱚᱸᱫᱽ ᱢᱩᱪᱟᱹᱫ: $6\n* ᱟᱥᱟᱦᱟᱱ ᱵᱚᱸᱫᱽᱠᱚ: $7\n\nᱟᱢ $1 ᱮᱢ ᱥᱟᱹᱜᱟᱹᱭ ᱫᱟᱲᱮᱭᱟᱭᱟ ᱵᱟᱝᱠᱷᱟᱱ ᱮᱴᱟᱜ [[{{MediaWiki:Grouppage-sysop}}|ᱟᱰᱢᱤᱱᱤᱥᱴᱨᱮᱴᱚᱨ]] ᱵᱚᱸᱫᱽ ᱵᱟᱵᱚᱫᱽ ᱛᱮ ᱜᱟᱞᱚᱪ ᱞᱟᱹᱜᱤᱫ ᱾\nᱟᱢ ᱵᱟᱢ ᱵᱮᱵᱷᱟᱨ ᱫᱟᱲᱮᱭᱟᱜ \"{{int:emailuser}}\" ᱥᱩᱵᱤᱫᱷᱟ ᱡᱚᱛᱷᱟᱛ ᱤᱢᱮᱞ ᱵᱩᱴᱟᱹ ᱛᱟᱢ ᱵᱟᱝ ᱛᱟᱦᱮᱸᱱ ᱠᱷᱟᱱ ᱟᱨ ᱱᱚᱶᱟ ᱫᱚ ᱪᱤᱱᱦᱟᱹᱣ-ᱟ [[Special:Preferences|ᱠᱷᱟᱛᱟ ᱧᱮᱞᱚᱚᱜ]] ᱠᱷᱚᱱ ᱟᱨ ᱟᱢ ᱫᱚ ᱵᱟᱢ ᱵᱚᱸᱫᱽ ᱟᱠᱟᱱᱟ ᱱᱚᱶᱟ ᱵᱮᱵᱷᱟᱨ ᱠᱷᱚᱱ ᱾\nᱟᱢᱟᱜ ᱱᱤᱛᱚᱜᱟᱜ IP ᱵᱩᱴᱟᱹ ᱫᱚ $3, ᱟᱨ ᱵᱚᱸᱫᱽ ID ᱫᱚ #$5  \nᱫᱟᱭᱟᱠᱟᱛᱮ ᱥᱮᱞᱮᱫᱽ ᱢᱮ ᱪᱮᱛᱟᱱᱟᱜ ᱠᱟᱛᱷᱟᱠᱚ ᱡᱚᱛᱚ ᱞᱮᱠᱟᱱ ᱠᱩᱠᱞᱤ ᱨᱮ ᱾",
        "blockednoreason": "ᱡᱟᱸᱦᱟᱸᱱ ᱚᱡᱮ ᱵᱟᱝ ᱮᱢᱠᱟᱱᱟ",
        "whitelistedittext": "ᱥᱟᱦᱴᱟ ᱥᱟᱯᱲᱟᱣ ᱞᱟᱹᱜᱤᱛ $1 ᱮᱢ ᱦᱩᱭᱩᱜ-ᱟ᱾",
        "nosuchsectiontitle": "ᱛᱷᱚᱠ ᱵᱟᱝ ᱧᱟᱢᱞᱮᱱᱟ",
        "newarticle": "(ᱱᱟᱣᱟᱱᱟᱜ)",
        "newarticletext": "ᱟᱢ ᱚᱠᱟ ᱥᱟᱦᱴᱟ ᱨᱮᱱᱟᱜ ᱡᱚᱱᱟᱲᱮᱢ ᱯᱟᱸᱡᱟᱸ ᱟᱹᱜᱩᱭᱫᱟ ᱚᱱᱚ ᱫᱚ ᱵᱟᱱᱩᱜ-ᱟ᱾\nᱚᱱᱟ ᱥᱟᱦᱴᱟ ᱛᱮᱭᱟᱨ ᱞᱟᱹᱜᱤᱛ ᱛᱮ, ᱞᱟᱛᱟᱨ ᱵᱟᱠᱥᱚ ᱵᱷᱤᱛᱨᱤᱨᱮ ᱚᱞ ᱮᱦᱚᱵ ᱢᱮ (ᱟᱨᱦᱚᱸ ᱡᱟᱹᱥᱛᱤ ᱵᱟᱰᱟᱭ ᱞᱟᱹᱜᱤᱛᱴᱮ [$1 ᱜᱚᱸᱲᱚᱸ ᱥᱟᱦᱴᱟ] ᱯᱟᱸᱡᱚᱸᱭᱢᱮ)᱾\nᱟᱢ ᱵᱷᱩᱞᱛᱮ ᱱᱚᱸᱰᱮᱢ ᱦᱮᱡ ᱟᱠᱟᱱ ᱠᱷᱟᱡ, ᱟᱢᱟᱜ ᱵᱨᱟᱣᱡᱟᱨ ᱨᱮᱱᱟᱜ '''ᱛᱟᱭᱚᱢ''' ᱵᱟᱴᱚᱱ ᱞᱤᱱᱢᱮ᱾",
        "anontalkpagetext": "----\n\n<em>ᱱᱚᱶᱟ ᱫᱚ ᱜᱟᱞᱚᱪ ᱥᱟᱦᱴᱟ ᱠᱟᱱᱟ ᱩᱠᱩᱧᱩᱛᱩᱢ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱠᱚᱣᱟᱜ ᱡᱟᱦᱟᱸᱭ ᱫᱚ ᱠᱷᱟᱛᱟ ᱵᱟᱭ ᱛᱮᱭᱟᱨ ᱟᱠᱟᱫᱟ ᱱᱤᱛ ᱦᱟᱹᱵᱤᱡ, ᱟᱨᱵᱟᱝ ᱡᱟᱦᱟᱸᱭ ᱵᱮᱵᱷᱟᱨ ᱟᱠᱟᱫᱟ ᱱᱚᱶᱟ ᱾</em>\nᱚᱱᱟᱛᱮ ᱟᱞᱮ ᱮᱞᱮᱞ IP ᱞᱮ ᱵᱮᱵᱷᱟᱨᱮᱜ-ᱟ ᱩᱱᱤ ᱪᱤᱱᱦᱟᱹᱣ ᱞᱟᱹᱜᱤᱫ ᱾\nᱚᱱᱠᱟᱱ IP ᱵᱩᱴᱟᱹ ᱫᱚ ᱦᱟᱹᱴᱤᱧ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ ᱛᱤᱢᱤᱱ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱫᱟᱨᱟᱭᱛᱮ ᱾\nᱡᱩᱫᱤ ᱟᱢ ᱩᱠᱩᱧᱩᱛᱩᱢ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱠᱟᱱᱟᱢ ᱟᱨ ᱵᱷᱟᱹᱵᱤᱭᱮᱜ-ᱟᱢ ᱵᱟᱝ ᱡᱚᱲᱟᱣᱟᱱ ᱠᱟᱛᱷᱟ ᱟᱢᱮ ᱩᱫᱩᱜᱢᱮ ᱠᱟᱱᱟ, ᱮᱱᱠᱷᱟᱱ  [[Special:CreateAccount|ᱠᱷᱟᱛᱟ ᱛᱮᱭᱟᱨᱢᱮ]] ᱟᱨᱵᱟᱝ [[Special:UserLogin|ᱞᱚᱜᱤᱱ]] ᱢᱮ ᱫᱟᱨᱟᱭ ᱵᱷᱮᱣᱱᱟ ᱠᱚ ᱥᱟᱦᱟᱭ ᱞᱟᱹᱜᱤᱫ ᱮᱴᱟᱜ ᱩᱠᱩᱧᱩᱛᱩᱢ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱠᱚ ᱥᱟᱶ ᱾",
-       "noarticletext": "ᱱᱮᱛᱚᱜ ᱱᱚᱣᱟ ᱥᱟᱦᱴᱟᱨᱮ ᱪᱮᱫᱜᱮ ᱵᱟᱹᱱᱩᱜ-ᱟ᱾\nᱮᱴᱟᱜ ᱥᱟᱦᱴᱟᱨᱮᱢ [[Special:Search/{{PAGENAME}}|search for this page title]],\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs],\nor [{{fullurl:{{FULLPAGENAME}}|action=edit}} edit this page]</span>.",
+       "noarticletext": "ᱱᱮᱛᱚᱜ ᱱᱚᱣᱟ ᱥᱟᱦᱴᱟᱨᱮ ᱪᱮᱫᱜᱮ ᱵᱟᱹᱱᱩᱜ-ᱟ᱾\nᱮᱴᱟᱜ ᱥᱟᱦᱴᱟᱨᱮᱢ [[Special:Search/{{PAGENAME}}|ᱱᱚᱶᱟ ᱥᱟᱦᱴᱟ ᱧᱩᱛᱩᱢ ᱥᱮᱸᱫᱽᱨᱟᱭ ᱢᱮ]],\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ᱡᱚᱲᱟᱣᱟᱱ ᱞᱚᱜᱽ ᱠᱚ ᱥᱮᱸᱫᱽᱨᱟᱭ ᱢᱮ],\nor [{{fullurl:{{FULLPAGENAME}}|action=edit}} ᱱᱚᱶᱟ ᱥᱟᱦᱴᱟ ᱥᱟᱯᱲᱟᱣ ᱢᱮ]</span>.",
        "noarticletext-nopermission": "ᱱᱚᱣᱟ ᱥᱟᱦᱴᱟᱨᱮ ᱱᱤᱛᱚᱜ ᱪᱮᱫᱜᱮ ᱚᱞ ᱵᱟᱹᱱᱩᱜ-ᱟ᱾\n\nᱟᱢ [[Special:Search/{{PAGENAME}}|ᱱᱚᱭᱟ ᱥᱟᱦᱴᱟᱨᱮᱱᱟᱜ ᱧᱤᱛᱩᱢᱮᱢ ᱥᱮᱸᱫᱽᱨᱟ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ]] ᱮᱴᱟᱜ ᱥᱟᱦᱴᱟ ᱠᱚᱨᱮᱦᱚᱸ,\nᱟᱨᱵᱟᱝ <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs]</span>.",
        "userpage-userdoesnotexist": "\"<nowiki>$1</nowiki>\" ńutuman jahãe beoharićaḱ ekaunṭ do baṅ resṭri hoeakana. Daya kate biḍạo katet́ ńelmẽ noa sakam do benoa/sompadonem menet́ kana se baṅ.",
        "userpage-userdoesnotexist-view": "ᱵᱮᱵᱦᱟᱨᱤᱭᱟᱜ \"$1\" ᱮᱠᱟᱣᱱᱴ ᱫᱚ ᱵᱟᱝ ᱨᱮᱥᱴᱨᱤ ᱟᱠᱟᱱᱟ᱾",
        "searchrelated": "ᱥᱟᱹᱜᱟᱹᱭᱟᱱᱠᱩ",
        "searchall": "ᱡᱚᱛᱚ",
        "search-showingresults": "{{PLURAL:$4|ᱚᱨᱡᱚ <strong>$1</strong> ᱨᱮᱱᱟᱜ <strong>$3</strong>|ᱚᱨᱡᱚᱠᱚ <strong>$1 - $2</strong> ᱨᱮᱱᱟᱜ <strong>$3</strong>}}",
-       "search-nonefound": "ᱠᱩᱠá±\9eᱤ á±¥á±\9fᱶá±\9bá±® á±¯á±·á±\9aá±\9e á±µá±\9fá±\9d á±¢á±¤á±\9eá±\9fᱹᱮ ᱞᱮᱱᱟ᱾",
+       "search-nonefound": "ᱠᱩᱠá±\9eᱤ á±¥á±\9fᱶá±\9bá±® á±\9aᱨᱡá±\9a á±µá±\9fá±\9d á±¯á±\9aá±²á±\9bá±\9f ᱞᱮᱱᱟ᱾",
        "powersearch-ns": "ᱨᱟᱠᱷᱟ ᱧᱩᱛᱩᱢ ᱨᱮ ᱥᱮᱸᱫᱽᱨᱟ",
        "powersearch-togglelabel": "ᱠᱷᱚᱸᱡᱽ:",
        "powersearch-toggleall": "ᱡᱚᱛᱚ",
        "recentchangeslinked-feed": "ᱥᱟᱹᱜᱟᱹᱭᱟᱱ ᱵᱚᱫᱚᱞᱠᱚ",
        "recentchangeslinked-toolbox": "ᱥᱟᱹᱜᱟᱹᱭᱟᱱ ᱵᱚᱫᱚᱞᱠᱚ",
        "recentchangeslinked-title": "ᱵᱚᱫᱚᱞᱟᱜ ᱠᱚᱫᱚ \"$1\" ᱥᱟᱶᱛᱮ ᱡᱚᱲᱟᱣ ᱜᱮᱭᱟ",
-       "recentchangeslinked-summary": "á±±á±\9aá±£á±\9f á±«á±\9a á±\9aá±±á±\9f á±\9bá±\9fá±¹á±\9eá± á±\9fá±¹ á± á±\9fá±±á±\9f á±\9aá± á±\9f á±«á±\9f á±±á±®á±µá±®á±\9bá±\9fᱨá±\9cá±® á±µá±\9aᱫá±\9aá±\9e á±¦á±©á±­ á±\9fá± á±\9fá±±á±\9f á±\9aá± á±\9f á±«á±\9a á±\9bá±·á±\9aá±  á±¦á±\9fá±\9bá±\9fá±£ á±\9fá± á±\9fá±± á±¥á±\9fá± á±\9fá±¢ á± á±·á±\9aᱱ᱾\n\n[[Special:Watchlist|á±\9fá±¢á±\9fá±\9c á±§á±®á±\9e á±\9eᱤᱥᱴᱤ]] á±¨á±®á±­ᱟᱜ ᱥᱟᱦᱴᱟ ᱫᱚ <strong>ᱢᱚᱴᱟ ᱛᱮ</strong> ᱚᱞ ᱟᱠᱟᱱᱟ ᱾",
+       "recentchangeslinked-summary": "á±¥á±\9fᱦᱴá±\9f á±¨á±®á±±á±\9fá±\9c á±§á±©á±\9bᱩᱢ á±\9fᱫᱮᱨᱢᱮ á±¡á±\9fᱦá±\9fᱸ á± á±·á±\9aá±± á±¡á±\9aá±±á±\9aá±²á±\9fá±£ á±\9fᱨᱵá±\9fá±\9d á±¥á±\9fᱦᱴá±\9f á±µá±\9aᱫá±\9aá±\9e á±§á±®á±\9e á±\9eá±\9fá±¹á±\9cᱤᱫ á±¾ (á±\9bá±·á±\9aá±  á±¨á±®á±±á±\9fá±\9c á±¥á±\9aᱦᱮᱫ á±§á±®á±\9e á±\9eá±\9fá±¹á±\9cᱤᱫ, á±\9fᱫᱮᱨᱢᱮ {{ns:category}}:á±\9bá±·á±\9aá±  á±§á±©á±\9bᱩᱢ) á±¾ [[Special:Watchlist|á±\9fá±¢á±\9fá±\9c á±§á±®á±\9e á±\9eᱤᱥᱴᱤ]] á±¨á±®á±±á±\9fá±\9c á±µá±\9aá±±á±\9aᱫá±\9aá±\9eᱟᱜ ᱥᱟᱦᱴᱟ ᱫᱚ <strong>ᱢᱚᱴᱟ ᱛᱮ</strong> ᱚᱞ ᱟᱠᱟᱱᱟ ᱾",
        "recentchangeslinked-page": "ᱥᱟᱦᱴᱟ ᱧᱤᱛᱩᱢ :",
        "recentchangeslinked-to": "ᱡᱚᱱᱚᱲ ᱥᱟᱦᱴᱟᱨᱮ ᱧᱮᱞ ᱚᱪᱚᱭ ᱢᱮ ᱮᱢᱟᱜ ᱥᱟᱦᱴᱟ ᱵᱟᱹᱜᱤ ᱠᱟᱛᱮ",
        "upload": "ᱨᱮᱫ ᱞᱟᱫᱮᱢᱮ",
        "filehist-thumb": "ᱴᱤᱯ",
        "filehist-thumbtext": "Thumbnail for version as of $1",
        "filehist-nothumb": "ᱵᱟᱹᱱᱩᱜ-ᱟ ᱴᱤᱯ-ᱨᱟᱢᱟ",
-       "filehist-user": "ᱵᱮᱵᱦᱟᱨᱤᱡ",
+       "filehist-user": "ᱵᱮᱵᱷᱟᱨᱤᱡ",
        "filehist-dimensions": "ᱡᱚᱠᱷᱟ",
        "filehist-filesize": "ᱨᱮᱫ ᱥᱟᱭᱤᱡᱽ",
        "filehist-comment": "ᱠᱟᱛᱷᱟ",
        "movethispage": "ᱱᱚᱶᱟ ᱥᱟᱦᱴᱟ ᱥᱟᱦᱟᱭᱢᱮ",
        "pager-newer-n": "{{PLURAL:$1|1 ᱱᱟᱣᱟᱱᱟᱜ | ᱱᱟᱣᱟᱱᱟᱜ $1}}",
        "pager-older-n": "{{PLURAL:$1|ᱢᱟᱨᱮᱭᱟᱜ 1|ᱢᱟᱨᱮᱭᱟᱜ $1}}",
-       "booksources": "ᱯá±\9aá±\9bá±\9aá±µ á±¯á±·á±®á±°á±\9fá±\9b á±¦á±\9aᱨᱠá±\9f",
+       "booksources": "ᱯá±\9aá±\9bá±\9aá±µ á±¯á±·á±®á±°á±\9fá±\9b á± á±\9a",
        "booksources-search-legend": "ᱯᱚᱛᱚᱵ ᱨᱮᱭᱟᱜ ᱯᱷᱮᱰᱟᱛ ᱦᱚᱨ ᱞᱟᱹᱜᱤᱛ ᱥᱮᱸᱫᱽᱨᱟ",
        "booksources-search": "ᱥᱮᱸᱫᱽᱨᱟ",
        "specialloguserlabel": "ᱠᱟᱹᱢᱤᱭᱟᱹ:",
        "sp-contributions-submit": "ᱥᱮᱸᱫᱽᱨᱟ",
        "whatlinkshere": "ᱱᱚᱸᱰᱮ ᱫᱚ ᱪᱮᱫ ᱡᱚᱱᱚᱲ ᱠᱳ",
        "whatlinkshere-title": "ᱚᱠᱟ ᱥᱟᱦᱴᱟ ᱠᱚᱫᱚ \"$1\" ᱨᱮ ᱡᱚᱱᱚᱲ ᱢᱮᱱᱟᱜ-ᱟ",
-       "whatlinkshere-page": "ᱥᱟᱦᱴᱟ",
-       "linkshere": "ᱞᱟᱛᱟᱨ ᱨᱮᱭᱟᱜ ᱥᱟᱦᱴᱟᱠᱚ ᱫᱚ '''[[:$1]]''' ᱡᱚᱱᱚᱲ ᱢᱮᱱᱟᱜ-ᱟ :",
-       "nolinkshere": "ᱥᱟᱦᱴᱟ ᱡᱚᱱᱚᱲ ᱵᱟᱱᱩᱜ-ᱟ ᱱᱤᱭᱟᱹ <strong>[[:$1]]</strong>.",
+       "whatlinkshere-page": "ᱥᱟᱦᱴᱟ:",
+       "linkshere-2": "ᱞᱟᱛᱟᱨ ᱨᱮᱭᱟᱜ ᱥᱟᱦᱴᱟᱠᱚ ᱫᱚ <strong>$1</strong> ᱥᱟᱶ ᱡᱚᱱᱚᱲ ᱢᱮᱱᱟᱜ-ᱟ :",
+       "nolinkshere-2": "ᱥᱟᱦᱴᱟ ᱡᱚᱱᱚᱲ ᱵᱟᱱᱩᱜ-ᱟ ᱱᱤᱭᱟᱹ <strong>$1</strong>.",
        "isredirect": "ᱵᱟᱝ ᱥᱚᱡᱽᱦᱮ ᱥᱟᱦᱴᱟ",
        "istemplate": "ᱥᱮᱞᱮᱫ",
        "isimage": "ᱨᱮᱫ ᱡᱚᱱᱚᱲ",
        "tooltip-ca-history": "ᱱᱚᱭᱟ ᱥᱟᱦᱴᱟ ᱨᱮᱱᱟᱜ ᱮᱱᱟᱝ ᱱᱟᱝ ᱧᱮᱞ ᱨᱩᱟᱹᱲ",
        "tooltip-ca-protect": "ᱱᱚᱣᱟ ᱥᱟᱦᱴᱟ ᱨᱩᱠᱷᱤᱭᱟᱹᱭ ᱢᱮ",
        "tooltip-ca-delete": "ᱱᱚᱣᱟ ᱥᱟᱦᱴᱟ ᱜᱮᱫᱽ ᱢᱮ",
-       "tooltip-ca-move": "á±±á±\9aᱣᱲ á±¥á±\9fᱦᱴá±\9f á± á±©á±\9eᱢᱮ",
+       "tooltip-ca-move": "á±±á±\9aá±£á±\9f á±¥á±\9fᱦᱴá±\9f á±©á±ªá±\9fᱹᱲᱢᱮ",
        "tooltip-ca-watch": "ᱱᱚᱭᱟ ᱥᱟᱦᱴᱟ ᱫᱚ ᱟᱢᱟᱜ ᱧᱮᱞᱚᱜ ᱛᱟᱹᱞᱠᱟᱹᱨᱮ ᱡᱚᱲᱟᱣᱢᱮ",
        "tooltip-ca-unwatch": "ᱟᱢᱟᱜ ᱧᱮᱞ ᱛᱟᱹᱞᱠᱟᱹ ᱠᱷᱚᱡ ᱱᱚᱣᱟ ᱥᱟᱦᱴᱟ ᱫᱚ ᱚᱪᱚᱜᱽ ᱢᱮ",
        "tooltip-search": "ᱥᱮᱸᱫᱽᱨᱟ {{SITENAME}}",
        "tooltip-n-help": "ᱥᱮᱸᱫᱽᱨᱟ ᱧᱟᱢ ᱨᱮᱭᱟᱜ ᱡᱟᱜᱟ",
        "tooltip-t-whatlinkshere": "ᱥᱟᱱᱟᱢ ᱩᱤᱠᱤ ᱥᱟᱦᱴᱟ ᱨᱮᱱᱟᱜ ᱛᱟᱹᱞᱠᱟᱹ ᱟᱨ ᱡᱚᱱᱚᱲ ᱫᱚ ᱱᱚᱸᱰᱮ",
        "tooltip-t-recentchangeslinked": "ᱱᱚᱭᱟ ᱥᱟᱦᱴᱟ ᱨᱮ ᱨᱚᱠᱟ ᱵᱚᱫᱚᱞ ᱟᱠᱟᱱ ᱥᱟᱦᱴᱟ ᱨᱮᱱᱟᱜ ᱡᱚᱱᱚᱲ",
-       "tooltip-feed-atom": "á±±á±\9aá±£á±\9f á±¥á±\9fᱦᱴá±\9f á±\9eá±\9fá±¹á±\9cᱤá±\9b Atom feed",
+       "tooltip-feed-atom": "á±±á±\9aá±£á±\9f á±¥á±\9fᱦᱴá±\9f á±\9eá±\9fá±¹á±\9cᱤᱫ á±\9fá±´á±\9aá±¢ á±¯á±·á±¤á±°",
        "tooltip-t-contributions": "ᱮᱱᱮᱢ ᱨᱮᱱᱟᱜ ᱛᱟᱹᱞᱠᱟᱹ {{GENDER:$1|ᱱᱩᱭ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ}}",
        "tooltip-t-emailuser": "ᱢᱤᱫ ᱤᱢᱮᱞ ᱠᱩᱞᱟᱭᱢᱮ {{GENDER:$1|ᱱᱩᱭ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ}}",
        "tooltip-t-upload": "ᱨᱮᱫ ᱠᱚ ᱞᱟᱫᱮᱢᱮ",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|ᱥᱟᱦᱴᱟ|ᱥᱟᱦᱴᱟᱠᱚ}}",
        "file-info-size": "$1 x $2 pixels, file size: $3, MIME type: $4",
        "file-info-size-pages": "$1 × $2 ᱯᱤᱠᱥᱮᱞ, ᱨᱮᱫ ᱥᱚᱝ: $3, MIME ᱞᱮᱠᱟᱱ: $4, $5 {{PLURAL:$5|ᱥᱟᱦᱴᱟ|ᱥᱟᱦᱴᱟᱠᱚ}}",
-       "file-nohires": "á±\9fá±­á±¢ᱟ ᱨᱮᱡᱩᱞᱮᱥᱚᱱ ᱵᱟᱱᱩᱜ-ᱟ᱾",
+       "file-nohires": "ᱥᱮᱬᱟ ᱨᱮᱡᱩᱞᱮᱥᱚᱱ ᱵᱟᱱᱩᱜ-ᱟ᱾",
        "svg-long-desc": "SVG ᱨᱮᱫ, ᱱᱚᱨᱢᱟᱞᱛᱮ $1 x $2 pixels, ᱨᱮᱫ ᱡᱟᱜᱟ: $3",
        "show-big-image": "ᱟᱥᱚᱞ ᱨᱮᱫ",
        "show-big-image-preview": "ᱧᱮᱞᱡᱚᱝ ᱨᱮᱱᱟᱜ ᱟᱠᱟᱨ:$1",
index 4e2d7aa..52e2f63 100644 (file)
        "whatlinkshere": "Pàginas chi ligant a custa",
        "whatlinkshere-title": "Pàginas chi ligant a \"$1\"",
        "whatlinkshere-page": "Pàgina:",
-       "linkshere": "Is pàginas chi sighint ligant a '''[[:$1]]''':",
-       "nolinkshere": "Peruna pàgina ligat a '''[[:$1]]'''.",
-       "nolinkshere-ns": "Peruna pàgina ligat a '''[[:$1]]''' in su nùmene-logu seberadu.",
+       "linkshere-2": "Is pàginas chi sighint ligant a '''$1''':",
+       "nolinkshere-2": "Peruna pàgina ligat a '''$1'''.",
+       "nolinkshere-ns-2": "Peruna pàgina ligat a '''$1''' in su nùmene-logu seberadu.",
        "isredirect": "pàgina de reindiritzamentu",
        "istemplate": "inclusione",
        "isimage": "ligòngiu a documentu",
index 65b1624..9903b2a 100644 (file)
        "whatlinkshere": "Chi punta ccà",
        "whatlinkshere-title": "Pàggini ca pùntanu a \"$1\"",
        "whatlinkshere-page": "Pàggina:",
-       "linkshere": "Sti pàggini hannu nu liami a '''[[:$1]]''':",
-       "nolinkshere": "Nudda pàggina havi nu liami a '''[[:$1]]'''.",
-       "nolinkshere-ns": "Nun ci sugnu pàggini chi puntano a '''[[:$1]]''' ntô namespace silizziunatu.",
+       "linkshere-2": "Sti pàggini hannu nu liami a '''$1''':",
+       "nolinkshere-2": "Nudda pàggina havi nu liami a '''$1'''.",
+       "nolinkshere-ns-2": "Nun ci sugnu pàggini chi puntano a '''$1''' ntô namespace silizziunatu.",
        "isredirect": "pàggina di rinnirizzamentu",
        "istemplate": "nclusioni",
        "isimage": "lijami ô file",
        "fileduplicatesearch-noresults": "Nuddu file chiamatu \"$1\" fu attruvatu.",
        "specialpages": "Pàggini spiciali",
        "specialpages-note-top": "Liggenna",
+       "specialpages-note-restricted": "* Pàggini spiciali nurmali.\n* <span class=\"mw-specialpagerestricted\">Pàggini spiciali risirvati.</strong>",
        "specialpages-group-maintenance": "Resucunti di manutinzioni",
        "specialpages-group-other": "Àutri pàggini spiciali",
        "specialpages-group-login": "Trasuta / criazzioni di cunti",
index 9de0674..b09b2ef 100644 (file)
        "whatlinkshere": "Whit airts here",
        "whatlinkshere-title": "Pages that link til \"$1\"",
        "whatlinkshere-page": "Page:",
-       "linkshere": "The follaein pages link til <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Nae pages link wi '''[[:$1]]'''.",
-       "nolinkshere-ns": "No pages aiet til <strong>[[:$1]]</strong> in the chosen namespace.",
+       "linkshere-2": "The follaein pages link til <strong>$1</strong>:",
+       "nolinkshere-2": "Nae pages link wi '''$1'''.",
+       "nolinkshere-ns-2": "No pages aiet til <strong>$1</strong> in the chosen namespace.",
        "isredirect": "reguidal page",
        "istemplate": "transclusion",
        "isimage": "file airtin",
        "fileduplicatesearch-noresults": "Naw file named \"$1\" foond.",
        "specialpages": "Byordinar pages",
        "specialpages-note-top": "The Legend",
+       "specialpages-note-restricted": "* Normal byordinair pages.\n* <span class=\"mw-specialpagerestricted\">Restreected byordinair pages.</span>",
        "specialpages-group-maintenance": "Maintenance reports",
        "specialpages-group-other": "Ither byordinair pages",
        "specialpages-group-login": "Login / cræft accoont",
index 0a17742..deec6e6 100644 (file)
        "whatlinkshere": "هتان ڇا ڳنڍيل آهي",
        "whatlinkshere-title": "\"$1\" سان ڳنڍيندڙ صفحا",
        "whatlinkshere-page": "صفحو:",
-       "linkshere": "هيٺيان صفحا <strong>[[:$1]]</strong> سان ڳنڍيل آهن:",
-       "nolinkshere": "'''[[:$1]]''' سان ڪو بہ صفحو ڳنڍيل ناهي.",
+       "linkshere-2": "هيٺيان صفحا <strong>$1</strong> سان ڳنڍيل آهن:",
+       "nolinkshere-2": "'''$1''' سان ڪو بہ صفحو ڳنڍيل ناهي.",
        "isredirect": "چورڻو صفحو",
        "istemplate": "شموليت",
        "isimage": "فائيل جو ڳنڍڻو",
index 06de033..6976bd4 100644 (file)
        "whatlinkshere": "Puntani inogghi",
        "whatlinkshere-title": "Pàgini chi pùntani a \"$1\"",
        "whatlinkshere-page": "Pàgina:",
-       "linkshere": "Li sighenti pàgini cuntenani cullegamenti a '''[[:$1]]''':",
-       "nolinkshere": "Nisciuna pàgina cunteni dei cullegamenti chi pùntani a '''[[:$1]]'''.",
-       "nolinkshere-ns": "Nò vi so pàgini chi pùntani a '''[[:$1]]''' i' lu namespace sciubaraddu.",
+       "linkshere-2": "Li sighenti pàgini cuntenani cullegamenti a '''$1''':",
+       "nolinkshere-2": "Nisciuna pàgina cunteni dei cullegamenti chi pùntani a '''$1'''.",
+       "nolinkshere-ns-2": "Nò vi so pàgini chi pùntani a '''$1''' i' lu namespace sciubaraddu.",
        "isredirect": "rinviu",
        "istemplate": "incrusioni",
        "isimage": "Cullegamentu a file",
index 7077d5e..c39abf8 100644 (file)
        "whatlinkshere": "بەسیارەگان وە ئێرە",
        "whatlinkshere-title": "ئەو پەڕەیلە ک وە «$1» بەسیار دێرن",
        "whatlinkshere-page": "پەڕە:",
-       "linkshere": "ئەی پەڕەیلە بەستیار دێرن وە '''[[:$1]]''':",
-       "nolinkshere": "هۊچ لاپەڕەێگ بەسیار وە '''[[:$1]]''' نەێرێد .",
+       "linkshere-2": "ئەی پەڕەیلە بەستیار دێرن وە '''$1''':",
+       "nolinkshere-2": "هۊچ لاپەڕەێگ بەسیار وە '''$1''' نەێرێد .",
        "isredirect": "پەڕەێ ڕەوانەکەر",
        "istemplate": "ناوتەپیاێەگان (transclusions)",
        "isimage": "بەسیار پەڕگە",
index 29fa5fc..a33423a 100644 (file)
        "sp-contributions-submit": "Oza",
        "whatlinkshere": "Siiddut mat čujuhit deike",
        "whatlinkshere-title": "Siiddut mat čujuhit $1",
-       "linkshere": "Čuovvovaš siidduin lea liŋka siidui <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Siidui <strong>[[:$1]]</strong> eai leat liŋkkat.",
-       "nolinkshere-ns": "Siidui <strong>[[:$1]]</strong> eai leat liŋkkat válljejuvvon nammagomuvuođas.",
+       "linkshere-2": "Čuovvovaš siidduin lea liŋka siidui <strong>$1</strong>:",
+       "nolinkshere-2": "Siidui <strong>$1</strong> eai leat liŋkkat.",
+       "nolinkshere-ns-2": "Siidui <strong>$1</strong> eai leat liŋkkat válljejuvvon nammagomuvuođas.",
        "isredirect": "ođđasitstivrensiidu",
        "istemplate": "lasihuvvon mállevuođđui",
        "whatlinkshere-prev": "← {{PLURAL:$1|ovddit siidu|$1 ovddit siiddu}}",
index 7308705..6e99960 100644 (file)
        "whatlinkshere": "Kaŋ ga dobu ne",
        "whatlinkshere-title": "Moɲey kaŋ ga dobu \"$1\" ga",
        "whatlinkshere-page": "Moo:",
-       "linkshere": "Moɲey wey ga dobu <strong>[[:$1]]</strong> ga:",
-       "nolinkshere": "Mooyaŋ kul ši dobu <strong>[[:$1]]</strong> ga.",
-       "nolinkshere-ns": "Mooyaŋ kul ši dobu <strong>[[:$1]]</strong> ga maafarru suubantaa ra.",
+       "linkshere-2": "Moɲey wey ga dobu <strong>$1</strong> ga:",
+       "nolinkshere-2": "Mooyaŋ kul ši dobu <strong>$1</strong> ga.",
+       "nolinkshere-ns-2": "Mooyaŋ kul ši dobu <strong>$1</strong> ga maafarru suubantaa ra.",
        "isredirect": "moo kuubi",
        "istemplate": "kanandiyan",
        "isimage": "tuku dobu",
        "fileduplicatesearch-noresults": "Tuku kul ši bara nda \"$1\" maa.  \\",
        "specialpages": "Moo cerecerantey",
        "specialpages-note-top": "Šilbaymaana",
+       "specialpages-note-restricted": "* Hankul cerecere moɲey.\n* <span class=\"mw-specialpagerestricted\">Fondo-kankamante cerecere moɲey.</span>",
        "specialpages-group-maintenance": "Alhaadimay bayrandey",
        "specialpages-group-other": "Cerecere moo taney",
        "specialpages-group-login": "Huru / kontu tee",
index e2918bd..d489059 100644 (file)
        "whatlinkshere": "Sosėjė̄ straipsnē",
        "whatlinkshere-title": "Poslapē, katrėi ruod i \"$1\"",
        "whatlinkshere-page": "Poslapis:",
-       "linkshere": "Anėi poslapē ruod i '''[[:$1]]''':",
-       "nolinkshere": "I '''[[:$1]]''' nūruodu nier.",
-       "nolinkshere-ns": "Nurodītuo vardū srėtī anė vėins poslapis neruod i '''[[:$1]]'''.",
+       "linkshere-2": "Anėi poslapē ruod i '''$1''':",
+       "nolinkshere-2": "I '''$1''' nūruodu nier.",
+       "nolinkshere-ns-2": "Nurodītuo vardū srėtī anė vėins poslapis neruod i '''$1'''.",
        "isredirect": "nusokėma poslapis",
        "istemplate": "īspraudėms",
        "isimage": "abruozdielė nūruoda",
        "fileduplicatesearch-info": "$1 × $2 pėkseliu<br />Faila dėdoms: $3<br />MIME tėps: $4",
        "specialpages": "Specēlė̄jė poslapē",
        "specialpages-note-top": "Pāiškėnėmā",
+       "specialpages-note-restricted": "* Normalūs specēlė̅jė puslapē.\n* <strong class=\"mw-specialpagerestricted\">Apribuotė specēlė̅jė puslapē.</strong>",
        "specialpages-group-maintenance": "Sėstemas palaikīma pranešėmā",
        "specialpages-group-other": "Kėtė specēlė̄jė poslapē",
        "specialpages-group-login": "Prisėjongėms / Registracėjė",
index 7290d42..d775349 100644 (file)
        "whatlinkshere": "Što upućuje ovamo",
        "whatlinkshere-title": "Stranice koje vode / Странице које воде до $1",
        "whatlinkshere-page": "Stranica:",
-       "linkshere": "Sljedeće stranice vode na '''[[:$1]]''':",
-       "nolinkshere": "Nema linkova na '''[[:$1]]'''.",
-       "nolinkshere-ns": "Nijedna stranica nije povezana sa '''[[:$1]]''' u odabranom imenskom prostoru.",
+       "linkshere-2": "Sljedeće stranice vode na '''$1''':",
+       "nolinkshere-2": "Nema linkova na '''$1'''.",
+       "nolinkshere-ns-2": "Nijedna stranica nije povezana sa '''$1''' u odabranom imenskom prostoru.",
        "isredirect": "preusmjeri stranicu",
        "istemplate": "kao šablon",
        "isimage": "link na datoteku",
        "fileduplicatesearch-result-n": "Datoteka \"$1\" ima {{PLURAL:$2|1 identičnog|$2 identična|$2 identičnih}} dvojnika.",
        "fileduplicatesearch-noresults": "Nije pronađena datoteka sa imenom \"$1\".",
        "specialpages": "Posebne stranice",
+       "specialpages-note-restricted": "* Normalne posebne stranice.\n* <span class=\"mw-specialpagerestricted\">Ograničene posebne stranice.</span>\n* <span class=\"mw-specialpagecached\">Keširane posebne stranice (mogu biti zastarjele).</span>",
        "specialpages-group-maintenance": "Izvještaji o održavanju / Извјештаји о одржавању",
        "specialpages-group-other": "Ostale posebne stranice - Остале посебне странице",
        "specialpages-group-login": "Prijava / Пријава",
index 7d7adf5..1e52adb 100644 (file)
        "whatlinkshere": "ⵎⴰⴷ ⵉⵜⵜⴰⵡⵉⵏ ⵙ ⵖⵉⴷ",
        "whatlinkshere-title": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⵜⵜⴰⵡⵉⵏⵉⵏ ⵙ \"$1\"",
        "whatlinkshere-page": "ⵜⴰⵙⵏⴰ:",
-       "linkshere": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⴰⴷ ⴹⴼⴰⵔⵏⵉⵏ ⴰⵔ ⵜⵜⴰⵡⵉⵏⵜ ⵙ <strong>[[:$1]]</strong>:",
-       "nolinkshere": "ⵓⵍⴰ ⴽⵔⴰ ⵏ ⵜⴰⵙⵏⴰ ⵓⵔ ⴰⵔ ⵜⴻⵜⵜⴰⵡⵉ ⵙ <strong>[[:$1]]</strong>.",
-       "nolinkshere-ns": "Ur tlla kra n tasna izdin d  '''[[:$1]]''' ɣ tɣult l-ittuystayn.",
+       "linkshere-2": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⴰⴷ ⴹⴼⴰⵔⵏⵉⵏ ⴰⵔ ⵜⵜⴰⵡⵉⵏⵜ ⵙ <strong>$1</strong>:",
+       "nolinkshere-2": "ⵓⵍⴰ ⴽⵔⴰ ⵏ ⵜⴰⵙⵏⴰ ⵓⵔ ⴰⵔ ⵜⴻⵜⵜⴰⵡⵉ ⵙ <strong>$1</strong>.",
+       "nolinkshere-ns-2": "Ur tlla kra n tasna izdin d  '''$1''' ɣ tɣult l-ittuystayn.",
        "isredirect": "Tasna immutin",
        "istemplate": "Illa gis",
        "isimage": "ⴰⵍⵉⵏⴽ ⵏ ⵓⴼⴰⵢⵍⵓ",
index d886354..62a1800 100644 (file)
        "whatlinkshere": "ႁဵင်းၵွင်ႉ ဢၼ်မီးတီႈၼႆႈပဵၼ်သင်",
        "whatlinkshere-title": "ၼႃႈလိၵ်ႈၸိူဝ်းလိင်ႉၸူး \"$1\"",
        "whatlinkshere-page": "ၼႃႈလိၵ်ႈ",
-       "linkshere": "ၼႃႈလိၵ်ႈၽၢႆႇတႂ်ႈၼႆႉ မၼ်းၵွင်ႉသၢၼ် ဝႆႉၸူး <strong>[[:$1]]</strong>:",
-       "nolinkshere": "ဢမ်ႇမီးၼႃႈလိၵ်ႈ ၸိူဝ်းၵွင်ႉၸူး<strong>[[:$1]]</strong>.",
-       "nolinkshere-ns": "ဢမ်ႇမီးၼႃႈလိၵ်ႈ ၸိူဝ်းၵွင်ႉၸူး <strong>[[:$1]]</strong>တီႈၼႂ်း လွၵ်းၸိုဝ်ႈ ဢၼ်လိူၵ်ႈဝႆႉၼၼ်ႉ။",
+       "linkshere-2": "ၼႃႈလိၵ်ႈၽၢႆႇတႂ်ႈၼႆႉ မၼ်းၵွင်ႉသၢၼ် ဝႆႉၸူး <strong>$1</strong>:",
+       "nolinkshere-2": "ဢမ်ႇမီးၼႃႈလိၵ်ႈ ၸိူဝ်းၵွင်ႉၸူး<strong>$1</strong>.",
+       "nolinkshere-ns-2": "ဢမ်ႇမီးၼႃႈလိၵ်ႈ ၸိူဝ်းၵွင်ႉၸူး <strong>$1</strong>တီႈၼႂ်း လွၵ်းၸိုဝ်ႈ ဢၼ်လိူၵ်ႈဝႆႉၼၼ်ႉ။",
        "isredirect": "ပိၼ်ႇႁူဝ်ၼႃႈလိၵ်ႈ",
        "istemplate": "တူဝ်ၶဝ်ႈပႃး",
        "isimage": "ၾၢႆႇၵွင်ႉ",
index 1618bf5..277a0c9 100644 (file)
        "whatlinkshere": "මෙතනට සබැඳෙන්නේ කුමක්ද",
        "whatlinkshere-title": "\"$1\" වෙත සබැ‍ඳෙන පිටු",
        "whatlinkshere-page": "පිටුව:",
-       "linkshere": "ඉදිරියෙහි දැක්වෙන පිටු, '''[[:$1]]''' වෙත සබැඳෙයි:",
-       "nolinkshere": "'''[[:$1]]''' වෙත කිසිදු පිටුවක් සබැඳී නොමැත.",
-       "nolinkshere-ns": "තෝරාගෙන ඇති නාම-අවකාශය තුලදී, කිසිදු පිටුවක්, '''[[:$1]]''' වෙත නොබැඳෙයි.",
+       "linkshere-2": "ඉදිරියෙහි දැක්වෙන පිටු, '''$1''' වෙත සබැඳෙයි:",
+       "nolinkshere-2": "'''$1''' වෙත කිසිදු පිටුවක් සබැඳී නොමැත.",
+       "nolinkshere-ns-2": "තෝරාගෙන ඇති නාම-අවකාශය තුලදී, කිසිදු පිටුවක්, '''$1''' වෙත නොබැඳෙයි.",
        "isredirect": "පිටුව යළි-යොමුකරන්න",
        "istemplate": "අන්තහ්කරණය",
        "isimage": "ගොනු සබැඳිය",
        "fileduplicatesearch-noresults": "\"$1\" නමින් ගොනුවක් හමු නොවුණි",
        "specialpages": "විශේෂ පිටු",
        "specialpages-note-top": "ප්‍රබන්ධය",
+       "specialpages-note-restricted": "* සාමාන්‍ය විශේෂ පිටු.\n* <span class=\"mw-specialpagerestricted\">සීමිත විශේෂ පිටු.</span>\n* <span class=\"mw-specialpagecached\">සීමිත කළ වි‍ශේෂ පිටු.</span>",
        "specialpages-group-maintenance": "නඩත්තු වාර්තා",
        "specialpages-group-other": "අනෙකුත් විශේෂ පිටු",
        "specialpages-group-login": "පිවිසෙන්න / ගිණුමක් තනන්න",
index a5f5931..7518cc7 100644 (file)
        "whatlinkshere": "Odkazy na túto stránku",
        "whatlinkshere-title": "Stránky odkazujúce na „$1“",
        "whatlinkshere-page": "Page:",
-       "linkshere": "Nasledujúce stránky odkazujú na '''[[:$1]]''':",
-       "nolinkshere": "Žiadne stránky neodkazujú na '''[[:$1]]'''.",
-       "nolinkshere-ns": "Žiadne stránky neodkazujú na '''[[:$1]]''' vo zvolenom mennom priestore.",
+       "linkshere-2": "Nasledujúce stránky odkazujú na '''$1''':",
+       "nolinkshere-2": "Žiadne stránky neodkazujú na '''$1'''.",
+       "nolinkshere-ns-2": "Žiadne stránky neodkazujú na '''$1''' vo zvolenom mennom priestore.",
        "isredirect": "presmerovacia stránka",
        "istemplate": "použitá",
        "isimage": "odkaz na súbor",
        "fileduplicatesearch-noresults": "Súbor s názvom „$1“ nebol nájdený.",
        "specialpages": "Špeciálne stránky",
        "specialpages-note-top": "Legenda",
+       "specialpages-note-restricted": "* Bežné špeciálne stránky.\n* <strong class=\"mw-specialpagerestricted\">Špeciálne stránky s obmedzeným prístupom.</strong>",
        "specialpages-group-maintenance": "Údržbové správy",
        "specialpages-group-other": "Iné špeciálne stránky",
        "specialpages-group-login": "Prihlásenie / registrácia",
index 0ee213e..588058b 100644 (file)
        "yourdiff": "فرق",
        "templatesused": "ایں ورقے تے  ورتے ڳئے {{PLURAL:$1|سانچے|سانچہ}}:",
        "templatesusedpreview": "ایں کچے کم تے  ورتے ڳئے {{PLURAL:$1|سانچے|سانچہ}}:",
-       "template-protected": "(بÚ\86اÛ\8cا Ú¯یا)",
+       "template-protected": "(بÚ\86اÛ\8cا Ú³یا)",
        "template-semiprotected": "(نیم محفوظ)",
        "hiddencategories": "ایہ ورقہ {{PLURAL:$1|1 لُکے زمریاں|$1 لکا زمرہ }} وچ شامل ہے:",
        "permissionserrors": "خطائے اجازت",
        "logentry-contentmodel-change-revertlink": "واپس",
        "logentry-contentmodel-change-revert": "واپس",
        "protectlogpage": "حفاظت لاگ",
-       "protectedarticle": "\"[[$1]]\" Ø¨Ú\86اÛ\8cا Ú¯Û\8cا Ø§ے",
+       "protectedarticle": "\"[[$1]]\" Ø¨Ú\86اÛ\8cا Ú³Û\8cا Û\81ے",
        "modifiedarticleprotection": "«[[$1]]» دا درجہ حفاظت تبدیل کیتا",
        "protectcomment": "سبب:",
        "protectexpiry": "مُکسی:",
        "whatlinkshere": "مربوط ورقے",
        "whatlinkshere-title": "«$1» دے نال جُڑے ہوے ورقے",
        "whatlinkshere-page": "ورقہ",
-       "linkshere": "<strong>[[:$1]]</strong> نال درج ذیل ورقے مربوط ہن:",
-       "nolinkshere": "<strong>[[:$1]]</strong> نال کوئی ورقہ مربوط کائنی۔",
+       "linkshere-2": "<strong>$1</strong> نال درج ذیل ورقے مربوط ہن:",
+       "nolinkshere-2": "<strong>$1</strong> نال کوئی ورقہ مربوط کائنی۔",
        "isredirect": "ورقہ ریڈائریکٹ کرو",
        "istemplate": "شامل شدہ",
        "isimage": "فائل دا ربط",
index f3e9296..db23653 100644 (file)
        "botpasswords-existing": "Obstoječa gesla botov",
        "botpasswords-createnew": "Ustvari novo geslo bota",
        "botpasswords-editexisting": "Uredi obstoječe geslo bota",
+       "botpasswords-label-needsreset": "(geslo mora biti ponastavljeno)",
        "botpasswords-label-appid": "Ime bota:",
        "botpasswords-label-create": "Ustvari",
        "botpasswords-label-update": "Posodobi",
        "botpasswords-restriction-failed": "Omejitve gesla bota preprečujejo to prijavo.",
        "botpasswords-invalid-name": "Navedeno uporabniško ime ne vsebuje ločila za geslo bota (»$1«).",
        "botpasswords-not-exist": "Uporabnik »$1« nima gesla bota z imenom »$2«.",
+       "botpasswords-needs-reset": "Geslo bota »$2« {{GENDER:$1|uporabnika|uporabnice}} »$1« mora biti ponastavljeno.",
        "resetpass_forbidden": "Gesla ne morete spremeniti",
        "resetpass_forbidden-reason": "Gesel nismo mogli spremeniti: $1",
        "resetpass-no-info": "Za neposreden dostop do te strani morate biti prijavljeni.",
        "subject-preview": "Predogled zadeve:",
        "previewerrortext": "Med poskusom prikaza predogleda vaših sprememb je prišlo do napake.",
        "blockedtitle": "Uporabnik je blokiran",
-       "blockedtext": "'''Urejanje z vašim uporabniškim imenom oziroma IP-naslovom je onemogočeno.'''\n\nBlokiral vas je $1.\nPodani razlog je ''$2''.\n\n* začetek blokade: $8\n* potek blokade: $6\n* blokirani uporabnik: $7\n\nO blokiranju se lahko pogovorite z uporabnikom/-co $1 ali katerim drugim [[{{MediaWiki:Grouppage-sysop}}|administratorjem]].\nVedite, da lahko ukaz »Pošlji uporabniku e-pismo« uporabite le, če ste v [[Special:Preferences|nastavitvah]] vpisali in potrdili svoj elektronski naslov in ta ni blokiran.\nVaš IP-naslov je $3, številka blokade pa #$5.\nProsimo, vključite ju v vse morebitne poizvedbe.",
-       "autoblockedtext": "Vaš IP-naslov je bil samodejno blokiran, saj je bil uporabljen s strani drugega uporabnika, ki ga je blokiral $1.\nRazlog za to je bil naslednji:\n\n:''$2''\n\n* Začetek blokade: $8\n* Konec blokade: $6\n* Blokirani uporabnik: $7\n\nKontaktirate lahko $1 ali katerega od drugih [[{{MediaWiki:Grouppage-sysop}}|administratorjev]], da razpravljate o blokadi.\n\nVedite, da lahko funkcijo »{{:MediaWiki:Emailuser/sl}}« uporabljate le, če ste v svoje [[Special:Preferences|uporabniške nastavitve]] vnesli veljaven e-poštni naslov, in vam njena uporaba ni bila preprečena.\n\nVaš trenutni IP-naslov je $3, ID blokiranja pa #$5. Prosimo, vključite ta ID v vsako zastavljeno vprašanje.",
+       "blockedtext": "<strong>Urejanje z vašim uporabniškim imenom oziroma IP-naslovom je onemogočeno.</strong>\n\nBlokiral vas je $1.\nPodani razlog je <em>$2</em>.\n\n* Začetek blokade: $8\n* Potek blokade: $6\n* Blokirani uporabnik: $7\n\nO blokiranju se lahko pogovorite z uporabnikom/-co $1 ali katerim drugim [[{{MediaWiki:Grouppage-sysop}}|administratorjem]].\nVedite, da lahko ukaz »{{int:emailuser}}« uporabite le, če ste v [[Special:Preferences|nastavitvah]] vpisali in potrdili svoj elektronski naslov in ta ni blokiran.\nVaš IP-naslov je $3, številka blokade pa #$5.\nProsimo, vključite ju v vse morebitne poizvedbe.",
+       "autoblockedtext": "Vaš IP-naslov je bil samodejno blokiran, saj je bil uporabljen s strani drugega uporabnika, ki ga je blokiral $1.\nRazlog za to je bil naslednji:\n\n:<em>$2</em>\n\n* Začetek blokade: $8\n* Konec blokade: $6\n* Blokirani uporabnik: $7\n\nKontaktirate lahko $1 ali katerega od drugih [[{{MediaWiki:Grouppage-sysop}}|administratorjev]], da razpravljate o blokadi.\n\nVedite, da lahko funkcijo »{{int:emailuser}}« uporabljate le, če ste v svoje [[Special:Preferences|uporabniške nastavitve]] vnesli veljaven e-poštni naslov, in vam njena uporaba ni bila preprečena.\n\nVaš trenutni IP-naslov je $3, ID blokiranja pa #$5. Prosimo, vključite ta ID v vsako zastavljeno vprašanje.",
        "systemblockedtext": "Vaše uporabniško ime ali IP-naslov je MediaWiki samodejn blokiral.\nPodani razlog je:\n\n:<em>$2</em>\n\n* Začetek blokade: $8\n* Potek blokade: $6\n* Blokirani uporabnik: $7\n\nVaš trenutni IP-naslov je $3.\nProsimo, da v svoje poizvedbe vključite vse zgornje podatke.",
        "blockednoreason": "razlog ni podan",
        "whitelistedittext": "Za urejanje strani se morate $1.",
        "whatlinkshere": "Kaj se povezuje sem",
        "whatlinkshere-title": "Strani, ki se povezujejo na $1",
        "whatlinkshere-page": "Stran:",
-       "linkshere": "Na '''[[:$1]]''' kažejo naslednje strani:",
-       "nolinkshere": "Nobena stran ne kaže na '''[[:$1]]'''.",
-       "nolinkshere-ns": "Nobena stran se ne povezuje na '''[[:$1]]''' v izbranem imenskem prostoru.",
+       "linkshere-2": "Na '''$1''' kažejo naslednje strani:",
+       "nolinkshere-2": "Nobena stran ne kaže na '''$1'''.",
+       "nolinkshere-ns-2": "Nobena stran se ne povezuje na '''$1''' v izbranem imenskem prostoru.",
        "isredirect": "preusmeritvena stran",
        "istemplate": "vključitev",
        "isimage": "povezava na datoteko",
        "pagedata-title": "Podatki strani",
        "pagedata-text": "Ta stran nudi podatkovni vmesnik do strani. Prosimo, navedite naslov strani v URL-ju z uporabo skladnje podstrani.\n* Pogajanje o vsebini se nanaša na glavo Accept vašega odjemalca. To pomeni, da bomo podatke strani posredovali v obliki, ki vašemu odjemalcu bolj ustreza.",
        "pagedata-not-acceptable": "Nismo našli ujemajoče oblike. Podprte vrste MIME: $1",
-       "pagedata-bad-title": "Neveljaven naslov: $1."
+       "pagedata-bad-title": "Neveljaven naslov: $1.",
+       "unregistered-user-config": "Iz varnostnih razlogov uporabniških podstrani JavaScript, CSS in JSON ne moremo naložiti neregistriranim uporabnikom."
 }
index 41e2e1b..e468f4d 100644 (file)
        "whatlinkshere": "Links uff de Seite",
        "whatlinkshere-title": "Seyta, de uff „$1“ verlinka",
        "whatlinkshere-page": "Seite:",
-       "linkshere": "De folgenden Seyta verlinka uff '''„[[:$1]]“''':",
-       "nolinkshere": "Kenne Seite verlinkt uff '''„[[:$1]]“'''.",
-       "nolinkshere-ns": "Kenne Seite verlinkt uff '''„[[:$1]]“''' eim gewählta Noamasraum.",
+       "linkshere-2": "De folgenden Seyta verlinka uff '''„$1“''':",
+       "nolinkshere-2": "Kenne Seite verlinkt uff '''„$1“'''.",
+       "nolinkshere-ns-2": "Kenne Seite verlinkt uff '''„$1“''' eim gewählta Noamasraum.",
        "isredirect": "Weiterleitungsseyte",
        "istemplate": "Vorlageneinbindung",
        "isimage": "Dateilink",
        "fileduplicatesearch-result-1": "De Datei „$1“ hoot keene identischa Duplikate.",
        "fileduplicatesearch-result-n": "De Datei „$1“ hoot {{PLURAL:$2|1 identisches Duplikat|$2 identische Duplikate}}.",
        "specialpages": "Spezialseyta",
+       "specialpages-note-restricted": "* Spezialseyta fier Jedermoan\n* <strong class=\"mw-specialpagerestricted\">Spezialseyta fier Nutzer miet erweiterta Rechta</strong>",
        "specialpages-group-other": "Andere Spezialseyta",
        "specialpages-group-login": "Oamelda",
        "specialpages-group-changes": "Letzte Änderunga und Logbicher",
index c043222..1aac592 100644 (file)
        "whatlinkshere": "Maxaa meeshaan la xiriiro",
        "whatlinkshere-title": "Boggaga la xiriiro \"$1\"",
        "whatlinkshere-page": "Bogga:",
-       "linkshere": "Bogyaashaan waxey la xiriiraan  '''[[:$1]]''':",
-       "nolinkshere": "Boggag la xiriiro   '''[[:$1]]''' ma jirto.",
+       "linkshere-2": "Bogyaashaan waxey la xiriiraan  '''$1''':",
+       "nolinkshere-2": "Boggag la xiriiro   '''$1''' ma jirto.",
        "isredirect": "bogga loo sii toosiyay",
        "istemplate": "ku jiri kara",
        "isimage": "faylka la xiriiro",
index 0654224..a0cf5bf 100644 (file)
        "whatlinkshere": "Lidhjet këtu",
        "whatlinkshere-title": "Faqe që lidhen tek $1",
        "whatlinkshere-page": "Faqja:",
-       "linkshere": "Faqet e mëposhtme lidhen këtu '''[[:$1]]''':",
-       "nolinkshere": "Asnjë faqe nuk lidhet tek '''[[:$1]]'''.",
-       "nolinkshere-ns": "Nuk ka faqe në hapësirën e zgjedhur që lidhen tek '''[[:$1]]'''.",
+       "linkshere-2": "Faqet e mëposhtme lidhen këtu '''$1''':",
+       "nolinkshere-2": "Asnjë faqe nuk lidhet tek '''$1'''.",
+       "nolinkshere-ns-2": "Nuk ka faqe në hapësirën e zgjedhur që lidhen tek '''$1'''.",
        "isredirect": "faqe përcjellëse",
        "istemplate": "përfshirë",
        "isimage": "Lidhja e dokumentit",
        "fileduplicatesearch-noresults": "Nuk u gjet asnjë skedë me emrin \"$1\".",
        "specialpages": "Faqet speciale",
        "specialpages-note-top": "Legjenda",
+       "specialpages-note-restricted": "* Faqet speciale normale.\n* <span class=\"mw-specialpagerestricted\">Faqet speciale të kufizuara.</span>",
        "specialpages-group-maintenance": "Përmbledhje mirëmbajtjeje",
        "specialpages-group-other": "Faqe speciale të tjera",
        "specialpages-group-login": "Hyrë / hap llogari",
index c0e0968..d802e94 100644 (file)
        "permissionserrorstext-withaction": "Немате дозволу за $2 из {{PLURAL:$1|следећег|следећих}} разлога:",
        "contentmodelediterror": "Не можете уредити ову измену јер је њен модел садржаја <code>$1</code>, што се разликује од тренутног модела садржаја странице <code>$2</code>.",
        "recreate-moveddeleted-warn": "<strong>Упозорење: поново правите страницу која је претходно обрисана.</strong>\n\nРазмотрите да ли је прикладно да наставите с уређивањем ове странице.\nОвде је наведена историја брисања и премештања с образложењем:",
-       "moveddeleted-notice": "Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð¾Ð±Ñ\80иÑ\81ана.\nÐ\98Ñ\81Ñ\82оÑ\80иÑ\98а Ñ\9aеног Ð±Ñ\80иÑ\81аÑ\9aа, Ð·Ð°Ñ\88Ñ\82иÑ\82е Ð¸ Ð¿Ñ\80емеÑ\88Ñ\82аÑ\9aа Ð½Ð°Ð»Ð°Ð·Ð¸ Ñ\81е Ð¸Ñ\81под:",
+       "moveddeleted-notice": "Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð¾Ð±Ñ\80иÑ\81ана.\nÐ\94невник Ð±Ñ\80иÑ\81аÑ\9aа, Ð·Ð°Ñ\88Ñ\82иÑ\82е Ð¸ Ð¿Ñ\80емеÑ\88Ñ\82аÑ\9aа Ñ\81Ñ\82Ñ\80аниÑ\86е Ð½Ð°Ð»Ð°Ð·Ð¸ Ñ\81е Ð¸Ñ\81под.",
        "moveddeleted-notice-recent": "Жао нам је, ова страница је недавно обрисана (у последњих 24 сата).\nИсторија њеног брисања, заштите и премештања налази се испод:",
        "log-fulllog": "Погледај целу историју",
        "edit-hook-aborted": "Измену је прекинула кука.\nНије дато никакво образложење.",
        "whatlinkshere": "Шта води овде",
        "whatlinkshere-title": "Странице које су повезане са „$1”",
        "whatlinkshere-page": "Страница:",
-       "linkshere": "Следеће странице имају везу до <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Ниједна страница није повезана са: <strong>[[:$1]]</strong>.",
-       "nolinkshere-ns": "Ниједна страница не води до '''[[:$1]]''' у изабраном именском простору.",
+       "linkshere-2": "Следеће странице имају везу до <strong>$1</strong>:",
+       "nolinkshere-2": "Ниједна страница није повезана са: <strong>$1</strong>.",
+       "nolinkshere-ns-2": "Ниједна страница не води до '''$1''' у изабраном именском простору.",
        "isredirect": "преусмерење",
        "istemplate": "укључивање",
        "isimage": "веза до датотеке",
index f464cf2..ddd4b1e 100644 (file)
        "noindex-category": "Neindeksirane stranice",
        "broken-file-category": "Stranice s neispravnim vezama do datoteka",
        "about": "O nama",
-       "article": "Stranica sa sadržajem",
+       "article": "Članak",
        "newwindow": "(otvara se u novom prozoru)",
        "cancel": "Otkaži",
        "moredotdotdot": "Više…",
        "permissionserrorstext": "Nemate ovlašćenje za ovu radnju iz {{PLURAL:$1|1=sledećeg|sledećih}} razloga:",
        "permissionserrorstext-withaction": "Nemate dozvolu za $2 iz {{PLURAL:$1|sledećeg|sledećih}} razloga:",
        "recreate-moveddeleted-warn": "<strong>Upozorenje: ponovo pravite stranicu koja je prethodno obrisana.</strong>\n\nRazmotrite da li je prikladno da nastavite s uređivanjem ove stranice.\nOvde je navedena istorija brisanja i premeštanja s obrazloženjem:",
-       "moveddeleted-notice": "Ova stranica je obrisana.\nIstorija njenog brisanja i premeštanja nalazi se ispod:",
+       "moveddeleted-notice": "Ova stranica je obrisana.\nDnevnik brisanja, zaštite i premeštanja stranice nalazi se ispod.",
        "moveddeleted-notice-recent": "Žao nam je, ova stranica je nedavno obrisana (u poslednjih 24 sata).\nOvde je navedena istorija brisanja i premeštanja s obrazloženjem.",
        "log-fulllog": "Pogledaj celu istoriju",
        "edit-hook-aborted": "Izmenu je prekinula kuka.\nNije dato nikakvo obrazloženje.",
        "whatlinkshere": "Šta vodi ovde",
        "whatlinkshere-title": "Stranice koje su povezane sa „$1”",
        "whatlinkshere-page": "Stranica:",
-       "linkshere": "Sledeće stranice imaju vezu do '''[[:$1]]''':",
-       "nolinkshere": "Nijedna stranica nije povezana sa: '''[[:$1]]'''.",
-       "nolinkshere-ns": "Nijedna stranica ne vodi do '''[[:$1]]''' u izabranom imenskom prostoru.",
+       "linkshere-2": "Sledeće stranice imaju vezu do '''$1''':",
+       "nolinkshere-2": "Nijedna stranica nije povezana sa: '''$1'''.",
+       "nolinkshere-ns-2": "Nijedna stranica ne vodi do '''$1''' u izabranom imenskom prostoru.",
        "isredirect": "preusmerenje",
        "istemplate": "uključivanje",
        "isimage": "veza ka datoteci",
index 322487c..7d99603 100644 (file)
        "sp-contributions-submit": "Suku",
        "whatlinkshere": "San e miti kon dyaso",
        "whatlinkshere-title": "Papira di e sori go na $1",
-       "linkshere": "Den papira disi e miti go na '''[[:$1]]''':",
-       "nolinkshere": "No wan papira e miti kon na '''[[:$1]]'''.",
+       "linkshere-2": "Den papira disi e miti go na '''$1''':",
+       "nolinkshere-2": "No wan papira e miti kon na '''$1'''.",
        "isredirect": "papira fu drai go",
        "istemplate": "poti leki wan template",
        "whatlinkshere-prev": "{{PLURAL:$1|a wan|den $1}} di psa",
index 61b8e02..78536c6 100644 (file)
        "whatlinkshere": "Links ap disse Siede",
        "whatlinkshere-title": "Sieden, do der ap \"$1\" linkje",
        "whatlinkshere-page": "Siede:",
-       "linkshere": "Do foulgjende Sieden ferwiese hierhäär:  '''[[:$1]]''': <br /><small>(Moonige Sieden wäide eventuell moorfooldich liested, konnen in säildene Falle oawers uk miste. Dät kumt fon oolde Failere in dän Software häär, man skoadet fääre niks.)</small>",
-       "nolinkshere": "Naan Artikkel ferwiest hierhäär: '''[[:$1]]'''.",
-       "nolinkshere-ns": "Neen Siede ferlinket ap '''„[[:$1]]“''' in dän wäälde Noomensruum.",
+       "linkshere-2": "Do foulgjende Sieden ferwiese hierhäär:  '''$1''': <br /><small>(Moonige Sieden wäide eventuell moorfooldich liested, konnen in säildene Falle oawers uk miste. Dät kumt fon oolde Failere in dän Software häär, man skoadet fääre niks.)</small>",
+       "nolinkshere-2": "Naan Artikkel ferwiest hierhäär: '''$1'''.",
+       "nolinkshere-ns-2": "Neen Siede ferlinket ap '''„$1“''' in dän wäälde Noomensruum.",
        "isredirect": "Fäärelaitengs-Siede",
        "istemplate": "Foarloagenienbiendenge",
        "isimage": "Doatäilink",
        "fileduplicatesearch-result-n": "Ju Doatäi „$1“ häd {{PLURAL:$2|1 identisk Duplikoat|$2 identiske Duplikoate}}.",
        "fileduplicatesearch-noresults": "Der wuud neen Doatäi mäd Noome \"$1\" fuunen.",
        "specialpages": "Spezioalsieden",
+       "specialpages-note-restricted": "* Reguläre Spezioalsieden\n* <span class=\"mw-specialpagerestricted\">Tougriepsbeskränkede Spezioalsieden</span>\n* <span class=\"mw-specialpagecached\">Cachegenerierde Spezioalsieden</span>",
        "specialpages-group-maintenance": "Fersuurgengsliesten",
        "specialpages-group-other": "Uur Spezioalsieden",
        "specialpages-group-login": "Anmäldje",
index 5c7309c..f76272f 100644 (file)
        "whatlinkshere": "Мынта ссылкалар",
        "whatlinkshere-title": "«$1» питкә йебәргән питләр",
        "whatlinkshere-page": "Пит:",
-       "linkshere": "''[[:$1]]''' питкә киләсе питләр тайанатылар:",
-       "nolinkshere": "[[:$1]] питкә пер питтән тә ссылка йуҡ.",
+       "linkshere-2": "''$1''' питкә киләсе питләр тайанатылар:",
+       "nolinkshere-2": "$1 питкә пер питтән тә ссылка йуҡ.",
        "isredirect": "йусыҡлау пит",
        "istemplate": "ҡушылыу",
        "isimage": "файллы ссылка",
index a52f6d4..0e93458 100644 (file)
        "whatlinkshere": "Anu nutumbu ka dieu",
        "whatlinkshere-title": "Kaca anu nutumbu ka \"$1\"",
        "whatlinkshere-page": "Kaca:",
-       "linkshere": "Kaca di handap ieu numbu ka '''[[:$1]]''':",
-       "nolinkshere": "Euweuh kaca anu nutumbu ka <strong>[[:$1]]</strong>.",
-       "nolinkshere-ns": "Euweuh kaca anu nutumbu ka <strong>[[:$1]]</strong> dina ruang-nama anu dipilih.",
+       "linkshere-2": "Kaca di handap ieu numbu ka '''$1''':",
+       "nolinkshere-2": "Euweuh kaca anu nutumbu ka <strong>$1</strong>.",
+       "nolinkshere-ns-2": "Euweuh kaca anu nutumbu ka <strong>$1</strong> dina ruang-nama anu dipilih.",
        "isredirect": "Kaca alihan",
        "istemplate": "ku citakan",
        "isimage": "tutumbu berkas",
index 534190a..3765b04 100644 (file)
        "botpasswords-existing": "Befintliga botlösenord",
        "botpasswords-createnew": "Skapa ett nytt botlösenord",
        "botpasswords-editexisting": "Redigera ett befintligt botlösenord",
+       "botpasswords-label-needsreset": "(lösenordet behöver återställas)",
        "botpasswords-label-appid": "Botnamn:",
        "botpasswords-label-create": "Skapa",
        "botpasswords-label-update": "Uppdatera",
        "botpasswords-restriction-failed": "Begränsningar av botlösenord tillåter inte denna inloggning.",
        "botpasswords-invalid-name": "Det angivna användarnamnet innehåller inte separatorn för botlösenord (\"$1\").",
        "botpasswords-not-exist": "Användaren \"$1\" har inte ett botlösenord som är \"$2\".",
+       "botpasswords-needs-reset": "Botlösenordet för botnamnet \"$2\" till {{GENDER:$1|användaren}} \"$1\" måste återställas.",
        "resetpass_forbidden": "Lösenord kan inte ändras",
        "resetpass_forbidden-reason": "Lösenorden kan inte ändras: $1",
        "resetpass-no-info": "Du måste vara inloggad för att komma åt den här sidan direkt.",
        "subject-preview": "Förhandsgranskning av ämne:",
        "previewerrortext": "Ett fel uppstod när dina ändringar skulle förhandsgranskas.",
        "blockedtitle": "Användaren är blockerad",
-       "blockedtext": "'''Din IP-adress eller ditt användarnamn är blockerat.'''\n\nBlockeringen utfördes av $1 med motiveringen: ''$2''.\n\n* Blockeringen startade: $8\n* Blockeringen gäller till: $6.\n* Blockeringen var avsedd för: $7.\n\nDu kan kontakta $1 eller någon annan av [[{{MediaWiki:Grouppage-sysop}}|administratörerna]] för att diskutera blockeringen.\nOm du är inloggad och har uppgivit en e-postadress i dina [[Special:Preferences|inställningar]] så kan du använda funktionen 'Skicka e-post till den här användaren', såvida du inte blivit blockerad från funktionen.\n\nDin IP-adress är $3 och blockerings-ID är #$5.\nVänligen ange informationen ovan i alla förfrågningar som du gör i ärendet.",
-       "autoblockedtext": "Din IP-adress har blockerats automatiskt eftersom den har använts av en annan användare som blockerats av $1.\nMotiveringen av blockeringen var:\n\n:''$2''\n\n* Blockeringen startade: $8\n* Blockeringen gäller till: $6\n* Blockeringen är avsedd för: $7\n\nDu kan kontakta $1 eller någon annan [[{{MediaWiki:Grouppage-sysop}}|administratör]] för att diskutera blockeringen.\n\nObservera att du inte kan använda dig av funktionen \"skicka e-post till användare\" om du inte har registrerat en giltig e-postadress i [[Special:Preferences|dina inställningar]] eller om du har blivit blockerad från att skicka e-post.\n\nDin nuvarande IP-adress är $3, och blockerings-ID är #$5.\nVänligen ange informationen ovan i alla förfrågningar som du gör i ärendet.",
+       "blockedtext": "'''Din IP-adress eller ditt användarnamn är blockerat.'''\n\nBlockeringen utfördes av $1 med motiveringen: ''$2''.\n\n* Blockeringen startade: $8\n* Blockeringen gäller till: $6.\n* Blockeringen var avsedd för: $7.\n\nDu kan kontakta $1 eller någon annan av [[{{MediaWiki:Grouppage-sysop}}|administratörerna]] för att diskutera blockeringen.\nOm du är inloggad och har uppgivit en e-postadress i dina [[Special:Preferences|inställningar]] så kan du använda funktionen \"{{int:emailuser}}\", såvida du inte blivit blockerad från funktionen.\n\nDin IP-adress är $3 och blockerings-ID är #$5.\nVänligen ange informationen ovan i alla förfrågningar som du gör i ärendet.",
+       "autoblockedtext": "Din IP-adress har blockerats automatiskt eftersom den har använts av en annan användare som blockerats av $1.\nMotiveringen av blockeringen var:\n\n:''$2''\n\n* Blockeringen startade: $8\n* Blockeringen gäller till: $6\n* Blockeringen är avsedd för: $7\n\nDu kan kontakta $1 eller någon annan [[{{MediaWiki:Grouppage-sysop}}|administratör]] för att diskutera blockeringen.\n\nObservera att du inte kan använda dig av funktionen \"{{int:emailuser}}\" om du inte har registrerat en giltig e-postadress i [[Special:Preferences|dina inställningar]] eller om du har blivit blockerad från att skicka e-post.\n\nDin nuvarande IP-adress är $3, och blockerings-ID är #$5.\nVänligen ange informationen ovan i alla förfrågningar som du gör i ärendet.",
        "systemblockedtext": "Ditt användarnamn eller IP-adress h    ar blockerats automatiskt av MediaWiki.\n\nMotiveringen av blockeringen var:\n\n:<em>$2</em>\n\n* Blockeringen startade: $8\n* Blockeringen gäller till: $6\n* Blockeringen är avsedd för: $7\n\nDin nuvarande IP-adress är $3.\nVänligen ange informationen ovan i alla förfrågningar som du gör i ärendet.",
        "blockednoreason": "ingen motivering angavs",
        "whitelistedittext": "Vänligen $1 för att redigera sidor.",
        "recentchangeslinked-feed": "Relaterade ändringar",
        "recentchangeslinked-toolbox": "Relaterade ändringar",
        "recentchangeslinked-title": "Ändringar relaterade till \"$1\"",
-       "recentchangeslinked-summary": "Ange namnet på en sida för att se ändringar på sidor som länkas till eller från denna sida. (För att se medlemmar i en kategori, skriv Kategori:Namnet på kategorin). Ändringar på sidor i [[Special:Watchlist|din bevakningslista]] är <strong>fetstilta</strong>.",
+       "recentchangeslinked-summary": "Ange namnet på en sida för att se ändringar på sidor som länkas till eller från denna sida. (För att se medlemmar i en kategori, skriv {{ns:category}}:Namnet på kategorin). Ändringar på sidor i [[Special:Watchlist|din bevakningslista]] är <strong>fetstilta</strong>.",
        "recentchangeslinked-page": "Sidnamn:",
        "recentchangeslinked-to": "Visa ändringar på sidor med länkar till den givna sidan istället",
        "recentchanges-page-added-to-category": "[[:$1]] lades till i kategorin",
        "protectedtitles-submit": "Visa titlar",
        "listusers": "Användarlista",
        "listusers-editsonly": "Visa endast användare som redigerat",
+       "listusers-temporarygroupsonly": "Visa endast användare i tillfälliga användargrupper",
        "listusers-creationsort": "Sortera efter datum skapat",
        "listusers-desc": "Sortera i fallande ordning",
        "usereditcount": "$1 {{PLURAL:$1|redigering|redigeringar}}",
        "apisandbox-dynamic-parameters-add-label": "Lägg till parameter:",
        "apisandbox-dynamic-parameters-add-placeholder": "Parameternamn",
        "apisandbox-dynamic-error-exists": "En parameter som heter \"$1\" finns redan.",
+       "apisandbox-templated-parameter-reason": "Denna [[Special:ApiHelp/main#main/templatedparams|mallparameter]] erbjuds baserat på {{PLURAL:$1|värdet|värden}} i $2.",
        "apisandbox-deprecated-parameters": "Föråldrade parametrar",
        "apisandbox-fetch-token": "Fyll i nyckeln automatiskt",
        "apisandbox-add-multi": "Lägg till",
        "whatlinkshere": "Vad som länkar hit",
        "whatlinkshere-title": "Sidor som länkar till \"$1\"",
        "whatlinkshere-page": "Sida:",
-       "linkshere": "Följande sidor länkar till <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Inga sidor länkar till <strong>[[:$1]]</strong>.",
-       "nolinkshere-ns": "Inga sidor i den angivna namnrymden länkar till <strong>[[:$1]]</strong>.",
+       "linkshere-2": "Följande sidor länkar till <strong>$1</strong>:",
+       "nolinkshere-2": "Inga sidor länkar till <strong>$1</strong>.",
+       "nolinkshere-ns-2": "Inga sidor i den angivna namnrymden länkar till <strong>$1</strong>.",
        "isredirect": "omdirigeringssida",
        "istemplate": "inkluderad som mall",
        "isimage": "fillänk",
        "pagedata-title": "Siddata",
        "pagedata-text": "Denna sida tillhandahåller ett datagränssnitt till sidor. Ange sidans titel i webbadressen med hjälp av undersidesyntax.\n* Innehållsförhandling gäller baserat på att din klients Accept-header. Detta innebär att siddatan kommer att tillhandahållas i det format som din klient föredrar.",
        "pagedata-not-acceptable": "Inga matchande format finns. MIME-typer som stöds:$1",
-       "pagedata-bad-title": "Ogiltig titel: $1."
+       "pagedata-bad-title": "Ogiltig titel: $1.",
+       "unregistered-user-config": "Av säkerhetsskäl kan inte undersidor med JavaScript, CSS och JSON läsas in för oregistrerade användare.",
+       "passwordpolicies": "Lösenordspolicyer",
+       "passwordpolicies-summary": "Detta är en lista över effektiva lösenordspolicyer för användargrupper som definieras i denna wiki.",
+       "passwordpolicies-group": "Grupp",
+       "passwordpolicies-policies": "Policyer",
+       "passwordpolicies-policy-minimalpasswordlength": "Lösenordet måste vara minst $1 {{PLURAL:$1|tecken}} långt",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Lösenordet måste vara minst $1 {{PLURAL:$1|tecken}} långt för att kunna logga in",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Lösenordet kan inte vara likadant som användarnamnet",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Lösenordet kan inte matcha specifikt svartlistade lösenord",
+       "passwordpolicies-policy-maximalpasswordlength": "Lösenordet måste vara högst $1 {{PLURAL:$1|tecken}} långt",
+       "passwordpolicies-policy-passwordcannotbepopular": "Lösenordet kan inte vara {{PLURAL:$1|det populäraste lösenordet|i listan över de $1 populäraste lösenorden}}"
 }
index 30f1355..ae02942 100644 (file)
        "whatlinkshere": "Viungo viungavyo ukurasa huu",
        "whatlinkshere-title": "Kurasa zilizounganishwa na \"$1\"",
        "whatlinkshere-page": "Ukurasa:",
-       "linkshere": "Kurasa zifuatazo zimeunganishwa na '''[[:$1]]''':",
-       "nolinkshere": "Hakuna kurasa zilizounganishwa na '''[[:$1]]'''.",
-       "nolinkshere-ns": "Hakuna kurasa zilizounganishwa na '''[[:$1]]''' katika eneo la wiki lililochaguliwa.",
+       "linkshere-2": "Kurasa zifuatazo zimeunganishwa na '''$1''':",
+       "nolinkshere-2": "Hakuna kurasa zilizounganishwa na '''$1'''.",
+       "nolinkshere-ns-2": "!!FUZZY!!!!FUZZY!!Hakuna kurasa zilizounganishwa na '''$1''' katika eneo la wiki lililochaguliwa.",
        "isredirect": "elekeza ukurasa",
        "istemplate": "jumuisho",
        "isimage": "kiungo cha faili",
        "fileduplicatesearch-noresults": "Faili linaloitwa \"$1\" halikupatikana.",
        "specialpages": "Kurasa maalum",
        "specialpages-note-top": "Simulizi",
+       "specialpages-note-restricted": "* Kurasa maalum za kawaida.\n* <span class=\"mw-specialpagerestricted\">Kurasa maalum zisizoonekana na wote.</span>\n* <span class=\"mw-specialpagecached\">Kurasa maalum zinazotoka \"cache\" (might be obsolete).</span>",
        "specialpages-group-maintenance": "Ripoti za kurekebisha na kutunza kurasa",
        "specialpages-group-other": "Kurasa maalum zingine",
        "specialpages-group-login": "Ingia / sajili akaunti",
index d78fcd1..a393e81 100644 (file)
        "and": "&#32;a",
        "faq": "FAQ",
        "actions": "Akcyje",
-       "namespaces": "Raumy mjan",
+       "namespaces": "Przestrzynie mian",
        "variants": "Ôpcyje",
        "navigation-heading": "Menu nawigacyje",
        "errorpagetitle": "Feler",
        "feed-invalid": "Ńywłaściwy typ kanałů informacyjnygo.",
        "feed-unavailable": "Kanoły informacyjne ńy sům dostympne",
        "site-rss-feed": "Kanoł RSS {{GRAMMAR:D.lp|$1}}",
-       "site-atom-feed": "Kanŏł Atom {{GRAMMAR:D.lp|$1}}",
+       "site-atom-feed": "Kanoł Atom {{GRAMMAR:D.lp|$1}}",
        "page-rss-feed": "Kanoł RSS \"$1\"",
        "page-atom-feed": "Kanoł Atom \"$1\"",
        "red-link-title": "$1 (niy ma zajty)",
        "welcomecreation-msg": "Uotwarli my sam lo Ćebje kůnto.\nPamjyntej coby posztalować [[Special:Preferences|preferencyji]]",
        "yourname": "Mjano użytkowńika:",
        "userlogin-yourname": "Mjano używocza",
-       "userlogin-yourname-ph": "Wszkryflej swoje mjano użytkowńika",
+       "userlogin-yourname-ph": "Wkludź swoje miano używacza",
        "createacct-another-username-ph": "Wszkryflej mjano użytkowńika",
        "yourpassword": "Hasło:",
        "userlogin-yourpassword": "Hasło",
-       "userlogin-yourpassword-ph": "Wszkryflej swoje hasło",
-       "createacct-yourpassword-ph": "Wszkryflej hasło",
+       "userlogin-yourpassword-ph": "Wkludź swoje hasło",
+       "createacct-yourpassword-ph": "Wkludź hasło",
        "yourpasswordagain": "Naszkryflej ausdruk zaś",
        "createacct-yourpasswordagain": "Potwjyrdź hasło",
-       "createacct-yourpasswordagain-ph": "Wszkryflej hasło jeszcze roz",
+       "createacct-yourpasswordagain-ph": "Wkludź hasło jeszcze rŏz",
        "userlogin-remembermypassword": "Ńy wylogůwywuj mje",
        "userlogin-signwithsecure": "Użyj bezpjecznygo połůnczyńa",
        "yourdomainname": "Twoja domyna",
        "userlogin-createanother": "Twůrz inksze kůnto",
        "createacct-emailrequired": "E-brif",
        "createacct-emailoptional": "E-brif (uopcjůnalne)",
-       "createacct-email-ph": "Wszkryflej swůj adres do e-brifa",
+       "createacct-email-ph": "Wkludź swojã adresã e-brifa",
        "createacct-another-email-ph": "Nastow e-brif",
        "createaccountmail": "Użyj chwilowygo hasła losowo genyrowanygo a wyślij je na wrychtowany adres e-brifa.",
        "createacct-realname": "Prawdźiwe imje a nazwisko (uopcjůnalńe)",
        "searchprofile-images": "Multimedyja",
        "searchprofile-everything": "Wszyjsko",
        "searchprofile-advanced": "Rozszerzůne",
-       "searchprofile-articles-tooltip": "Podszukowaniy we zorcie mian $1",
+       "searchprofile-articles-tooltip": "Podszukowaniy we przestrzyni mian $1",
        "searchprofile-images-tooltip": "Szukej plikōw",
        "searchprofile-everything-tooltip": "Podszukowaniy cołkij zawartości (a tyż zajtōw dyskusyje)",
        "searchprofile-advanced-tooltip": "Podszukowaniy we ôbranych zortach mian",
        "undelete-error-long": "Napotkano felery při wćepywańu nazod plika:\n\n$1",
        "undelete-show-file-confirm": "Jeżeś echt pewny co chcesz uobejzdrzeć wyćepano wersyjo plika „<nowiki>$1</nowiki>” s $2 $3?",
        "undelete-show-file-submit": "Ja",
-       "namespace": "Raum mjan:",
+       "namespace": "Przestrzyń mian:",
        "invert": "Wybjer na uopy",
-       "tooltip-invert": "Uoznacz te pole, coby ukryć půmjany na zajtach we uobranych raumach mjan (a powjůnzanych ze ńimi inkszymi raumami mjan, eli uoznaczůno)",
-       "namespace_association": "powjůnzany raum mjan",
-       "tooltip-namespace_association": "Uoznacz te pole, coby uwzglyndńić zajty dyskusyji i tyjmy powjůnzane ze uobranymi raumami mjan",
+       "tooltip-invert": "Ôznŏcz tyn kastlik, coby skryć pōmiany na zajtach we ôbranych przestrzyniach mian (i swiōnzanych ze nimi inkszymi przestrzyniami mian, eli ôznŏczōno)",
+       "namespace_association": "powiōnzanŏ przestrzyń mian",
+       "tooltip-namespace_association": "Ôznŏcz tyn kastlik, coby zawrzić zajty dyskusyje i tyjmy swiōnzane ze ôbranymi przestrzyniami mian",
        "blanknamespace": "(przodńo)",
        "contributions": "Ajnzac {{GENDER:$1|używocza|używoczki}}",
        "contributions-title": "Wkłod użytkowńika $1",
        "whatlinkshere": "Co sam linkuje",
        "whatlinkshere-title": "Zajty, kere linkujům na \"$1\"",
        "whatlinkshere-page": "Zajta:",
-       "linkshere": "Nastympůjůnce zajty sóm adrésůwane do '''[[:$1]]''':",
-       "nolinkshere": "Żodno zajta ńy je adrésowana do '''[[:$1]]'''.",
-       "nolinkshere-ns": "Žodno zajta ńy je adresowano do '''[[:$1]]''' we wybrany přestřyni mjan.",
+       "linkshere-2": "Nastympůjůnce zajty sóm adrésůwane do '''$1''':",
+       "nolinkshere-2": "Żodno zajta ńy je adrésowana do '''$1'''.",
+       "nolinkshere-ns-2": "Žodno zajta ńy je adresowano do '''$1''' we wybrany přestřyni mjan.",
        "isredirect": "překerowujůnca zajta",
        "istemplate": "dołůnczony muster",
        "isimage": "Link do plika",
        "fileduplicatesearch-result-1": "Ńy ma duplikatu pliku „$1”.",
        "fileduplicatesearch-result-n": "We {{GRAMMAR:MS.lp|{{SITENAME}}}} {{PLURAL:$2|je dodatkowo kopia|sům $2 dodatkowe kopje|je $2 dodatkowych kopii}} plika „$1”.",
        "specialpages": "Szpecjalne zajty",
+       "specialpages-note-restricted": "* Ekstra zajty uogůlńy dostympne.\n* <strong class=\"mw-specialpagerestricted\">Ekstra zajty do kerych dostymp je uograńiczůny.</strong>",
        "specialpages-group-maintenance": "Raporty kůnserwacyjne",
        "specialpages-group-other": "Inkše ekstra zajty",
        "specialpages-group-login": "Logowańy / regisztrowańy",
index 69121fa..b2ffaad 100644 (file)
        "whatlinkshere": "இப்பக்கத்தை இணைத்தவை",
        "whatlinkshere-title": "\"$1\" பக்கத்துக்கு இணைக்கப்பட்டவை",
        "whatlinkshere-page": "பக்கம்:",
-       "linkshere": "'''[[:$1]]''' பின்வரும் பக்கங்களில் இப்பக்கம் இணைக்கப்பட்டுள்ளது:",
-       "nolinkshere": "'''[[:$1]]''' எந்தப் பக்கத்திலும் இந்தப் பக்கம் இணைக்கப்படவில்லை.",
-       "nolinkshere-ns": "தெரிவு செய்யப்பட்ட பெயர்வெளியில் '''[[:$1]]''' பக்கத்துக்கு இணைக்கப்பட்ட பக்கங்கள் எதுவுமில்லை.",
+       "linkshere-2": "'''$1''' பின்வரும் பக்கங்களில் இப்பக்கம் இணைக்கப்பட்டுள்ளது:",
+       "nolinkshere-2": "'''$1''' எந்தப் பக்கத்திலும் இந்தப் பக்கம் இணைக்கப்படவில்லை.",
+       "nolinkshere-ns-2": "தெரிவு செய்யப்பட்ட பெயர்வெளியில் '''$1''' பக்கத்துக்கு இணைக்கப்பட்ட பக்கங்கள் எதுவுமில்லை.",
        "isredirect": "வழிமாற்றுப் பக்கம்",
        "istemplate": "உள்ளிடப்பட்டுள்ளது",
        "isimage": "கோப்பு இணைப்பு",
        "fileduplicatesearch-noresults": "\"$1\" என்ற பெயர் கொண்ட கோப்பு எதுவும் காணப்படவில்லை.",
        "specialpages": "சிறப்புப் பக்கங்கள்",
        "specialpages-note-top": "உள்பட்டியல்",
+       "specialpages-note-restricted": " * சராசரி சிறப்புப் பக்கங்கள்.\n * <span class=\"mw-specialpagerestricted\">வரையறுக்கப்பட்ட சிறப்புப் பக்கங்கள்.</span>",
        "specialpages-group-maintenance": "பராமரிப்பு அறிக்கைகள்",
        "specialpages-group-other": "ஏனைய சிறப்புப் பக்கங்கள்",
        "specialpages-group-login": "புகுபதிகை/பயனர் கணக்கு தொடக்கம்",
index a9a151e..1abd0a4 100644 (file)
        "whatlinkshere": "Aniy p’ubuy tay lpgan sqaniy",
        "whatlinkshere-title": "Aniy ’mubuy sa zngayan tay \"$1\"",
        "whatlinkshere-page": "Zngayan",
-       "linkshere": "Zngayan tay suruw qaniy ga aniy p’ubuy sa <strong>[[:$1]]</strong>:",
-       "nolinkshere": "Ungat zngazyan ’mubuy squw <strong>[[:$1]]</strong>.",
+       "linkshere-2": "Zngayan tay suruw qaniy ga aniy p’ubuy sa <strong>$1</strong>:",
+       "nolinkshere-2": "Ungat zngazyan ’mubuy squw <strong>$1</strong>.",
        "isredirect": "t’ringun pawsa’ sa zngayan",
        "istemplate": "’nagal sa",
        "isimage": "’ubuy sa biru’ na ana nanu’ zayzyuwaw",
index 0b7edba..581b6af 100644 (file)
        "whatlinkshere": "ಇಡೆ ವಾ ಪುಟೊ ಕೊಂಡಿ ಕೊರ್ಪುಂಡು",
        "whatlinkshere-title": "\"$1\" ಕ್ಕ್ ಸಂಪರ್ಕ ಕೊರ್ಪಿನ ಪುಟೊಕುಲು",
        "whatlinkshere-page": "ಪುಟೊ:",
-       "linkshere": "</strong>[[:$1]]<strong>ಗ್ ಈ ತಿರ್ತ್‍ದ ಪುಟೊಕುಲು ಕೊಂಡಿ ಕೊರ್ಪುಂಡು.",
-       "nolinkshere": "'''[[:$1]]''' ಗ್ ವಾ ಪುಟೊಕುಲೆಡ್ಲಾ ಲಿಂಕ್ ಇಜ್ಜಿ.",
+       "linkshere-2": "</strong>$1<strong>ಗ್ ಈ ತಿರ್ತ್‍ದ ಪುಟೊಕುಲು ಕೊಂಡಿ ಕೊರ್ಪುಂಡು.",
+       "nolinkshere-2": "'''$1''' ಗ್ ವಾ ಪುಟೊಕುಲೆಡ್ಲಾ ಲಿಂಕ್ ಇಜ್ಜಿ.",
        "isredirect": "ಪಿರ ನಿರ್ದೇಶನೊದ ಪುಟೊ",
        "istemplate": "ಸೇರಾವುನೆ",
        "isimage": "ಫೈಲ್‍ದ ಕೊಂಡಿ",
index 2442646..ad2fb34 100644 (file)
        "whatlinkshere": "ఇక్కడికి లింకైనవి",
        "whatlinkshere-title": "\"$1\"కి లింకున్న పుటలు",
        "whatlinkshere-page": "పేజీ:",
-       "linkshere": "కింది పేజీల నుండి <strong>[[:$1]]</strong>కు లింకులు ఉన్నాయి:",
-       "nolinkshere": "'''[[:$1]]'''కు ఏ పేజీ నుండీ లింకు లేదు.",
-       "nolinkshere-ns": "'''[[:$1]]''' పేజీకి లింకయ్యే పేజీలు ఎంచుకున్న నేంస్పేసులో లేవు.",
+       "linkshere-2": "కింది పేజీల నుండి <strong>$1</strong>కు లింకులు ఉన్నాయి:",
+       "nolinkshere-2": "'''$1'''కు ఏ పేజీ నుండీ లింకు లేదు.",
+       "nolinkshere-ns-2": "'''$1''' పేజీకి లింకయ్యే పేజీలు ఎంచుకున్న నేంస్పేసులో లేవు.",
        "isredirect": "దారిమార్పు పుట",
        "istemplate": "పేజీకి జతపరిచారు",
        "isimage": "దస్త్రపు లంకె",
        "fileduplicatesearch-noresults": "\"$1\" అనే పేరుగల దస్త్రమేమీ కనబడలేదు.",
        "specialpages": "ప్రత్యేక పేజీలు",
        "specialpages-note-top": "సూచిక",
+       "specialpages-note-restricted": "* మామూలు ప్రత్యేక పుటలు.\n* <span class=\"mw-specialpagerestricted\">నియంత్రిత ప్రత్యేక పుటలు.</span>",
        "specialpages-group-maintenance": "నిర్వహణా నివేదికలు",
        "specialpages-group-other": "ఇతర ప్రత్యేక పేజీలు",
        "specialpages-group-login": "లాగినవండి / ఖాతా సృష్టించుకోండి",
index bc23697..56000b2 100644 (file)
        "whatlinkshere": "Artigu sira ne'ebé bá iha ne'e",
        "whatlinkshere-title": "Pájina sira ne'ebé bá \"$1\".",
        "whatlinkshere-page": "Pájina:",
-       "linkshere": "Pájina sira ne'e link ba '''[[:$1]]''':",
+       "linkshere-2": "Pájina sira ne'e link ba '''$1''':",
        "isimage": "ligasaun ba fixeiru",
        "whatlinkshere-prev": "{{PLURAL:$1|oinmai|oinmai $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|molok|molok $1}}",
index e73941a..c7931cf 100644 (file)
        "whatlinkshere": "Пайвандҳои дар ин сахифа",
        "whatlinkshere-title": "Саҳифаҳое ки ба $1 пайванд доранд",
        "whatlinkshere-page": "Саҳифа:",
-       "linkshere": "Саҳифаҳои зерин ба '''[[:$1]]''' пайванданд:",
-       "nolinkshere": "Ягон саҳифа ба '''[[:$1]]''' пайванд нест.",
-       "nolinkshere-ns": "Ҳеҷ саҳифа аз фазоиноми интихобшуда ба '''[[:$1]]''' пайванд надорад.",
+       "linkshere-2": "Саҳифаҳои зерин ба '''$1''' пайванданд:",
+       "nolinkshere-2": "Ягон саҳифа ба '''$1''' пайванд нест.",
+       "nolinkshere-ns-2": "Ҳеҷ саҳифа аз фазоиноми интихобшуда ба '''$1''' пайванд надорад.",
        "isredirect": "саҳифаи тағйири масир",
        "istemplate": "истифодашуда дар саҳифа",
        "isimage": "пайванд ба парванда",
index 1076f8c..129b5a4 100644 (file)
        "whatlinkshere": "Pajvandhoi dar in saxifa",
        "whatlinkshere-title": "Sahifahoe ki ba $1 pajvand dorand",
        "whatlinkshere-page": "Sahifa:",
-       "linkshere": "Sahifahoi zerin ba '''[[:$1]]''' pajvandand:",
-       "nolinkshere": "Jagon sahifa ba '''[[:$1]]''' pajvand nest.",
-       "nolinkshere-ns": "Heç sahifa az fazoinomi intixobşuda ba '''[[:$1]]''' pajvand nadorad.",
+       "linkshere-2": "Sahifahoi zerin ba '''$1''' pajvandand:",
+       "nolinkshere-2": "Jagon sahifa ba '''$1''' pajvand nest.",
+       "nolinkshere-ns-2": "Heç sahifa az fazoinomi intixobşuda ba '''$1''' pajvand nadorad.",
        "isredirect": "sahifai taƣjiri masir",
        "istemplate": "istifodaşuda dar sahifa",
        "isimage": "pajvandi aks",
index dc85fa6..9671e93 100644 (file)
        "whatlinkshere": "หน้าที่ลิงก์มา",
        "whatlinkshere-title": "หน้าที่ลิงก์มา \"$1\"",
        "whatlinkshere-page": "หน้า:",
-       "linkshere": "หน้าต่อไปนี้ลิงก์มา <strong>[[:$1]]</strong>:",
-       "nolinkshere": "ไม่มีหน้าใดลิงก์มา <strong>[[:$1]]</strong>",
-       "nolinkshere-ns": "ไม่มีหน้าใดลิงก์มา <strong>[[:$1]]</strong> ในเนมสเปซที่เลือก",
+       "linkshere-2": "หน้าต่อไปนี้ลิงก์มา <strong>$1</strong>:",
+       "nolinkshere-2": "ไม่มีหน้าใดลิงก์มา <strong>$1</strong>",
+       "nolinkshere-ns-2": "ไม่มีหน้าใดลิงก์มา <strong>$1</strong> ในเนมสเปซที่เลือก",
        "isredirect": "หน้าเปลี่ยนทาง",
        "istemplate": "โดยใช้แม่แบบ",
        "isimage": "ลิงก์ไฟล์",
index 27d7d6f..6d99da1 100644 (file)
        "whatlinkshere": "Şu ýere çykgytlar",
        "whatlinkshere-title": "\"$1\" makalasyna çykgyt berýän sahypalar",
        "whatlinkshere-page": "Sahypa:",
-       "linkshere": "'''[[:$1]]''' sahypasyna çykgyt berýän sahypalar:",
-       "nolinkshere": "'''[[:$1]]''' sahypasyna çykgyt berýän sahypa ýok.",
-       "nolinkshere-ns": "Saýlanyp alynan at giňişliginde hiçbir sahypa '''[[:$1]]''' sahypasyna çykgyt bermeýär.",
+       "linkshere-2": "'''$1''' sahypasyna çykgyt berýän sahypalar:",
+       "nolinkshere-2": "'''$1''' sahypasyna çykgyt berýän sahypa ýok.",
+       "nolinkshere-ns-2": "Saýlanyp alynan at giňişliginde hiçbir sahypa '''$1''' sahypasyna çykgyt bermeýär.",
        "isredirect": "gönükdirme sahypasy",
        "istemplate": "atanaklaýyn girizme",
        "isimage": "faýl çykgydy",
        "fileduplicatesearch-result-1": "\"$1\" faýlynyň meňzeş dublikaty ýok.",
        "fileduplicatesearch-result-n": "\"$1\" faýlynyň {{PLURAL:$2|1 sany meňzeş dublikaty|$2 sany meňzeş dublikaty}} bar.",
        "specialpages": "Ýörite sahypalar",
+       "specialpages-note-restricted": "* Adaty ýörite sahypalar.\n* <strong class=\"mw-specialpagerestricted\">Çäklendirilen ýörite sahypalar.</strong>",
        "specialpages-group-maintenance": "Tehniki abatlaýyş hasabatlary",
        "specialpages-group-other": "Başga ýörite sahypalar",
        "specialpages-group-login": "Hasaba gir / täze hasap aç",
index 6266763..d3c3087 100644 (file)
        "whatlinkshere": "Mga nakaturo dito",
        "whatlinkshere-title": "Mga pahinang kumakawing sa $1",
        "whatlinkshere-page": "Pahina:",
-       "linkshere": "Nakakawing ang sumusunod na mga pahina sa '''[[:$1]]''':",
-       "nolinkshere": "Walang pahinang nakakawing sa '''[[:$1]]'''.",
-       "nolinkshere-ns": "Walang pahinang nakakawing sa '''[[:$1]]''' mula sa loob ng napiling espasyo ng pangalan.",
+       "linkshere-2": "Nakakawing ang sumusunod na mga pahina sa '''$1''':",
+       "nolinkshere-2": "Walang pahinang nakakawing sa '''$1'''.",
+       "nolinkshere-ns-2": "Walang pahinang nakakawing sa '''$1''' mula sa loob ng napiling espasyo ng pangalan.",
        "isredirect": "pahinang panturo/panuto",
        "istemplate": "pagsasali",
        "isimage": "link ng file",
        "fileduplicatesearch-result-n": "Ang talaksan na \"$1\" ay may {{PLURAL:$2|1 kapareho|$2 mga kapareho}}.",
        "fileduplicatesearch-noresults": "Walang natagpuang talaksan na may pangalang \"$1\".",
        "specialpages": "Mga natatanging pahina",
+       "specialpages-note-restricted": "* Normal na natatanging mga pahina.\n* <span class=\"mw-specialpagerestricted\">Pinaghihigpitang natatanging mga pahina.</span>",
        "specialpages-group-maintenance": "Mga pagpapanatiling ulat",
        "specialpages-group-other": "Iba pang natatanging mga pahina",
        "specialpages-group-login": "Mag-login / lumikha ng account",
index 02f50c0..fe377e5 100644 (file)
        "whatlinkshere": "Сәбонон ијо",
        "whatlinkshere-title": "Сәһифон, сәбон вардән бә \"$1\"",
        "whatlinkshere-page": "Сәһифә:",
-       "linkshere": "Ым сәһифон сәбон вардән ијо ''[[:$1]]''':",
-       "nolinkshere": "Бә ым сәһифә ҹо сәһифонку сәбонон нин '''[[:$1]]'''.",
+       "linkshere-2": "Ым сәһифон сәбон вардән ијо ''$1''':",
+       "nolinkshere-2": "Бә ым сәһифә ҹо сәһифонку сәбонон нин '''$1'''.",
        "isredirect": "унвони дәгиш кардә сәһифәје",
        "istemplate": "әловә",
        "isimage": "фајлинә сәбон",
index 422b905..c9a65d6 100644 (file)
        "sp-contributions-talk": "Alea",
        "whatlinkshere": "Ngaahi fehokotaki ki heni",
        "whatlinkshere-page": "Peesi:",
-       "linkshere": "ʻOku fehokotaki ki heni ʻa e ngaahi peesi:",
-       "nolinkshere": "ʻOku ʻikai ha ngaahi kupu fehokotaki ki heni.",
+       "linkshere-2": "!!FUZZY!!ʻOku fehokotaki ki heni ʻa e ngaahi peesi:",
+       "nolinkshere-2": "!!FUZZY!!ʻOku ʻikai ha ngaahi kupu fehokotaki ki heni.",
        "isredirect": "Peesi leʻei",
        "istemplate": "kātoi",
        "whatlinkshere-links": "← fehokotaki",
index 0226e5c..fcbe9af 100644 (file)
        "botpasswords-existing": "Mevcut bot parolaları",
        "botpasswords-createnew": "Yeni bir bot parolası oluştur",
        "botpasswords-editexisting": "Mevcut bir bot parolasını düzenle",
+       "botpasswords-label-needsreset": "(parolanın sıfırlanması gerekiyor)",
        "botpasswords-label-appid": "Bot ismi:",
        "botpasswords-label-create": "Oluştur",
        "botpasswords-label-update": "Güncelle",
        "botpasswords-no-provider": "BotPasswordsSessionProvider kullanılamaz.",
        "botpasswords-restriction-failed": "Bot parolası kısıtlamaları bu oturum açma işlemini önlemektedir.",
        "botpasswords-invalid-name": "Belirtilen kullanıcı adı bot parolası ayırıcısı içermiyor (\"$1\").",
+       "botpasswords-needs-reset": "\"$1\" {{GENDER:$1|kullanıcısına}} ait \"$2\" adlı bot için bot parolası sıfırlanmalı.",
        "resetpass_forbidden": "Parolalar değiştirilememektedir",
        "resetpass_forbidden-reason": "Parolalar değiştirilemez: $1",
        "resetpass-no-info": "Bu sayfaya doğrudan erişmek için oturum açmanız gereklidir.",
        "subject-preview": "Konu ön izlemesi:",
        "previewerrortext": "Yaptığınız değişikliklerin önizlemesi sırasında bir hata oluştu.",
        "blockedtitle": "Kullanıcı erişimi engellendi.",
-       "blockedtext": "'''Kullanıcı adı veya IP adresiniz engellenmiştir.'''\n\nSizi engelleyen hizmetli: $1.<br />\nEngelleme sebebi: ''$2''.\n\n* Engellenmenin başlangıcı: $8\n* Engellenmenin bitişi: $6\n* Engellenme süresi: $7\n\nBelirtilen nedene göre engellenmenizin uygun olmadığını düşünüyorsanız, $1 ya da başka bir [[{{MediaWiki:Grouppage-sysop}}|hizmetli]] ile bu durumu görüşebilirsiniz. [[Special:Preferences|Tercihlerim]] kısmında geçerli bir e-posta adresi girmediyseniz \"Kullanıcıya e-posta gönder\" özelliğini kullanamazsınız, tercihlerinize e-posta adresinizi eklediğinizde e-posta gönderme hakkına sahip olacaksınız.\n<br />Şu anki IP adresiniz $3, engellenme numaranız #$5.\n<br />Bir hizmetliden durumunuz hakkında bilgi almak istediğinizde veya herhangi bir sorguda bu bilgiler gerekecektir, lütfen not ediniz.",
+       "blockedtext": "<strong>Kullanıcı adı veya IP adresiniz engellenmiştir.</strong>\n\nSizi engelleyen hizmetli: $1.<br />\nEngelleme sebebi: <em>$2</em>.\n\n* Engellenmenin başlangıcı: $8\n* Engellenmenin bitişi: $6\n* Engellenme süresi: $7\n\nBelirtilen nedene göre engellenmenizin uygun olmadığını düşünüyorsanız, $1 ya da başka bir [[{{MediaWiki:Grouppage-sysop}}|hizmetli]] ile bu durumu görüşebilirsiniz. [[Special:Preferences|Tercihlerim]] kısmında geçerli bir e-posta adresi girmediyseniz \"Kullanıcıya e-posta gönder\" özelliğini kullanamazsınız, tercihlerinize e-posta adresinizi eklediğinizde e-posta gönderme hakkına sahip olacaksınız.\n<br />Şu anki IP adresiniz $3, engellenme numaranız #$5.\n<br />Bir hizmetliden durumunuz hakkında bilgi almak istediğinizde veya herhangi bir sorguda bu bilgiler gerekecektir, lütfen not ediniz.",
        "autoblockedtext": "IP adresiniz otomatik olarak engellendi, çünkü $1 tarafından engellenmiş başka bir kullanıcı tarafından kullanılmaktaydı.\nBelirtilen sebep şudur:\n\n:''$2''\n\n* Engellemenin başlangıcı: $8\n* Engellemenin bitişi: $6\n* Bloke edilmesi istenen: $7\n\nEngelleme hakkında tartışmak için $1 ile veya diğer [[{{MediaWiki:Grouppage-sysop}}|hizmetlilerden]] biriyle irtibata geçebilirsiniz.\n\nNot, [[Special:Preferences|kullanıcı tercihlerinize]] geçerli bir e-posta adresi kaydetmediyseniz  \"kullanıcıya e-posta gönder\" özelliğinden faydalanamayabilirsiniz ve bu özelliği kullanmaktan engellenmediniz.\n\nŞu anki IP numaranız $3 ve engellenme ID'niz #$5.\nLütfen yapacağınız herhangi bir sorguda yukarıdaki bütün detayları bulundurun.",
        "blockednoreason": "sebep verilmedi",
        "whitelistedittext": "Değişiklik yapabilmek için $1.",
        "whatlinkshere": "Sayfaya bağlantılar",
        "whatlinkshere-title": "\"$1\" sayfasına bağlantı veren sayfalar",
        "whatlinkshere-page": "Sayfa:",
-       "linkshere": "'''[[:$1]]''' sayfasına bağlantısı olan sayfalar:",
-       "nolinkshere": "'''[[:$1]]''' sayfasına bağlantı veren sayfa yok.",
-       "nolinkshere-ns": "Seçilen ad alanında hiçbir sayfa '''[[:$1]]''' sayfasına bağlanmıyor.",
+       "linkshere-2": "'''$1''' sayfasına bağlantısı olan sayfalar:",
+       "nolinkshere-2": "'''$1''' sayfasına bağlantı veren sayfa yok.",
+       "nolinkshere-ns-2": "Seçilen ad alanında hiçbir sayfa '''$1''' sayfasına bağlanmıyor.",
        "isredirect": "yönlendirme sayfası",
        "istemplate": "dönüştürülme",
        "isimage": "dosya bağlantısı",
index 405c5cb..be26c1f 100644 (file)
        "whatlinkshere": "Asirwoṭo biFaṭaṭe",
        "whatlinkshere-title": "Faṭoṭe dkitte Asiruṭo 3am\"$1\"",
        "whatlinkshere-page": "Faṭo",
-       "linkshere": "aFaṭoṭani masre ne 3am '''[[:$1]]''':",
-       "nolinkshere": "Layto Faṭoṭe dkitte Asiruṭo 3am '''[[:$1]]'''.",
+       "linkshere-2": "aFaṭoṭani masre ne 3am '''$1''':",
+       "nolinkshere-2": "Layto Faṭoṭe dkitte Asiruṭo 3am '''$1'''.",
        "isredirect": "redirect page",
        "istemplate": "transclusion",
        "isimage": "Asiruṭo duFayl",
index 06917aa..b541bc6 100644 (file)
        "whatlinkshere": "Leswi khwekelaka laha",
        "whatlinkshere-title": "Matluka lama khwekelaka eka $1",
        "whatlinkshere-page": "Tluka:",
-       "linkshere": "Matluka lama landzelaka makhwekela eka '''[[:$1]]''':",
-       "nolinkshere": "Kuhava matluka lama khwekelaka eka  '''[[:$1]]'''.",
+       "linkshere-2": "Matluka lama landzelaka makhwekela eka '''$1''':",
+       "nolinkshere-2": "Kuhava matluka lama khwekelaka eka  '''$1'''.",
        "isredirect": "Tluka ro kongomisa",
        "istemplate": "Swisivela ndhzawu",
        "isimage": "Xikhwekerisi xa fayili",
index c15d558..b262214 100644 (file)
@@ -59,7 +59,7 @@
        "tog-shownumberswatching": "Битне күзәтү исемлекләренә өстәгән кулланучылар санын күрсәтелсен",
        "tog-oldsig": "Хәзерге имзагыз:",
        "tog-fancysig": "Имзаның шәхси вики-билгеләмәсе (автоматик сылтамасыз)",
-       "tog-uselivepreview": "Тиз карап алуны куллану",
+       "tog-uselivepreview": "Ð\91иÑ\82не Ñ\8fңаÑ\80Ñ\82мÑ\8bйÑ\87а Ñ\82из карап алуны куллану",
        "tog-forceeditsummary": "Үзгәртүләрне тасвирлау юлы тутырылмаган булса, кисәтү",
        "tog-watchlisthideown": "Минем үзгәртүләрем күзәтү исемлегеннән яшерелсен",
        "tog-watchlisthidebots": "Бот үзгәртүләре күзәтү исемлегеннән яшерелсен",
        "virus-scanfailed": "сканерлау хатасы ($1 коды)",
        "virus-unknownscanner": "билгесез антивирус:",
        "logouttext": "<strong>Сез хисап язмагыздан чыктыгыз.</strong>\n\nКайбер битләр Сез кергән кебек күрсәтелергә мөмкин. Моны бетерү өчен браузер кэшын чистартыгыз.",
+       "cannotlogoutnow-title": "Хәзер үк чыгып булмый",
        "welcomeuser": "Рәхим итегез, $1!",
        "yourname": "Кулланучы исеме:",
        "userlogin-yourname": "Кулланучы исеме",
        "createacct-yourpasswordagain-ph": "Серсүзне кабаттан кертегез",
        "userlogin-remembermypassword": "Системада калырга",
        "userlogin-signwithsecure": "Якланган кушылу",
+       "cannotlogin-title": "Чыгып булмый",
+       "cannotlogin-text": "Системага керү мөмкин түгел.",
+       "cannotloginnow-title": "Хәзер үк кереп булмый",
        "yourdomainname": "Доменыгыз:",
        "password-change-forbidden": "Сез бу викидә серсүзне үзгәртә алмыйсыз.",
        "externaldberror": "Тышкы мәгълүмат базасы ярдәмендә аутентификация үткәндә хата чыкты, яисә тышкы хисап язмагызга үзгәрешләр кертү хокукыгыз юк.",
        "nosuchusershort": "$1 исемле кулланучы юк. Язылышыгызны тикшерегез.",
        "nouserspecified": "Сез теркәү исмегезне күрсәтергә тиешсез.",
        "login-userblocked": "Бу кулланучы тыелды. Керү тыелган.",
-       "wrongpassword": "ЯзÑ\8bлган Ñ\81еÑ\80Ñ\81үз Ð´Ó©Ñ\80еÑ\81 Ñ\82үгел. Ð¢Ð°Ð³Ñ\8bн Ð±ÐµÑ\80 Ñ\82апкÑ\8bÑ\80 Ñ\81Ñ\8bнагыз.",
+       "wrongpassword": "СеÑ\80Ñ\81үз Ñ\8fиÑ\81Ó\99 ÐºÑ\83лланÑ\83Ñ\87Ñ\8b Ð¸Ñ\81еме Ð´Ó©Ñ\80еÑ\81 Ñ\82үгел. Ð¯Ò£Ð°Ð´Ð°Ð½ Ò\97Ñ\8bеп ÐºÐ°Ñ\80агыз.",
        "wrongpasswordempty": "Серсүз юлы буш булырга тиеш түгел.",
        "passwordtooshort": "Сезсүз кимендә $1 {{PLURAL:$1|символдан}} торырга тиеш.",
        "password-name-match": "Кертелгән серсүз кулланучы исеменнән аерылырга тиеш.",
        "nowiki_tip": "Вики-форматлауны исәпкә алмау",
        "image_sample": "Мисал.jpg",
        "image_tip": "Куелган файл",
+       "media_sample": "Мисал.ogg",
        "media_tip": "Файлга сылтама",
        "sig_tip": "Имза һәм вакыт",
        "hr_tip": "Горизонталь сызык (еш кулланмагыз)",
        "savechanges": "Үзгәртүләрне саклау",
        "publishpage": "Бит ясау",
        "publishchanges": "Битне бастыру",
+       "savearticle-start": "Битне саклау...",
+       "savechanges-start": "Үзгәртүләрне саклау...",
+       "publishpage-start": "Битне бастыру...",
+       "publishchanges-start": "Төзәтмәләрне бастыру...",
        "preview": "Алдан карау",
        "showpreview": "Алдан карау",
        "showdiff": "Кертелгән үзгәртүләр",
        "anoneditwarning": "<strong>Игътибар!</strong> Сез сайтта теркәлмәдегез. Әгәрдә сез нинди дә булсә төзәтмәләр яисә үзгәртүләр кертсәгез, сезнең IP-адрес башка кулланучыларга да билгеле булачак. Сайтка <strong>[$1 керсәгез]</strong> яисә <strong>[$2 кулланучы язмасын төзесәгез]</strong>, сез керткән үзгәртүләр сезнең кулланучы язмагызга бәйләнгән булачак, шулай ук башка мөмкинлекләр дә туачак.",
        "anonpreviewwarning": "''Сез системада теркәлмәдегез.Сезнең тарафтан эшләнгән барлык үзгәртүләр дә сезнең IP-юлламагызны саклауга китерә.''",
        "missingsummary": "'''Искәртү.''' Сез үзгәртүгә кыскача тасвирлау язмадыгыз. Сез «Битне саклау» төймәсенә тагын бер тапкыр бассагыз, үзгәртүләр тасвирламасыз сакланачак.",
-       "missingcommenttext": "Ð\90Ñ\81ка Ñ\82аÑ\81виÑ\80лама язуыгыз сорала.",
+       "missingcommenttext": "Ð\9aомменÑ\82 язуыгыз сорала.",
        "missingcommentheader": "<strong>Искәртү:</strong> Сез шәрехнең темасын күрсәтмәгәнсез.\n«$1» төймәсенә кабат бассагыз, үзгәртүләр темасыз язылачак.",
        "summary-preview": "Төзәтмәләрне карап чыгу:",
        "subject-preview": "Башисемне алдан карау:",
        "search-interwiki-caption": "Тугандаш проектлар нәтиҗәсе",
        "search-interwiki-default": "$1 нәтиҗә:",
        "search-interwiki-more": "(тагын)",
+       "search-interwiki-more-results": "күбрәк нәтиҗәләр",
        "search-relatedarticle": "Бәйле",
        "searchrelated": "бәйле",
        "searchall": "барлык",
        "prefs-watchlist-edits": "Киңәйтелгән күзәтү исемлегендә күрсәтелүче төзәтмәләрнең максималь саны:",
        "prefs-watchlist-edits-max": "Максимум сан: 1000",
        "prefs-watchlist-token": "Күзәтү исемлеге токены:",
+       "prefs-watchlist-managetokens": "Токеннар беләр идарә итү",
        "prefs-misc": "Башка көйләнмәләр",
        "prefs-resetpass": "Серсүзне үзгәртү",
        "prefs-changeemail": "Электрон әрҗә адресын үзгәртү яисә бетерү",
+       "prefs-setemail": "Электрон почта адресын көйләү",
        "prefs-email": "E-mail көйләнмәләре",
        "prefs-rendering": "Күренеш",
        "saveprefs": "Саклау",
        "recentchangesdays": "Соңгы үзгәртүләрне күрсәтүче көннәр саны:",
        "recentchangesdays-max": "(иң күбе $1 {{PLURAL:$1|көн}})",
        "recentchangescount": "Төп буларак кулланучы үзгәртүләр саны:",
-       "prefs-help-recentchangescount": "Үз өченә үзгәртүләрне, битләрнең тарихын һәм язлу көндәлеген дә кертә.",
+       "prefs-help-recentchangescount": "Максимум сан: 1000",
        "prefs-help-watchlist-token2": "Бу сезнең кузәтү исемлеге өчен ясалган веб-агымының серле ачкычы.\nАны белгән һәркем сезнең күзәтү исемлегегезне карый ала, шуңа да башкаларга аны күрсәтмәгез. [[Special:ResetTokens|Ачкычны ташларга теләсәгез, әлеге юрамага басыгыз]].",
        "savedprefs": "Көйләнмәләрегез сакланды.",
        "timezonelegend": "Сәгать поясы:",
        "timezoneregion-europe": "Аурупа",
        "timezoneregion-indian": "Һинд океаны",
        "timezoneregion-pacific": "Тын океан",
-       "allowemail": "Ð\91аÑ\88ка ÐºÑ\83лланÑ\83Ñ\87Ñ\8bлаÑ\80дан Ñ\85аÑ\82лаÑ\80 Ð°Ð»Ñ\8bÑ\80га Ñ\80Ó©Ñ\85Ñ\81Ó\99Ñ\82 Ð¸Ñ\82елÑ\81ен",
+       "allowemail": "Ð\91аÑ\88ка ÐºÑ\83лланÑ\83Ñ\87Ñ\8bлаÑ\80га Ð¼Ð¸Ò£Ð° Ñ\85аÑ\82лаÑ\80 Ñ\8fзаÑ\80га Ñ\80Ó©Ñ\85Ñ\81Ó\99Ñ\82 Ð¸Ñ\82Ò¯",
        "prefs-searchoptions": "Эзләү",
        "prefs-namespaces": "Исемнәр мәйданы",
        "default": "килешү буенча",
        "prefs-files": "Файллар",
        "prefs-custom-css": "Шәхси CSS",
+       "prefs-custom-json": "Кулланма JSON",
        "prefs-custom-js": "Шәхси JS",
-       "prefs-common-config": "Барлык бизәлешләр өчен гомуми CSS/JS:",
+       "prefs-common-config": "Барлык бизәлешләр өчен гомуми CSS/JSON/JavaScript:",
        "prefs-reset-intro": "Бу бит сезнең көйләнмәләрегезне бетерү өчен кулланыла. Бу эшне башкару нәтиҗәсендә сез яңадан үз көйләнмәләрне яңадан кайтара алмыйсыз.",
        "prefs-emailconfirm-label": "E-mail раслау",
        "youremail": "Электрон почта:",
        "username": "{{GENDER:$1|Кулланучы исеме}}:",
        "prefs-memberingroups": "{{PLURAL:$1|Төркем}} {{GENDER:$2|әгъзасы}}:",
        "prefs-memberingroups-type": "$1",
+       "group-membership-link-with-expiry": "$1 ($2 кадәр)",
        "prefs-registration": "Теркәлү вакыты:",
        "prefs-registration-date-time": "$1",
        "yourrealname": "Чын исем:",
        "prefs-dateformat": "Вакытың форматы",
        "prefs-timeoffset": "Вакыт билгеләнеше",
        "prefs-advancedediting": "Гомуми көйләүләр",
+       "prefs-developertools": "Девелопер кораллары",
        "prefs-editor": "Мөхәррир",
        "prefs-preview": "Алдан карау",
        "prefs-advancedrc": "Киңәйтелгән көйләүләр",
        "userrights-changeable-col": "Сезнең тарафтан үзгәртелми торган төркемнәр",
        "userrights-unchangeable-col": "Сезнең тарафтан үзгәртелми торган төркемнәр",
        "userrights-irreversible-marker": "$1*",
+       "userrights-expiry": "Бетә:",
+       "userrights-expiry-othertime": "Башка вакыт:",
+       "userrights-expiry-options": "1 көн:1 day,1 атна:1 week,1 ай:1 month,3 ай:3 months,6 ай:6 months,1 ел:1 year",
        "userrights-conflict": "Кулланучы хокукларын үзгәртү конфликты! Төзәтмәләрегезне тикшерегез, аннары кабатлагыз.",
        "group": "Төркем:",
        "group-user": "Кулланучылар",
        "recentchanges-legend-heading": "<strong>Аңлатма:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (шулай ук [[Special:NewPages|яңа битләр исемлеген]] карагыз)",
        "recentchanges-submit": "Күрсәт",
+       "rcfilters-legend-heading": "<strong>Кыскартулар тезмәсе:&nbsp;</strong>",
        "rcfilters-activefilters": "Актив фильтрлар",
        "rcfilters-limit-title": "Күрсәтү өчен үзгәртүләр",
        "rcfilters-days-title": "Соңгы көннәр",
        "rcfilters-hours-title": "Соңгы сәгатьләр",
-       "rcfilters-days-show-days": "$1 көн",
-       "rcfilters-days-show-hours": "$1 сәгать",
+       "rcfilters-days-show-days": "$1 {{PLURAL:$1|көн}}",
+       "rcfilters-days-show-hours": "$1 {{PLURAL:$1|сәгать}}",
        "rcfilters-quickfilters": "Сакланган фильтрлар",
+       "rcfilters-savedqueries-remove": "Бетерү",
+       "rcfilters-savedqueries-new-name-label": "Исем",
+       "rcfilters-savedqueries-cancel-label": "Баш тарту",
        "rcfilters-savedqueries-add-new-title": "Хәзерге фильтр көйләнмәләрен саклау",
        "rcfilters-clear-all-filters": "Барлык филтерләрне чистарту",
        "rcfilters-search-placeholder": "Фильтрланы соңгы үзгәртү (карау яисә кертүне башлау)",
        "rcfilters-filter-editsbyself-label": "Сезнең үзгәртүләр",
        "rcfilters-filter-editsbyself-description": "Сезнең кертемегез.",
        "rcfilters-filter-editsbyother-label": "Башка кулланучыларның үзгәртүләре",
-       "rcfilters-filter-user-experience-level-registered-label": "Теркәлгән",
+       "rcfilters-filter-user-experience-level-registered-label": "Теркәлүчеләр",
        "rcfilters-filter-user-experience-level-registered-description": "Теркәлгән мөхәррирләр.",
        "rcfilters-filter-user-experience-level-unregistered-label": "Теркәлмәгәннәр",
        "rcfilters-filter-user-experience-level-unregistered-description": "Системага кермәгән мөхәррирләр.",
        "rcfilters-filter-user-experience-level-experienced-label": "Тәҗрибәле кулланучылар",
        "rcfilters-filter-user-experience-level-experienced-description": "Төзәтүләре 500 дән күбрәк һәм актив эш көннәре 30 дан артык теркәлгән мөхәррирләр",
        "rcfilters-filtergroup-automated": "Автоматлаштырылган кертем",
+       "rcfilters-filter-bots-label": "Бот",
        "rcfilters-filter-bots-description": "Автоматлаштырылган кораллар ярдәмендә ясалган үзгәртүләр.",
        "rcfilters-filter-humans-label": "Кеше (бот түгел)",
        "rcfilters-filter-humans-description": "Кешеләр ясаган үзгәртүләр.",
+       "rcfilters-filtergroup-reviewstatus": "Тикшерү статусы",
        "rcfilters-filter-minor-label": "Кече үзгәртүләр",
        "rcfilters-filter-minor-description": "«Кече үзгәртү» дип тамгаланган үзгәртүләр",
        "rcfilters-filter-major-label": "Гади үзгәртүләр",
        "rcfilters-filter-previousrevision-description": "«Соңгы юрама» булмаган барлык үзгәртүләр.",
        "rcfilters-view-tags": "Тәгләнгән үзгәртүләр",
        "rcfilters-liveupdates-button": "Автоматик яңарту",
+       "rcfilters-watchlist-markseen-button": "Бар үзгәртүләрне каралган дип билгеләргә",
+       "rcfilters-watchlist-edit-watchlist-button": "Күзәтү исемлегегезне үзгәртү",
        "rcnotefrom": "Астарак <strong>$3, $4</strong> өчен {{PLURAL:$5|үзгәртүләр күрсәтелгән}} (<strong>$1</strong> артык түгел).",
        "rclistfrom": "$3 $2 башлап яңа үзгәртүләрне күрсәт",
        "rcshowhideminor": "кече үзгәртүләрне $1",
        "recentchangeslinked-feed": "Бәйләнешле үзгәртүләр",
        "recentchangeslinked-toolbox": "Бәйләнешле үзгәртүләр",
        "recentchangeslinked-title": "\"$1\" битенә бәйләнешле үзгәртүләр",
-       "recentchangeslinked-summary": "Ð\91Ñ\83 ÐºÒ¯Ñ\80Ñ\81Ó\99Ñ\82елгÓ\99н Ð±Ð¸Ñ\82 Ð±ÐµÐ»Ó\99н Ñ\81Ñ\8bлÑ\82алган (йÓ\99 ÐºÒ¯Ñ\80Ñ\81Ó\99Ñ\82елгÓ\99н Ñ\82Ó©Ñ\80кемгÓ\99 ÐºÐµÑ\80Ñ\82кÓ\99н) Ð±Ð¸Ñ\82лÓ\99Ñ\80нең Ò¯Ð·Ð³Ó\99Ñ\80Ñ\82елмÓ\99лÓ\99Ñ\80е Ð¸Ñ\81емлеге. [[Special:Watchlist|Күзәтү исемлегегезгә]] керә торган битләр '''калын''' итеп күрсәтелгән.",
+       "recentchangeslinked-summary": "Ð\91Ñ\83 Ð±Ð¸Ñ\82Ñ\82Ñ\82Ó\99н Ñ\8fиÑ\81Ó\99 Ð±Ñ\83 Ð±Ð¸Ñ\82кÓ\99 Ñ\81Ñ\8bлÑ\82аган Ð±Ð¸Ñ\82лÓ\99Ñ\80дÓ\99ге Ò¯Ð·Ð³Ó\99Ñ\80Ñ\82мÓ\99ле ÐºÐ°Ñ\80аÑ\83 Ó©Ñ\87ен Ð±Ð¸Ñ\82нең Ð¸Ñ\81емен ÐºÐµÑ\80Ñ\82егез. (Ð\91илгеле Ð±ÐµÑ\80 Ñ\82Ó©Ñ\80кемгÓ\99 ÐºÐ°Ñ\80аган Ð±Ð¸Ñ\82лÓ\99Ñ\80не ÐºÐ°Ñ\80аÑ\83 Ó©Ñ\87ен {{ns:category}}:ТөÑ\80кем Ð¸Ñ\81емен Ñ\8fзÑ\8bгÑ\8bз).[[Special:Watchlist|Күзәтү исемлегегезгә]] керә торган битләр '''калын''' итеп күрсәтелгән.",
        "recentchangeslinked-page": "Битнең исеме:",
        "recentchangeslinked-to": "Моның урынына бу биткә бәйле булган битләрдәге үзгәртүләрне күрсәтү",
        "upload": "Файл йөкләү",
        "whatlinkshere": "Бирегә нәрсә сылтый",
        "whatlinkshere-title": "$1 битенә сылтый торган битләр",
        "whatlinkshere-page": "Бит:",
-       "linkshere": "'''[[:$1]]''' битенә чираттагы битләр сылтый:",
-       "nolinkshere": "'''[[:$1]]''' битенә башка битләр сылтамыйлар.",
+       "linkshere-2": "'''$1''' битенә чираттагы битләр сылтый:",
+       "nolinkshere-2": "'''$1''' битенә башка битләр сылтамыйлар.",
        "isredirect": "юнәлтү бите",
        "istemplate": "кертүләр",
        "isimage": "файл сылтамасы",
        "fileduplicatesearch": "Бер үк файлларны эзләү",
        "fileduplicatesearch-submit": "Эзләү",
        "specialpages": "Махсус битләр",
+       "specialpages-note-restricted": "* Гади махсус битләр.\n* <span class=\"mw-specialpagerestricted\">Чикләнелгән махсус битләр.</span>",
        "specialpages-group-maintenance": "Техник карау хисапнамәсе",
        "specialpages-group-other": "Башка махсус битләр",
        "specialpages-group-login": "Керү / Теркәлү",
index da6e606..35aa487 100644 (file)
        "whatlinkshere": "Biregä närsä sıltıy",
        "whatlinkshere-title": "$1 bitenä sıltıy torğan bitlär",
        "whatlinkshere-page": "Bit:",
-       "linkshere": "'''[[:$1]]''' bitenä çirattağı bitlär sıltıy:",
-       "nolinkshere": "'''[[:$1]]''' bitenä başqa bitlär sıltamıylar.",
+       "linkshere-2": "'''$1''' bitenä çirattağı bitlär sıltıy:",
+       "nolinkshere-2": "'''$1''' bitenä başqa bitlär sıltamıylar.",
        "isredirect": "yünältü bite",
        "istemplate": "kertülär",
        "isimage": "fayl qullanılışı",
        "version-software-version": "Versiä",
        "fileduplicatesearch-submit": "Ezläw",
        "specialpages": "Maxsus bitlär",
+       "specialpages-note-restricted": "* Ğädi maxsus bitlär.\n* <strong class=\"mw-specialpagerestricted\">Çiklänelgän ğädi maxsus bitlär</strong>",
        "specialpages-group-maintenance": "Texnik qaraw xisapnamäse",
        "specialpages-group-other": "Başqa maxsus bitlär",
        "specialpages-group-login": "Kerü / terkälü",
index b60268e..d8971d5 100644 (file)
        "whatlinkshere": "Аргышкан арыннар",
        "whatlinkshere-title": "«$1» деп арынче айтып турар тускай арыннар",
        "whatlinkshere-page": "Арын:",
-       "linkshere": "Адаандагы арыннар бээр «'''[[:$1]]'''» шөлүдүп турарлар:",
-       "nolinkshere": "'''[[:$1]]''' деп арынче шөлүтткен арыннар чок.",
+       "linkshere-2": "Адаандагы арыннар бээр «'''$1'''» шөлүдүп турарлар:",
+       "nolinkshere-2": "'''$1''' деп арынче шөлүтткен арыннар чок.",
        "isredirect": "шиглидер арын",
        "istemplate": "киирткен арыннар",
        "isimage": "файлдың холбаазы",
index e0819e6..c37a572 100644 (file)
        "whatlinkshere": "Татчы чӧлсконъёс",
        "whatlinkshere-title": "«$1» вылэ чӧлскись бамъёс",
        "whatlinkshere-page": "Бам:",
-       "linkshere": "Та бамъёс <strong>[[:$1]]</strong> вылэ чӧлско:",
+       "linkshere-2": "Та бамъёс <strong>$1</strong> вылэ чӧлско:",
        "isredirect": "ыстӥсь бам",
        "istemplate": "пыртон",
        "isimage": "файл линк",
index b6d2f49..0200aee 100644 (file)
        "whatlinkshere": "بۇ جايدىكى ئۇلانما",
        "whatlinkshere-title": "\"$1\" بەتكە ئۇلانغان بەتلەر",
        "whatlinkshere-page": "بەت:",
-       "linkshere": "تۆۋەندىكى بەتلەر '''[[:$1]]'''غا ئۇلانغان:",
-       "nolinkshere": "'''[[:$1]]'''غا ئۇلانغان بەت يوق.",
-       "nolinkshere-ns": "تاللانغان ئات بوشلۇقىدا '''[[:$1]]''' غا ئۇلانغان بەت يوق.",
+       "linkshere-2": "تۆۋەندىكى بەتلەر '''$1'''غا ئۇلانغان:",
+       "nolinkshere-2": "'''$1'''غا ئۇلانغان بەت يوق.",
+       "nolinkshere-ns-2": "تاللانغان ئات بوشلۇقىدا '''$1''' غا ئۇلانغان بەت يوق.",
        "isredirect": "قايتا نىشان بەلگىلەنگەن بەت",
        "istemplate": "ئۆز ئىچىگە ئالغان",
        "isimage": "ھۆججەت ئۇلانما",
        "fileduplicatesearch-result-n": " \"$1\" ھۆججەتنىڭ تامامەن ئوخشاش {{PLURAL:$2|1 تەكرار|$2 تەكرار}} نۇسخىسى بار.",
        "fileduplicatesearch-noresults": "\"$1\" ئاتلىق ھۆججەت تېپىلمىدى.",
        "specialpages": "ئالاھىدە بەتلەر",
+       "specialpages-note-restricted": "* ئادەتتىكى ئالاھىدە بەت.\n* <strong class=\"mw-specialpagerestricted\">چەكلىمىلىك ئالاھىدە بەتلەر.</strong>\n* <span class=\"mw-specialpagecached\">غەملەنگەن ئالاھىدە بەتلەر(ۋاقتى ئۆتكەن بولۇشى مۇمكىن).</span>",
        "specialpages-group-maintenance": "ئاسراش دوكلاتى",
        "specialpages-group-other": "باشقا ئالاھىدە بەتلەر",
        "specialpages-group-login": "تىزىملىتىش / كىرىش",
index 32a5e95..c20ce59 100644 (file)
@@ -74,7 +74,8 @@
                        "SimondR",
                        "Renamerr",
                        "Avatar6",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Movses"
                ]
        },
        "tog-underline": "Підкреслювання посилань:",
        "subject-preview": "Попередній перегляд теми:",
        "previewerrortext": "Сталася помилка при спробі попереднього перегляду Ваших змін.",
        "blockedtitle": "Користувача заблоковано",
-       "blockedtext": "<strong>Ð\92аÑ\88 Ð¾Ð±Ð»Ñ\96ковий Ð·Ð°Ð¿Ð¸Ñ\81 Ð°Ð±Ð¾ IP-адÑ\80еÑ\81а Ð·Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ñ\96.</strong>\n\nÐ\91локÑ\83ваннÑ\8f Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ðµ Ð°Ð´Ð¼Ñ\96нÑ\96Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80ом $1.\nÐ\9fÑ\80иÑ\87ина Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f: <em>$2</em>.\n\n* Ð\9fоÑ\87аÑ\82ок Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f: $8\n* Ð\97акÑ\96нÑ\87еннÑ\8f Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f: $6\n* Ð\94Ñ\96апазон Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f: $7\n\nÐ\92и Ð¼Ð¾Ð¶ÐµÑ\82е Ð½Ð°Ð´Ñ\96Ñ\81лаÑ\82и Ð»Ð¸Ñ\81Ñ\82а ÐºÐ¾Ñ\80иÑ\81Ñ\82Ñ\83ваÑ\87евÑ\96 $1 Ð°Ð±Ð¾ Ð±Ñ\83дÑ\8c\8fкомÑ\83 Ñ\96нÑ\88омÑ\83 [[{{MediaWiki:Grouppage-sysop}}|адмÑ\96нÑ\96Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\83]], Ñ\89об Ð¾Ð±Ð³Ð¾Ð²Ð¾Ñ\80иÑ\82и Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f.\n\nÐ\97веÑ\80нÑ\96Ñ\82Ñ\8c Ñ\83вагÑ\83, Ñ\89о Ð²Ð¸ Ð½Ðµ Ð·Ð¼Ð¾Ð¶ÐµÑ\82е Ð½Ð°Ð´Ñ\96Ñ\81лаÑ\82и Ð»Ð¸Ñ\81Ñ\82а Ð°Ð´Ð¼Ñ\96нÑ\96Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\83, якщо ви не зареєстровані або не підтвердили свою електронну адресу в [[Special:Preferences|особистих налаштуваннях]], а також якщо вам було заборонено надсилати листи при блокуванні.\n\nВаша поточна IP-адреса — $3, ідентифікатор блокування — #$5. Будь ласка, зазначайте ці дані у своїх запитах.",
+       "blockedtext": "<strong>Ð\92аÑ\88 Ð¾Ð±Ð»Ñ\96ковий Ð·Ð°Ð¿Ð¸Ñ\81 Ð°Ð±Ð¾ IP-адÑ\80еÑ\81а Ð·Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ñ\96.</strong>\n\nÐ\91локÑ\83ваннÑ\8f Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ðµ Ð°Ð´Ð¼Ñ\96нÑ\96Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80ом $1.\nÐ\9fÑ\80иÑ\87ина Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f: <em>$2</em>.\n\n* Ð\9fоÑ\87аÑ\82ок Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f: $8\n* Ð\97акÑ\96нÑ\87еннÑ\8f Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f: $6\n* Ð\94Ñ\96апазон Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f: $7\n\nÐ\92и Ð¼Ð¾Ð¶ÐµÑ\82е Ð½Ð°Ð´Ñ\96Ñ\81лаÑ\82и Ð»Ð¸Ñ\81Ñ\82а ÐºÐ¾Ñ\80иÑ\81Ñ\82Ñ\83ваÑ\87евÑ\96 $1 Ð°Ð±Ð¾ Ð±Ñ\83дÑ\8c\8fкомÑ\83 Ñ\96нÑ\88омÑ\83 [[{{MediaWiki:Grouppage-sysop}}|адмÑ\96нÑ\96Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\83]], Ñ\89об Ð¾Ð±Ð³Ð¾Ð²Ð¾Ñ\80иÑ\82и Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f.\n\nÐ\97веÑ\80нÑ\96Ñ\82Ñ\8c Ñ\83вагÑ\83, Ñ\89о Ð²Ð¸ Ð½Ðµ Ð·Ð¼Ð¾Ð¶ÐµÑ\82е Ð²Ð¸ÐºÐ¾Ñ\80иÑ\81Ñ\82аÑ\82и Ñ\84Ñ\83нкÑ\86Ñ\96Ñ\8e \"{{int:emailuser}}\", якщо ви не зареєстровані або не підтвердили свою електронну адресу в [[Special:Preferences|особистих налаштуваннях]], а також якщо вам було заборонено надсилати листи при блокуванні.\n\nВаша поточна IP-адреса — $3, ідентифікатор блокування — #$5. Будь ласка, зазначайте ці дані у своїх запитах.",
        "autoblockedtext": "Ваша IP-адреса автоматично заблокована у зв'язку з тим, що вона раніше використовувалася кимось із заблокованих користувачів. Адміністратор ($1), що її заблокував, зазначив наступну причину блокування:\n\n:''$2''\n\n* Початок блокування: $8\n* Закінчення блокування: $6\n* Блокування виконав: $7\n\nВи можете надіслати листа користувачеві $1 або будь-якому іншому [[{{MediaWiki:Grouppage-sysop}}|адміністратору]], щоб обговорити блокування.\n\nЗверніть увагу, що ви не зможете надіслати листа адміністраторові, якщо ви не зареєстровані у проекті або не підтвердили свою електронну адресу в [[Special:Preferences|особистих налаштуваннях]], а також якщо вам було заборонено надсилати листи при блокуванні.\n\nВаша поточна IP-адреса — $3, ідентифікатор блокування — #$5. Будь ласка, зазначайте його у своїх запитах.",
        "systemblockedtext": "Ваше ім'я користувача або IP-адресу було автоматично заблоковано MediaWiki.\nВказана причина:\n\n:<em>$2</em>\n\n* Початок блокування: $8\n* Закінчення блокування: $6\n* Ціль блокування: $7\n\nВаша поточна IP-адреса — $3.\nБудь ласка, додайте всі вказані подробиці до будь-яких запитів, які Ви будете робити.",
        "blockednoreason": "не вказано причини",
        "recentchangeslinked-feed": "Пов'язані редгування",
        "recentchangeslinked-toolbox": "Пов'язані редагування",
        "recentchangeslinked-title": "Пов'язані редагування для «$1»",
-       "recentchangeslinked-summary": "Уведіть назву сторінки, щоб побачити зміни на сторінках, які посилаються на неї, або на які вона сама посилається. (Для перегляду членів категорії вводьте {{ns:14}}:Назва категорії). Зміни на сторінках з [[Special:Watchlist|Вашого Списку спостереження]] виділені <strong>жирним</strong>.",
+       "recentchangeslinked-summary": "Уведіть назву сторінки, щоб побачити зміни на сторінках, які посилаються на неї, або на які вона сама посилається. Для перегляду членів категорії вводьте {{ns:category}}:Назва категорії. Зміни на сторінках з [[Special:Watchlist|Вашого списку спостереження]] виділені <strong>жирним шрифтом</strong>.",
        "recentchangeslinked-page": "Назва сторінки:",
        "recentchangeslinked-to": "Показати зміни на сторінках, пов'язаних з даною",
        "recentchanges-page-added-to-category": "[[:$1]] Додано до категорії",
        "whatlinkshere": "Посилання сюди",
        "whatlinkshere-title": "Сторінки, що посилаються на «$1»",
        "whatlinkshere-page": "Сторінка:",
-       "linkshere": "Такі сторінки посилаються на '''[[:$1]]''':",
-       "nolinkshere": "На статтю '''[[:$1]]''' не вказує жодна стаття.",
-       "nolinkshere-ns": "У вибраному просторі назв нема сторінок, що посилаються на '''[[:$1]]'''.",
+       "linkshere-2": "Такі сторінки посилаються на '''$1''':",
+       "nolinkshere-2": "На статтю '''$1''' не вказує жодна стаття.",
+       "nolinkshere-ns-2": "У вибраному просторі назв нема сторінок, що посилаються на '''$1'''.",
        "isredirect": "сторінка-перенаправлення",
        "istemplate": "включення",
        "isimage": "посилання на файл",
index 7f10673..fa0f81b 100644 (file)
        "whatlinkshere": "مربوط صفحات",
        "whatlinkshere-title": "«$1» سے مربوط صفحات",
        "whatlinkshere-page": "صفحہ:",
-       "linkshere": "<strong>[[:$1]]</strong> سے درج ذیل صفحات مربوط ہیں:",
-       "nolinkshere": "<strong>[[:$1]]</strong> سے کوئی صفحہ مربوط نہیں ہے۔",
-       "nolinkshere-ns": "منتخب نام فضا میں <strong>[[:$1]]</strong> سے مربوط کوئی صفحہ نہیں ہے۔",
+       "linkshere-2": "<strong>$1</strong> سے درج ذیل صفحات مربوط ہیں:",
+       "nolinkshere-2": "<strong>$1</strong> سے کوئی صفحہ مربوط نہیں ہے۔",
+       "nolinkshere-ns-2": "منتخب نام فضا میں <strong>$1</strong> سے مربوط کوئی صفحہ نہیں ہے۔",
        "isredirect": "رجوع مکرر صفحہ",
        "istemplate": "شامل شدہ",
        "isimage": "فائل کا ربط",
index 09c9da0..71afccf 100644 (file)
        "whatlinkshere": "Bogʻliq sahifalar",
        "whatlinkshere-title": "„$1“ga bogʻlangan sahifalar",
        "whatlinkshere-page": "Sahifa:",
-       "linkshere": "Quyidagi sahifalar '''[[:$1]]''' sahifasiga bogʻlangan:",
-       "nolinkshere": "'''[[:$1]]''' sahifasiga hech qaysi sahifa bog‘lanmagan.",
-       "nolinkshere-ns": "Tanlangan nomfazoda '''[[:$1]]'''ga bog‘langan sahifalar mavjud emas.",
+       "linkshere-2": "Quyidagi sahifalar '''$1''' sahifasiga bogʻlangan:",
+       "nolinkshere-2": "'''$1''' sahifasiga hech qaysi sahifa bog‘lanmagan.",
+       "nolinkshere-ns-2": "Tanlangan nomfazoda '''$1'''ga bog‘langan sahifalar mavjud emas.",
        "isredirect": "yoʻnaltiruvchi sahifa",
        "istemplate": "qoʻshimcha",
        "isimage": "faylli havola",
index b853818..5b5357a 100644 (file)
        "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 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:",
+       "viewsourcetext": "Te poli 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 pàjina ła gà drento un testo de l'interfacia utente del software de sto sito, quindi la xe proteta parché nisuni ła strusie.\nPar xontar o modifegar tradusion par tute łe wiki doparar [https://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.\nPar xontare o modifegar łe tradusion vałide so tute łe wiki, considera ła posibiłità de doparar [https://translatewiki.net/wiki/Main_Page?setlang=vec translatewiki.net], el projeto MediaWiki par ła localixasion.",
        "permissionserrorstext": "Nò se dispone dei parmesi nesessari ad eseguir l'asion richiesta, par {{PLURAL:$1|el seguente motivo|i seguenti motivi}}:",
        "permissionserrorstext-withaction": "Nò se dispone dei parmesi nesesari par $2, par {{PLURAL:$1|el seguente modivo|i seguenti modivi}}:",
        "recreate-moveddeleted-warn": "'''Ocio: te stè par ricrear na pagina zà scancelà precedentemente.'''\n\nPar piaser assicùrete che sia dal bon el caso de 'ndar vanti a modificar sta pagina.\nL'elenco de i relativi spostamenti e scancelazion el vien riportà qua de seguito par comodità:",
-       "moveddeleted-notice": "Sta pagina la xe stà scancelà.\nL'elenco dei so spostamenti e scancelassion el vien riportà qua soto par informassion.",
+       "moveddeleted-notice": "Sta pagina la xe stà scancelà.\nL'elenco dei so spostamenti, protesion e scancelassion te lo cati qua soto par informassion.",
        "log-fulllog": "Varda registro conpleto",
        "edit-hook-aborted": "Modifica abortìa da parte de l'hook.\nNo xe stà dà nissuna spiegazion in merito.",
        "edit-gone-missing": "No se riesse a agiornar la pàxena.\nPararìa che la sìpia stà scancelà.",
        "page_first": "prima",
        "page_last": "ultima",
        "histlegend": "Confronto tra version: segna le casèle de le version che te voli confrontar e struca Invio o el boton in fondo.\n\nLegenda: '''({{int:cur}})''' = difarense co l'ultima version, '''({{int:last}})''' = difarense co la version subito prima, '''{{int:minoreditletter}}''' = canbiamento picenin",
-       "history-fieldset-title": "Ruma in te la storia",
+       "history-fieldset-title": "Ruma in te le revision",
        "history-show-deleted": "Solo quei scancelà",
        "histfirst": "pi vecia",
        "histlast": "pi nova",
        "editundo": "tira indrìo",
        "diff-empty": "(Nissuna difarensa)",
        "diff-multi-sameuser": "({{PLURAL:$1|Una revision intermedia|$1 revision intermedie}} del stesso utente mia mostrà)",
+       "diff-multi-otherusers": "({{PLURAL:$1|Na version intermedia|$1 version intermedie}} de {{PLURAL:$2|n'altro utente|$2 utenti}} mia mostrà)",
        "diff-multi-manyusers": "({{PLURAL:$1|Una revision intermedia|$1 revision intermedie}} de pi de {{PLURAL:$2|un utente|$2 utenti}} mia mostrà)",
        "difference-missing-revision": "{{PLURAL:$2|Na version|$2 version}} de sta difarensa ($1) {{PLURAL:$2|nó ła xe sta trovà|nó łe xe stae trovae}}.\n\nCuesto se verifega de sołito seguendo un ligamente vecio de un dif a na pàjina scansełà.\nI detaji i pol esar catai inte'l [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de łe scansełasion].",
        "searchresults": "Risultati de la riserca",
        "search-redirect": "(rimando da $1)",
        "search-section": "(sesion $1)",
        "search-category": "(categoria $1)",
+       "search-file-match": "(catà drento el file)",
        "search-suggest": "Sercavito forsi: $1",
        "search-interwiki-caption": "Projeti fradei",
        "search-interwiki-default": "Risultati da $1:",
        "recentchanges": "Ultimi canbiamenti",
        "recentchanges-legend": "Prefarense par i ultimi canbiamenti",
        "recentchanges-summary": "Qua se vede i ultimi canbiamenti fati a sto sito.",
+       "recentchanges-noresult": "No gò catà nissuna modifica in sto periodo co sti criteri de riserca.",
        "recentchanges-feed-description": "Tien tracia dei ultimi canbiamenti fati a sto sito",
        "recentchanges-label-newpage": "Sta modifica la ga creà na pagina nova",
        "recentchanges-label-minor": "Sto qua el xe un canbiamento picenin",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (varda anca [[Special:NewPages|l'elenco de le pagine nove]])",
        "rcfilters-filter-reviewstatus-manual-label": "Verificà manualmente",
        "rcfilters-filter-reviewstatus-auto-label": "Verificà en automatico.",
-       "rcnotefrom": "Qui di seguito sono elencate le modifiche da '''$2''' (fino a '''$1''').",
+       "rcnotefrom": "Qua de soto {{PLURAL:$5|xe mostrà la modifica fata|xe mostrà le modifiche fate }} da <strong>$3, $4</strong> (se ghe ne vede fin a <strong>$1</strong>).",
        "rclistfrom": "Mostra i canbiamenti fati da ƚe $2 del $3",
        "rcshowhideminor": "$1 i canbiamenti picenini",
        "rcshowhideminor-show": "Mostra",
        "recentchangeslinked-feed": "Canbiamenti ligà a sta pagina",
        "recentchangeslinked-toolbox": "Canbiamenti ligà a sta pagina",
        "recentchangeslinked-title": "Canbiamenti ligà a \"$1\"",
-       "recentchangeslinked-summary": "Sti qua i xe i canbiamenti fati ultimamente a pagine pontà da na pagina indicà da ti (o a pagine de na categoria indicà da ti).\nLe pagine [[Special:Watchlist|tegnùe d'ocio]] le xe in '''grosso'''.",
+       "recentchangeslinked-summary": "Scrivi el nome de na pagina pa' védar i canbiamenti fati a le pagine pontà da ela. (Pa' védar le pagine de na categoria, scrivi {{ns:category}}:Nome de la categoria). I canbiamenti a le pagine [[Special:Watchlist|tegnùe d'ocio]] i xe in <strong>groso</strong>.",
        "recentchangeslinked-page": "Nome de la pagina:",
        "recentchangeslinked-to": "Mostra solo i canbiamenti a le pagine ligà a quela indicà",
        "upload": "Carga un file",
        "booksources-invalid-isbn": "El nùmaro ISBN inserìo no'l xe mia valido: controla de novo se te lo ghè copià justo da la fonte originale.",
        "magiclink-tracking-isbn": "Pàgine che dòpara coƚegamenti magisi ISBN",
        "specialloguserlabel": "Asion efetuà da:",
-       "speciallogtitlelabel": "Asion efetuà so:",
+       "speciallogtitlelabel": "Asion efetuà so (titolo de la pagina o {{ns:user}}:nome utente):",
        "log": "Registri",
        "all-logs-page": "Tuti i registri pùblici",
        "alllogstext": "Vixualixazion unificà de tuti i registri disponibili de {{SITENAME}}.\nTe podi restrénzar i criteri de riçerca selezionando el tipo de registro, el nome utente, o la pàxena interessà (ocio che sti ultimi du i distingue tra majuscolo e minuscolo).",
        "unwatchthispage": "Desmeti de tegner d'ocio",
        "notanarticle": "Sta pagina no la xè na pagina de contenuto",
        "notvisiblerev": "La revision la xe stà scancelà",
-       "watchlist-details": "Te sì drio tegner d'ocio {{PLURAL:$1|una pagina (e la so pagina de discussion)|$1 pagine (e le so pagine de discussion)}}.",
+       "watchlist-details": "Te sì drio tegner d'ocio {{PLURAL:$1|una pagina|$1 pagine}} (più le pagine de discussion).",
        "wlheader-enotif": "Xe ativà la notifica via e-mail.",
-       "wlheader-showupdated": "Le pagine che xe stà canbià da la to ultima visita le xe segnà in '''grosso'''",
-       "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.",
+       "wlheader-showupdated": "Le pagine che xe stà canbià da l'ultima olta che te le ghè viste, a le xe segnà in <strong>groso</strong>.",
+       "wlnote": "Cuà soto te cati {{PLURAL:$1|'l ultimo canbiamento|i ultimi <strong>$1</strong> canbiamenti}} inte {{PLURAL:$2|l'ultema ora|łe ultime <strong>$2</strong> ore}}; i dati i xe axornai a łe $4 del $3.",
        "wlshowlast": "Mostra le ultime $1 ore $2 zorni",
        "watchlist-options": "Inpostassion de le pagine tegnùe d'ocio",
        "watching": "Taco a tegner d'ocio...",
        "whatlinkshere": "Punta qua",
        "whatlinkshere-title": "Pagine che ponta a ''$1''",
        "whatlinkshere-page": "Pagina:",
-       "linkshere": "Ste pagine qua le ponta a '''[[:$1]]''':",
-       "nolinkshere": "Nissuna pagina la contien colegamenti che punta a '''[[:$1]]'''.",
-       "nolinkshere-ns": "No ghe xe pagine che punta a '''[[:$1]]''' nel namespace selezionà.",
+       "linkshere-2": "Ste pagine qua le ponta a '''$1''':",
+       "nolinkshere-2": "Nissuna pagina la contien colegamenti che punta a '''$1'''.",
+       "nolinkshere-ns-2": "No ghe xe pagine che punta a '''$1''' nel namespace selezionà.",
        "isredirect": "Pagina de rimando",
        "istemplate": "inclusion",
        "isimage": "colegamento verso file",
        "tooltip-feed-rss": "Feed RSS par sta pagina",
        "tooltip-feed-atom": "Feed Atom par sta pagina",
        "tooltip-t-contributions": "La lista de i contribui de {{GENDER:$1|sto|sta}} utente",
-       "tooltip-t-emailuser": "Invia on mesajo e-mail a sto utente",
+       "tooltip-t-emailuser": "Màndeghe na e-mail a {{GENDER:$1|sto utente qua}}",
        "tooltip-t-upload": "Carga file",
        "tooltip-t-specialpages": "Lista de tute le pagine speciali",
        "tooltip-t-print": "Version stanpabile de sta pagina",
        "pageinfo-length": "Longhessa de la pagina (in byte)",
        "pageinfo-article-id": "ID de la pagina",
        "pageinfo-language": "Lengua del contenuto de la pagina",
-       "pageinfo-robot-policy": "Stato par i motori de riserca",
+       "pageinfo-content-model": "Modèl del contegnùo de la pagina",
+       "pageinfo-robot-policy": "Indexixasion par i robot",
        "pageinfo-robot-index": "Parmesso",
        "pageinfo-robot-noindex": "Vietà",
        "pageinfo-watchers": "Nùmaro de utenti che tien d'ocio sta pagina",
        "pageinfo-few-watchers": "Manco de $1 {{PLURAL:$1|oservador|oservadori}}",
-       "pageinfo-redirects-name": "Rimandi verso sta pagina",
+       "pageinfo-redirects-name": "Nùmaro de rimandi verso sta pagina",
        "pageinfo-subpages-name": "Sotopagine de sta pagina",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|rimandi}}; $3 {{PLURAL:$3|no rimandi}})",
        "pageinfo-firstuser": "Creador de sta pagina",
        "watchlistedit-raw-added": "Xe stà zontà {{PLURAL:$1|una pagina|$1 pagine}}:",
        "watchlistedit-raw-removed": "Xe stà eliminà {{PLURAL:$1|una pagina|$1 pagine}}:",
        "watchlistedit-clear-titles": "Pagine:",
+       "watchlisttools-clear": "Desvoda la lista dei tegnùi d'ocio",
        "watchlisttools-view": "Varda i canbiamenti",
        "watchlisttools-edit": "Varda e canbia le pagine tegnùe d'ocio",
        "watchlisttools-raw": "Canbia la lista in formato testo",
        "version-libraries-license": "Licensa",
        "version-libraries-description": "Descrision",
        "version-libraries-authors": "Autori",
-       "redirect": "Rimando par file, utente, pagina o ID de version.",
+       "redirect": "Rimando par file, utente, pagina, revision o registro",
        "redirect-summary": "Sta pagina speciale la rimanda a un file (dato el nome del file), a na pagina (dato l'ID de la revision), o a na pagina utente (dato l'ID de l'utente).",
        "redirect-submit": "Và",
        "redirect-lookup": "Ciave de riserca:",
        "redirect-value": "Valor:",
        "redirect-user": "ID utente",
+       "redirect-page": "ID de la pagina",
        "redirect-revision": "Revision de la pagina",
        "redirect-file": "Nome del file",
        "redirect-not-exists": "Valor mia catà",
        "fileduplicatesearch-noresults": "Nisun file de nome \"$1\" trovà.",
        "specialpages": "Pagine speciali",
        "specialpages-note-top": "Legenda",
+       "specialpages-note-restricted": "* Pàjine speciałi normałi.\n* <span class=\"mw-specialpagerestricted\">Pàjine speciałi a aceso limità.</span>",
        "specialpages-group-maintenance": "Resoconti de manutenzion",
        "specialpages-group-other": "Altre pagine speciali",
        "specialpages-group-login": "Login / registrasion",
        "htmlform-yes": "Sì",
        "htmlform-chosen-placeholder": "Selessiona na opzione",
        "logentry-delete-delete": "$1 {{GENDER:$2|el|la}} ga scansełà ła pajina $3",
-       "logentry-delete-restore": "$1 {{GENDER:$2|el|la}} ga ripristinà \"$3\"",
+       "logentry-delete-restore": "$1 {{GENDER:$2|el|la}} ga ripristinà $3 ($4)",
        "logentry-delete-event": "$1 {{GENDER:$2|el|la}} ga canbià ła vixibiłità de {{PLURAL:$5|n'asion del registro|$5 asion del registro}} de \"$3\": $4",
        "logentry-delete-revision": "$1 {{GENDER:$2|el|la}} ga canbià ła vixibiłità de {{PLURAL:$5|na revixion|$5 revixion}} de ła pajina\"$3\": $4",
        "logentry-delete-event-legacy": "$1 {{GENDER:$2|el|la}} ga canbià ła vixibiłità de calche asion del registro de \"$3\"",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|el|la}} ga canbià l'apartenensa a grupi de $3",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|el|la}} xe stà automategamente promoso/a da $4 a $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|el|la}} gà cargà $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|el|la}} gà cargà na version nova de $3.",
        "rightsnone": "(nissun)",
        "feedback-adding": "Inserimento del feedback inte ła pàjina...",
        "feedback-back": "Indrìo",
        "mw-widgets-dateinput-placeholder-day": "AAAA-MM-GG",
        "mw-widgets-dateinput-placeholder-month": "AAAA-MM",
        "mw-widgets-titleinput-description-redirect": "rimando a $1",
-       "randomrootpage": "Pagina raìsa caxuale"
+       "randomrootpage": "Pagina raìsa a ocio"
 }
index 6a40619..28e0f1d 100644 (file)
        "whatlinkshere": "Kosketused - nakhu",
        "whatlinkshere-title": "Lehtpoled, kudambad kosketadas \"$1\"-lehtpolen",
        "whatlinkshere-page": "Lehtpol’:",
-       "linkshere": "Nened lehtpoled kosketadas '''[[:$1]]''':",
-       "nolinkshere": "'''[[:$1]]'''-lehtpol't ei kosketa ni üks' lehtpol'.",
-       "nolinkshere-ns": "'''[[:$1]]'''-lehtpol't ei kosketa ni üks' lehtpol' valitud nimiavarudes.",
+       "linkshere-2": "Nened lehtpoled kosketadas '''$1''':",
+       "nolinkshere-2": "'''$1'''-lehtpol't ei kosketa ni üks' lehtpol'.",
+       "nolinkshere-ns-2": "'''$1'''-lehtpol't ei kosketa ni üks' lehtpol' valitud nimiavarudes.",
        "isredirect": "Oigendai lehtpol'",
        "istemplate": "mülütand",
        "isimage": "Kosketuz failale",
        "fileduplicatesearch-result-1": "\"$1\"-failal ei ole identižid dublikatoid.",
        "fileduplicatesearch-result-n": "\"$1\"-failal om {{PLURAL:$2|1 identine kopii|$2 identišt kopijad}}.",
        "specialpages": "Specialižed lehtpoled",
+       "specialpages-note-restricted": "* Järgeližed specialižed lehtpoled.\n* <span class=\"mw-specialpagerestricted\">Kaitud specialižed lehtpoled.</span>",
        "specialpages-group-maintenance": "Tehnižen holitandan satusenladindad",
        "specialpages-group-other": "Toižed specialižed lehtpoled",
        "specialpages-group-login": "Kirjutadas sistemha / Sada registracii",
index aa78905..097cc73 100644 (file)
@@ -41,7 +41,8 @@
                        "Tmp1109",
                        "Phjtieudoc",
                        "Harriettruong3",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Leducthn"
                ]
        },
        "tog-underline": "Gạch chân liên kết:",
@@ -78,7 +79,7 @@
        "tog-watchlisthideminor": "Ẩn các sửa đổi nhỏ khỏi danh sách theo dõi",
        "tog-watchlisthideliu": "Ẩn sửa đổi của thành viên đã đăng nhập khỏi danh sách theo dõi",
        "tog-watchlistreloadautomatically": "Tự động tải lại danh sách theo dõi khi nào bộ lọc được thay đổi (cần JavaScript)",
-       "tog-watchlistunwatchlinks": "Thêm liên kết ngừng theo dõi/theo dõi trực tiếp vào mục trong danh sách theo dõi (cần JavaScript để bật/tắt)",
+       "tog-watchlistunwatchlinks": "Thêm nút ngừng theo dõi/theo dõi ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) trực tiếp vào trang theo dõi có thay đổi (cần JavaScript để bật/tắt)",
        "tog-watchlisthideanons": "Ẩn sửa đổi của người dùng vô danh khỏi danh sách theo dõi",
        "tog-watchlisthidepatrolled": "Ẩn sửa đổi đã tuần tra trong danh sách theo dõi",
        "tog-watchlisthidecategorization": "Ẩn việc xếp thể loại",
        "cascadeprotected": "Trang này đã bị khóa không cho sửa đổi, vì nó được nhúng vào {{PLURAL:$1|trang|những trang}} đã bị khóa với tùy chọn “khóa theo tầng” được kích hoạt:\n$2",
        "namespaceprotected": "Bạn không có quyền sửa các trang trong không gian tên '''$1'''.",
        "customcssprotected": "Bạn không có quyền sửa đổi trang CSS này vì nó chứa các tùy chọn cá nhân của một thành viên khác.",
+       "customjsonprotected": "Bạn không có quyền sửa đổi trang JSON này vì nó chứa các tùy chọn cá nhân của một thành viên khác.",
        "customjsprotected": "Bạn không có quyền sửa đổi trang JavaScript này vì nó chứa các tùy chọn cá nhân của một thành viên khác.",
        "mycustomcssprotected": "Bạn không có quyền sửa đổi trang CSS này.",
+       "mycustomjsonprotected": "Bạn không có quyền sửa đổi trang JSON này.",
        "mycustomjsprotected": "Bạn không có quyền sửa đổi trang JavaScript này.",
        "myprivateinfoprotected": "Bạn không có quyền sửa đổi thông tin cá nhân của bạn.",
        "mypreferencesprotected": "Bạn không có quyền thay đổi tùy chọn của bạn.",
        "password-login-forbidden": "Tên đăng nhập và mật khẩu này đã bị cấm không được sử dụng.",
        "mailmypassword": "Tái tạo mật khẩu",
        "passwordremindertitle": "Mật khẩu tạm thời cho {{SITENAME}}",
-       "passwordremindertext": "Ai đó (có thể là bạn, có địa chỉ IP $1) đã yêu cầu chúng tôi gửi mật khẩu mới của {{SITENAME}} ($4). Chúng tôi đã tạo một mật khẩu tạm “$3” cho thành viên “$2”. Nếu bạn chính là người đã yêu cầu mật khẩu, bạn cần phải đăng nhập và thay đổi mật khẩu ngay bây giờ. Mật khẩu tạm sẽ hết hạn trong vòng {{PLURAL:$5|một ngày|$5 ngày}}.\n\nNếu bạn không yêu cầu gửi mật khẩu mới, hoặc bạn đã nhớ ra mật khẩu cũ của mình và không còn muốn đổi nó nữa, bạn có thể bỏ qua bức thư này và tiếp tục sử dụng mật khẩu cũ của bạn.",
+       "passwordremindertext": "Ai đó (có địa chỉ IP $1) đã yêu cầu chúng tôi gửi mật khẩu mới của {{SITENAME}} ($4). Chúng tôi đã tạo một mật khẩu tạm “$3” cho thành viên “$2”. Nếu bạn chính là người đã yêu cầu mật khẩu, bạn cần phải đăng nhập và thay đổi mật khẩu ngay bây giờ. Mật khẩu tạm sẽ hết hạn trong vòng {{PLURAL:$5|một ngày|$5 ngày}}.\n\nNếu bạn không yêu cầu gửi mật khẩu mới, hoặc bạn đã nhớ ra mật khẩu cũ của mình và không còn muốn đổi nó nữa, bạn có thể bỏ qua bức thư này và tiếp tục sử dụng mật khẩu cũ của bạn.",
        "noemail": "Thành viên “$1” không ghi thư điện tử.",
        "noemailcreate": "Bạn cần cung cấp một địa chỉ thư điện tử hợp lệ",
        "passwordsent": "Mật khẩu mới đã được gửi tới thư điện tử của thành viên “$1”. Xin đăng nhập lại sau khi nhận thư.",
        "botpasswords-existing": "Mật khẩu bot hiện tại",
        "botpasswords-createnew": "Tạo một mật khẩu mới bot",
        "botpasswords-editexisting": "Chỉnh sửa một mật khẩu hiện tại của bot",
+       "botpasswords-label-needsreset": "(mật khẩu cần được đặt lại)",
        "botpasswords-label-appid": "Tên bot:",
        "botpasswords-label-create": "Tạo",
        "botpasswords-label-update": "Cập nhật",
        "botpasswords-label-grants": "Các quyền có liên quan:",
        "botpasswords-help-grants": "Các lượt cấp phép cho phép truy cập các quyền lợi mà tài khoản của bạn đã có. Việc cấp phép tại đây không có cho phép truy cập quyền nào mà tài khoản của bạn thường không có. Xem thêm thông tin trong [[Special:ListGrants|bảng cấp phép]].",
        "botpasswords-label-grants-column": "Cấp quyền",
-       "botpasswords-bad-appid": "Bot có tên \"$1\" không hợp lệ.",
+       "botpasswords-bad-appid": "Tên bot “$1” không hợp lệ.",
        "botpasswords-insert-failed": "Không thể thêm tên bot \"$1\". Nó đã được thêm vào chưa?",
        "botpasswords-update-failed": "Không thể khi cập nhật bot có tên “$1”. Có phải nó đã bị xóa?",
        "botpasswords-created-title": "Mật khẩu bot đã được tạo",
-       "botpasswords-created-body": "Đã tạo mật khẩu cho bot tên \"$1\" của {{GENDER:$2|thành viên}} \"$2\".",
+       "botpasswords-created-body": "Đã tạo mật khẩu cho bot tên “$1” của thành viên “$2”.",
        "botpasswords-updated-title": "Mật khẩu Bot đã được cập nhật",
-       "botpasswords-updated-body": "Đã cập nhật mật khẩu cho bot tên \"$1\" của {{GENDER:$2|thành viên}} \"$2\".",
+       "botpasswords-updated-body": "Đã cập nhật mật khẩu cho bot tên “$1” của thành viên “$2”.",
        "botpasswords-deleted-title": "Mật khẩu bot đã bị xóa",
-       "botpasswords-deleted-body": "Đã xóa mật khẩu cho bot tên \"$1\" của {{GENDER:$2|thành viên}} \"$2\".",
+       "botpasswords-deleted-body": "Đã xóa mật khẩu cho bot tên “$1” của thành viên “$2”.",
        "botpasswords-newpassword": "Mật khẩu mới để đăng nhập như <strong>$1</strong> là <strong>$2</strong>. <em>Xin hãy ghi lại mật khẩu này để mai mốt tham khảo.</em> <br> (Các bot cũ cần tên đăng nhập khớp với tên người dùng cuối cùng có thể sử  dụng tên người dùng <strong>$3</strong> và mật khẩu <strong>$4</strong>.)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider không có sẵn.",
        "botpasswords-restriction-failed": "Mật khẩu bot giới hạn ngăn chặn đăng nhập này.",
        "botpasswords-invalid-name": "Tên người dùng đã chỉ định không chứa dấu tách mật khẩu bot (\"$1\").",
        "botpasswords-not-exist": "Người dùng \"$1\" không có mật khẩu bot có tên \"$2\".",
+       "botpasswords-needs-reset": "Mật khẩu bot của bot tên “$2” của người dùng “$1” cần được đặt lại.",
        "resetpass_forbidden": "Không được đổi mật khẩu",
        "resetpass_forbidden-reason": "Không thể đổi mật khẩu: $1",
        "resetpass-no-info": "Bạn phải đăng nhập mới có thể truy cập trực tiếp trang này.",
        "savechanges": "Lưu các thay đổi",
        "publishpage": "Đăng trang",
        "publishchanges": "Đăng thay đổi",
-       "savearticle-start": "Lưu trang...",
-       "savechanges-start": "Lưu thay đổi...",
-       "publishpage-start": "Đăng trang...",
-       "publishchanges-start": "Đăng thay đổi...",
+       "savearticle-start": "Lưu trang",
+       "savechanges-start": "Lưu các thay đổi…",
+       "publishpage-start": "Đăng trang",
+       "publishchanges-start": "Đăng các thay đổi…",
        "preview": "Xem trước",
        "showpreview": "Xem trước",
        "showdiff": "Xem thay đổi",
        "subject-preview": "Xem trước đề mục:",
        "previewerrortext": "Có lỗi xảy ra khi xem trước những thay đổi của bạn.",
        "blockedtitle": "Thành viên bị cấm",
-       "blockedtext": "'''Tên người dùng hoặc địa chỉ IP của bạn đã bị cấm.'''\n\nNgười thực hiện cấm là $1.\nLý do được cung cấp là ''$2''.\n\n* Bắt đầu cấm: $8\n* Kết thúc cấm: $6\n* Mục tiêu cấm: $7\n\nBạn có thể liên hệ với $1 hoặc một [[{{MediaWiki:Grouppage-sysop}}|bảo quản viên]] khác để thảo luận về việc cấm.\nBạn không thể sử dụng tính năng “gửi thư cho người này” trừ khi bạn đã ghi một địa chỉ thư điện tử hợp lệ trong [[Special:Preferences|tùy chọn tài khoản]] và bạn không bị khóa chức năng đó.\nĐịa chỉ IP hiện tại của bạn là $3, và mã số cấm là #$5.\nXin hãy ghi kèm tất cả các thông tin trên vào thư yêu cầu của bạn.",
-       "autoblockedtext": "Địa chỉ IP của bạn đã bị tự động cấm vì một người nào đó đã sử dụng nó, $1 là thành viên đã thực hiện cấm.\nLý do được cung cấp là:\n\n:''$2''\n\n* Bắt đầu cấm: $8\n* Kết thúc cấm: $6\n* Mục tiêu cấm: $7\n\nBạn có thể liên hệ với $1 hoặc một trong số các\n[[{{MediaWiki:Grouppage-sysop}}|bảo quản viên]] khác để thảo luận về việc cấm.\n\nChú ý rằng bạn sẽ không dùng được chức năng “gửi thư cho người này” trừ khi bạn đã ghi một địa chỉ thư điện tử hợp lệ trong [[Special:Preferences|tùy chọn]] và bạn không bị cấm dùng chức năng đó.\n\nĐịa chỉ IP hiện tại của bạn là $3, mã số cấm là $5.\nXin hãy ghi kèm tất cả các chi tiết trên vào thư yêu cầu của bạn.",
+       "blockedtext": "<strong>Tên người dùng hoặc địa chỉ IP của bạn đã bị cấm.</strong>\n\nNgười thực hiện cấm là $1.\nLý do được cung cấp là <em>$2</em>.\n\n* Bắt đầu cấm: $8\n* Kết thúc cấm: $6\n* Mục tiêu cấm: $7\n\nBạn có thể liên hệ với $1 hoặc một [[{{MediaWiki:Grouppage-sysop}}|bảo quản viên]] khác để thảo luận về việc cấm.\nBạn không thể sử dụng tính năng “{{int:emailuser}}” trừ khi bạn đã ghi một địa chỉ thư điện tử hợp lệ trong [[Special:Preferences|tùy chọn tài khoản]] và bạn không bị khóa chức năng đó.\nĐịa chỉ IP hiện tại của bạn là $3, và mã số cấm là #$5.\nXin hãy ghi kèm tất cả các thông tin trên vào thư yêu cầu của bạn.",
+       "autoblockedtext": "Địa chỉ IP của bạn đã bị tự động cấm vì một người nào đó đã sử dụng nó, $1 là thành viên đã thực hiện cấm.\nLý do được cung cấp là:\n\n:<em>$2</em>\n\n* Bắt đầu cấm: $8\n* Kết thúc cấm: $6\n* Mục tiêu cấm: $7\n\nBạn có thể liên hệ với $1 hoặc một trong số các\n[[{{MediaWiki:Grouppage-sysop}}|bảo quản viên]] khác để thảo luận về việc cấm.\n\nChú ý rằng bạn sẽ không dùng được chức năng “{{int:emailuser}}” trừ khi bạn đã ghi một địa chỉ thư điện tử hợp lệ trong [[Special:Preferences|tùy chọn]] và bạn không bị cấm dùng chức năng đó.\n\nĐịa chỉ IP hiện tại của bạn là $3, mã số cấm là $5.\nXin hãy ghi kèm tất cả các chi tiết trên vào thư yêu cầu của bạn.",
        "systemblockedtext": "Tên người dùng hoặc địa chỉ IP của bạn bị MediaWiki cấm tự động.\nLý do được cung cấp là:\n\n:<em>$2</em>\n\n* Bắt đầu cấm: $8\n* Kết thúc cấm: $6\n* Mục tiêu cấm: $7\n\nĐịa chỉ IP hiện tại của bạn là $3.\nXin vui lòng bao gồm tất cả các chi tiết bên trên khi nào hỏi về tác vụ này.",
        "blockednoreason": "không đưa ra lý do",
        "whitelistedittext": "Bạn phải $1 để sửa trang.",
        "blocked-notice-logextract": "Người dùng này hiện đang bị cấm sửa đổi. Nhật trình cấm gần nhất được ghi ở dưới để tiện theo dõi:",
        "clearyourcache": "<strong>Chú ý:</strong> Sau khi lưu trang, có thể bạn sẽ phải xóa bộ nhớ đệm của trình duyệt để xem các thay đổi.\n* <strong>Firefox / Safari:</strong> Nhấn giữ phím <em>Shift</em> trong khi nhấn <em>Tải lại</em> (<em>Reload</em>), hoặc nhấn tổ hợp <em>Ctrl-F5</em> hay <em>Ctrl-R</em> (⌘R trên Mac)\n* <strong>Google Chrome:</strong> Nhấn tổ hợp <em>Ctrl-Shift-R</em> (⇧⌘R trên Mac)\n* <strong>Internet Explorer:</strong> Nhấn giữ phím <em>Ctrl</em> trong khi nhấn <em>Làm tươi</em>, hoặc nhấn tổ hợp <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Mở <em>Menu → Cài đặt</em> (<em>Opera → Tùy chỉnh</em> trên Mac), mở tab <em>Quyền riêng tư & bảo mật</em>, bấm <em>Xóa dữ liệu duyệt web</em> và đánh hộp kiểm <em>Hình ảnh và tệp trong cache</em>.",
        "usercssyoucanpreview": "'''Mẹo:''' Sử dụng nút “{{int:showpreview}}” để kiểm thử bản CSS của bạn trước khi lưu trang.",
+       "userjsonyoucanpreview": "'''Mẹo:''' Sử dụng nút “{{int:showpreview}}” để kiểm thử bản JSON của bạn trước khi lưu trang.",
        "userjsyoucanpreview": "'''Mẹo:''' Sử dụng nút “{{int:showpreview}}” để kiểm thử bản JS của bạn trước khi lưu trang.",
        "usercsspreview": "'''Hãy nhớ rằng bạn chỉ đang xem trước trang CSS cá nhân của bạn.\nNó chưa được lưu!'''",
+       "userjsonpreview": "<strong>Nhớ rằng bạn chỉ đang kiểm thử/xem trước cấu hình JSON, nó chưa được lưu!</strong>",
        "userjspreview": "'''Nhớ rằng bạn chỉ đang kiểm thử/xem trước trang JavaScript, nó chưa được lưu!'''",
        "sitecsspreview": "'''Nhớ rằng bạn chỉ đang xem trước bản CSS này.'''\n'''Nó chưa được lưu!'''",
+       "sitejsonpreview": "<strong>Nhớ rằng bạn chỉ đang xem trước cấu hình JSON này.\nNó chưa được lưu!</strong>",
        "sitejspreview": "'''Nhớ rằng bạn chỉ đang xem trước bản JavaScript này.\n'''Nó chưa được lưu!'''",
-       "userinvalidconfigtitle": "'''Cảnh báo:''' Không có skin “$1”. Hãy nhớ rằng các trang .css và .js tùy chỉnh sử dụng tiêu đề chữ thường, như {{ns:user}}:Ví&nbsp;dụ/vector.css chứ không phải {{ns:user}}:Ví&nbsp;dụ/Vector.css.",
+       "userinvalidconfigtitle": "<strong>Cảnh báo:</strong> Không có skin “$1”. Các trang .css, .json, và .js tùy chỉnh sử dụng tiêu đề chữ thường, như {{ns:user}}:Ví&nbsp;dụ/vector.css chứ không phải {{ns:user}}:Ví&nbsp;dụ/Vector.css.",
        "updated": "(Cập nhật)",
        "note": "'''Ghi chú:'''",
        "previewnote": "'''Đây chỉ mới là bản xem trước.'''\nCác thay đổi của bạn vẫn chưa được lưu!",
        "longpageerror": "'''Lỗi: Văn bạn mà bạn muốn lưu dài $1 kilôbyte, dài hơn độ dài tối đa cho phép $2 kilôbyte.'''\nKhông thể lưu trang.",
        "readonlywarning": "<strong>CẢNH BÁO: Cơ sở dữ liệu đã bị khóa để bảo dưỡng, do đó bạn không thể lưu các sửa đổi của mình. Bạn nên cắt-dán đoạn bạn vừa sửa vào một tập tin và lưu nó lại để sửa đổi sau này.</strong>\n\nQuản trị viên hệ thống khi khóa dữ liệu đã đưa ra lý do: $1",
        "protectedpagewarning": "'''Cảnh báo: Trang này đã bị khóa và chỉ có các thành viên có quyền quản lý mới có thể sửa được.'''\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
-       "semiprotectedpagewarning": "'''Lưu ý:''' Trang này đã bị khóa nên chỉ có các thành viên có tài khoản mới có thể sửa đổi được.\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
+       "semiprotectedpagewarning": "<strong>Lưu ý:</strong> Trang này đã bị khóa nên chỉ có các thành viên tự xác nhận có thể sửa đổi được.\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
        "cascadeprotectedwarning": "'''Cảnh báo:''' Trang này đã bị khóa, chỉ có thành viên có [[Special:ListGroupRights|quyền quản lý]] mới có thể sửa đổi, vì nó được nhúng vào {{PLURAL:$1|trang|những trang}} bị khóa theo tầng sau:",
        "titleprotectedwarning": "'''Cảnh báo:  Trang này đã bị khóa và bạn phải có một số [[Special:ListGroupRights|quyền nhất định]] mới có thể tạo trang.'''\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
        "templatesused": "{{PLURAL:$1|Bản mẫu|Các bản mẫu}} dùng trong trang này:",
        "diff-multi-sameuser": "(Không hiển thị {{PLURAL:$1||$1}} phiên bản của cùng người dùng ở giữa)",
        "diff-multi-otherusers": "(Không hiển thị {{PLURAL:$1||$1}} phiên bản của {{PLURAL:$2|một người dùng khác|$2 người dùng}} ở giữa)",
        "diff-multi-manyusers": "(Không hiển thị {{PLURAL:$1||$1}} phiên bản của hơn $2 thành viên ở giữa)",
+       "diff-paragraph-moved-tonew": "Đoạn văn được chuyển đến vị trí mới. Nhấn chuột để nhảy tới vị trí mới.",
+       "diff-paragraph-moved-toold": "Đoạn văn được chuyển từ vị trí khác. Nhấn chuột để nhảy tới vị trí cũ.",
        "difference-missing-revision": "Không tìm thấy {{PLURAL:$2|một phiên bản|$2 phiên bản}} trong khác biệt này ($1).\n\nLỗi này thường xuất hiện đối khi theo dõi liên kết lỗi thời đến khác biệt giữa các bản của trang đã bị xóa.\nXem chi tiết trong [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} nhật trình xóa].",
        "searchresults": "Kết quả tìm kiếm",
        "searchresults-title": "Kết quả tìm kiếm “$1”",
        "stub-threshold-disabled": "Tắt",
        "recentchangesdays": "Số ngày hiển thị trong thay đổi gần đây:",
        "recentchangesdays-max": "(tối đa $1 ngày)",
-       "recentchangescount": "Số sửa đổi hiển thị mặc định:",
-       "prefs-help-recentchangescount": "Số này bao gồm các thay đổi gần đây, lịch sử trang, và nhật trình.",
+       "recentchangescount": "Số sửa đổi để hiển thị trong thay đổi gần đây, lịch sử trang, và nhật trình theo mặc định:",
+       "prefs-help-recentchangescount": "Con số tối đa: 1.000",
        "prefs-help-watchlist-token2": "Đây là chìa khóa bí mật cho nguồn cấp dữ liệu danh sách theo dõi của bạn.\nBất cứ ai biết nó sẽ có thể để đọc danh sách theo dõi của bạn, vì vậy đừng chia sẻ nó.\nNếu cần, [[Special:ResetTokens|bạn có thể thiết lập lại nó]].",
        "savedprefs": "Đã lưu các tùy chọn cá nhân.",
        "savedrights": "Đã lưu các nhóm người dùng của {{GENDER:$1}}$1.",
        "default": "mặc định",
        "prefs-files": "Tập tin",
        "prefs-custom-css": "sửa CSS",
+       "prefs-custom-json": "JSON tùy biến",
        "prefs-custom-js": "sửa JS",
-       "prefs-common-config": "CSS/JavaScript chung cho mọi giao diện:",
+       "prefs-common-config": "CSS/JSON/JavaScript chung cho mọi giao diện:",
        "prefs-reset-intro": "Có thể mặc định lại toàn bộ tùy chọn dùng trang này. Điều này không thể hoàn tác.",
        "prefs-emailconfirm-label": "Xác nhận thư điện tử:",
        "youremail": "Thư điện tử:",
        "prefs-dateformat": "Kiểu hiển thị ngày tháng",
        "prefs-timeoffset": "Chênh lệch giờ",
        "prefs-advancedediting": "Tùy chọn chung",
+       "prefs-developertools": "Công cụ dành cho lập trình viên",
        "prefs-editor": "Trình soạn",
        "prefs-preview": "Xem trước",
        "prefs-advancedrc": "Tùy chọn nâng cao",
        "right-editcontentmodel": "Sửa kiểu nội dung của trang",
        "right-editinterface": "Sửa giao diện người dùng",
        "right-editusercss": "Sửa tập tin CSS của người dùng khác",
+       "right-edituserjson": "Sửa tập tin JSON của người dùng khác",
        "right-edituserjs": "Sửa đổi tập tin JavaScript của người dùng khác",
        "right-editmyusercss": "Sửa đổi tập tin CSS cá nhân của mình",
+       "right-editmyuserjson": "Sửa đổi tập tin JSON cá nhân của mình",
        "right-editmyuserjs": "Sửa đổi tập tin JavaScript cá nhân của mình",
        "right-viewmywatchlist": "Xem danh sách theo dõi của mình",
        "right-editmywatchlist": "Sửa đổi danh sách theo dõi của mình – một số tác vụ có thể thêm trang vào danh sách bất chấp quyền này",
        "grant-createaccount": "Mở tài khoản",
        "grant-createeditmovepage": "Tạo, sửa đổi, và di chuyển trang",
        "grant-delete": "Xóa trang, phiên bản, và mục nhật trình",
-       "grant-editinterface": "Sửa không gian tên MediaWiki và CSS/JavaScript cá nhân",
-       "grant-editmycssjs": "Sửa đổi CSS/JavaScript cá nhân của bạn",
+       "grant-editinterface": "Sửa không gian tên MediaWiki và CSS/JSON/JavaScript cá nhân",
+       "grant-editmycssjs": "Sửa đổi CSS/JSON/JavaScript cá nhân của bạn",
        "grant-editmyoptions": "Sửa đổi tùy chọn cá nhân của bạn",
        "grant-editmywatchlist": "Sửa danh sách theo dõi của bạn",
        "grant-editpage": "Sửa đổi các trang đã tồn tại",
        "rcfilters-advancedfilters": "Bộ lọc nâng cao",
        "rcfilters-limit-title": "Số kết quả hiển thị",
        "rcfilters-limit-and-date-label": "$1 thay đổi, $2",
+       "rcfilters-date-popup-title": "Thời gian tìm kiếm",
        "rcfilters-days-title": "Những ngày gần đây",
        "rcfilters-hours-title": "Số giờ gần đây",
        "rcfilters-days-show-days": "$1 ngày",
        "rcfilters-restore-default-filters": "Mặc định lại các bộ lọc",
        "rcfilters-clear-all-filters": "Xóa sạch các bộ lọc",
        "rcfilters-show-new-changes": "Xem các thay đổi mới nhất",
-       "rcfilters-search-placeholder": "Lọc các thay đổi gần đây (duyệt hoặc bắt đầu đánh chữ)",
+       "rcfilters-search-placeholder": "Lọc các thay đổi gần đây (sử dụng trình đơn hoặc tìm tên bộ lọc)",
        "rcfilters-invalid-filter": "Bộ lọc không hợp lệ",
        "rcfilters-empty-filter": "Không có bộ lọc hiện hành. Tất cả các đóng góp được hiển thị.",
        "rcfilters-filterlist-title": "Bộ lọc",
        "rcfilters-filter-user-experience-level-unregistered-label": "Vô danh",
        "rcfilters-filter-user-experience-level-unregistered-description": "Người dùng chưa đăng nhập.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Người mới đến",
-       "rcfilters-filter-user-experience-level-newcomer-description": "Người dùng đã đăng nhập có ít hơn 10 sửa đổi  4 ngày hoạt động.",
+       "rcfilters-filter-user-experience-level-newcomer-description": "Người dùng đã đăng nhập có ít hơn 10 sửa đổi hoặc 4 ngày hoạt động.",
        "rcfilters-filter-user-experience-level-learner-label": "Người đang tập",
        "rcfilters-filter-user-experience-level-learner-description": "Người dùng đã đăng nhập có nhiều kinh nghiệm hơn “Người mới đến” mà ít hơn “Người có kinh nghiệm”.",
        "rcfilters-filter-user-experience-level-experienced-label": "Người có kinh nghiệm",
        "rcfilters-filter-humans-label": "Con người (không phải bot)",
        "rcfilters-filter-humans-description": "Các sửa đổi của người thật.",
        "rcfilters-filtergroup-reviewstatus": "Tình trạng tuần tra",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Các sửa đổi không được đánh dấu tuần tra thủ công hoặc tự động.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Chưa được tuần tra",
+       "rcfilters-filter-reviewstatus-manual-description": "Các sửa đổi được đánh dấu tuần tra thủ công.",
+       "rcfilters-filter-reviewstatus-manual-label": "Đánh dấu tuần tra thủ công",
+       "rcfilters-filter-reviewstatus-auto-description": "Sửa đổi của người dùng nâng cao được đánh dấu tuần tra tự động.",
+       "rcfilters-filter-reviewstatus-auto-label": "Tự đánh dấu tuần tra",
        "rcfilters-filtergroup-significance": "Sự quan trọng",
        "rcfilters-filter-minor-label": "Sửa đổi nhỏ",
        "rcfilters-filter-minor-description": "Các sửa đổi được tác giả đánh dấu là nhỏ.",
        "rcfilters-watchlist-edit-watchlist-button": "Sửa danh sách trang theo dõi",
        "rcfilters-watchlist-showupdated": "Thay đổi mới trên các trang kể lần cuối bạn xem trang được in <strong>đậm</strong> và có dấu tô màu.",
        "rcfilters-preference-label": "Ẩn phiên bản cải tiến của trang Thay đổi Gần đây",
+       "rcfilters-filter-showlinkedfrom-label": "Xem các thay đổi tại trang có liên kết từ",
+       "rcfilters-filter-showlinkedfrom-option-label": "<strong>Trang có liên kết từ</strong> trang được chọn",
+       "rcfilters-filter-showlinkedto-label": "Xem các thay đổi tại trang có liên kết đến",
+       "rcfilters-filter-showlinkedto-option-label": "<strong>Trang có liên kết đến</strong> trang được chọn",
        "rcfilters-target-page-placeholder": "Nhập tên trang (hoặc thể loại)",
        "rcnotefrom": "Dưới đây là {{PLURAL:$5|thay đổi duy nhất|các thay đổi}} từ <strong>$3 $4</strong> (hiển thị tối đa <strong>$1</strong> thay đổi).",
        "rclistfromreset": "Đặt lại lựa chọn ngày",
        "recentchangeslinked-feed": "Thay đổi liên quan",
        "recentchangeslinked-toolbox": "Thay đổi liên quan",
        "recentchangeslinked-title": "Thay đổi liên quan tới “$1”",
-       "recentchangeslinked-summary": "Nhập tên trang để xem các thay đổi được thực hiện tại những trang được liên kết với trang đó. (Để xem các trang được xếp vào một thể loại nào đó, nhập Thể loại:Tên thể loại). Các thay đổi được thực hiện tại trang trong [[Special:Watchlist|danh sách bạn theo dõi]] được '''tô đậm'''.",
+       "recentchangeslinked-summary": "Nhập tên trang để xem các thay đổi được thực hiện tại những trang được liên kết với trang đó. (Để xem các trang được xếp vào một thể loại nào đó, nhập {{ns:category}}:Tên thể loại). Các thay đổi được thực hiện tại trang trong [[Special:Watchlist|danh sách bạn theo dõi]] được '''tô đậm'''.",
        "recentchangeslinked-page": "Tên trang:",
        "recentchangeslinked-to": "Hiện thay đổi tại những trang có liên kết đến trang này thay thế",
        "recentchanges-page-added-to-category": "[[:$1]] được xếp vào thể loại",
        "uploaded-script-svg": "Tìm thấy phần tử “$1” có khả năng chạy kịch bản trong tập tin SVG được tải lên.",
        "uploaded-hostile-svg": "Tìm thấy CSS nguy hiểm trong phần tử style của tập tin SVG được tải lên.",
        "uploaded-event-handler-on-svg": "Không cho phép đặt thuộc tính xử lý sự kiện <code>$1=\"$2\"</code> trong tập tin SVG.",
-       "uploaded-href-attribute-svg": "Các đặc tính href trong tập tin SVG chỉ được phép dẫn đến các trang http:// hoặc https://, nhưng gặp phải <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-attribute-svg": "Phần tử <a> chỉ có thể liên kết (đặc tính href) đến đích data: (tập tin nhúng), http:// hay https://, hoặc mảnh (#, cùng trang). Đối với các phần tử khác như <image>, chỉ cho phép data: và mảnh. Hãy thử nhúng hình ảnh khi xuất hình SVG. Đã tìm thấy <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-href-unsafe-target-svg": "Tìm thấy href đến đích URI data: không an toàn <code>&lt;$1 $2=\"$3\"&gt;</code> trong tập tin SVG được tải lên.",
        "uploaded-animate-svg": "Tìm thấy thẻ “animate” có thể thay đổi href qua thuộc tính “from” <code>&lt;$1 $2=\"$3\"&gt;</code> trong tập tin SVG được tải lên.",
        "uploaded-setting-event-handler-svg": "Đã ngăn cản việc đặt thuộc tính xử lý sự kiện khi tìm thấy <code>&lt;$1 $2=\"$3\"&gt;</code> trong tập tin SVG được tải lên.",
        "lockmanager-fail-closelock": "Không thể đóng tập tin khóa cho “$1”.",
        "lockmanager-fail-deletelock": "Không thể xóa tập tin khóa cho “$1”.",
        "lockmanager-fail-acquirelock": "Không thể lấy khóa cho “$1”.",
-       "lockmanager-fail-openlock": "Không thể mở tập tin khóa cho “$1”.",
+       "lockmanager-fail-openlock": "Không thể mở tập tin khóa cho “$1”. Hãy chắc chắn rằng thư mục tải lên được cấu hình đàng hoàng và máy chủ Web được phép ghi vào thư mục đó. Xem thêm chi tiết tại https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgUploadDirectory.",
        "lockmanager-fail-releaselock": "Không thể thả khóa cho “$1”.",
        "lockmanager-fail-db-bucket": "Không thể liên lạc với đủ cơ sở dữ liệu khóa trong nhóm $1.",
        "lockmanager-fail-db-release": "Không thể thả các chìa khóa trên cơ sở dữ liệu $1.",
        "uploadstash-bad-path-invalid": "Đường dẫn không hợp lệ.",
        "uploadstash-bad-path-unknown-type": "Loại không xác định \"$1\".",
        "uploadstash-bad-path-unrecognized-thumb-name": "Tên hình thu nhỏ không nhận dạng được.",
+       "uploadstash-bad-path-bad-format": "Chìa khóa “$1” không tuân theo định dạng.",
        "uploadstash-file-not-found-no-thumb": "Không thể tải hình thu nhỏ.",
        "uploadstash-file-not-found-no-object": "Không tạo được đối tượng tập tin cục bộ cho hình thu nhỏ.",
        "uploadstash-file-not-found-no-remote-thumb": "Nạp hình thu nhỏ thất bại: $1\nURL = $2",
+       "uploadstash-file-not-found-missing-content-type": "Thiếu đầu đề kiểu-nội-dung (content-type).",
        "uploadstash-not-logged-in": "Người dùng chưa đăng nhập, các tập tin phải do người dùng đã đăng nhập tải lên.",
        "uploadstash-no-such-key": "Khoá không tồn tại ($1), không thể xoá.",
        "uploadstash-zero-length": "Tập tin có dung lượng bằng không.",
        "doubleredirects": "Đổi hướng kép",
        "doubleredirectstext": "Trang này liệt kê các trang đổi hướng đến một trang đổi hướng khác.\nMỗi hàng có chứa các liên kết đến trang đổi hướng thứ nhất và thứ hai, cũng như mục tiêu của trang đổi hướng thứ hai, thường là trang đích “thực sự”, là nơi mà trang đổi hướng đầu tiên nên trỏ đến.\nCác mục <del>bị gạch bỏ</del> là các trang đã được sửa.",
        "double-redirect-fixed-move": "[[$1]] đã được đổi tên.\nNó được cập nhật tự động và giờ là trang đổi hướng đến [[$2]].",
-       "double-redirect-fixed-maintenance": "Tự động giải quyết đổi hướng kép từ [[$1]] đến [[$2]] trong một công việc bảo trì.",
+       "double-redirect-fixed-maintenance": "Tự động giải quyết đổi hướng kép từ [[$1]] đến [[$2]] trong một công việc bảo trì",
        "double-redirect-fixer": "Người sửa trang đổi hướng",
        "brokenredirects": "Đổi hướng sai",
        "brokenredirectstext": "Các trang đổi hướng sau đây liên kết đến trang không tồn tại:",
        "deadendpages": "Trang đường cùng",
        "deadendpagestext": "Các trang này không có liên kết đến trang khác trong {{SITENAME}}.",
        "protectedpages": "Trang bị khóa",
+       "protectedpages-filters": "Bộ lọc:",
        "protectedpages-indef": "Chỉ hiển thị khóa vô hạn",
        "protectedpages-summary": "Danh sách này liệt kê các trang hiện đang bị khóa. Xem danh sách các tên trang bị khóa không được tạo ra tại [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Chỉ hiển thị khóa theo tầng",
        "protectedtitles-submit": "Xem các tên trang",
        "listusers": "Danh sách thành viên",
        "listusers-editsonly": "Chỉ hiện thành viên có tham gia sửa đổi",
+       "listusers-temporarygroupsonly": "Chỉ xem những người dùng trong nhóm người dùng tạm",
        "listusers-creationsort": "Xếp theo ngày khởi tạo",
        "listusers-desc": "Sắp xếp thứ tự giảm dần",
        "usereditcount": "$1 sửa đổi",
        "apisandbox-dynamic-parameters-add-label": "Thêm tham số:",
        "apisandbox-dynamic-parameters-add-placeholder": "Tên tham số",
        "apisandbox-dynamic-error-exists": "Một tham số có tên \"$1\" đã tồn tại.",
+       "apisandbox-templated-parameter-reason": "[[Special:ApiHelp/main#main/templatedparams|Tham số mẫu]] này được cung cấp theo {{PLURAL:$1|giá trị|các giá trị}} của $2.",
        "apisandbox-deprecated-parameters": "Tham số bị phản đối",
        "apisandbox-fetch-token": "Tự động điền token này",
+       "apisandbox-add-multi": "Thêm",
        "apisandbox-submit-invalid-fields-title": "Một số field là không hợp lệ",
        "apisandbox-submit-invalid-fields-message": "Xin vui lòng sửa các miền được đánh dấu và thử lại.",
        "apisandbox-results": "Kết quả",
        "rollback-success": "Đã hủy sửa đổi của {{GENDER:$3}}$1;\nquay về phiên bản cuối của {{GENDER:$4}}$2.",
        "rollback-success-notify": "Đã hủy sửa đổi của $1;\nquay về phiên bản cuối của $2. [$3 Xem thay đổi]",
        "sessionfailure-title": "Phiên thất bại",
-       "sessionfailure": "Dường như có trục trặc với phiên đăng nhập của bạn; thao tác này đã bị hủy để tránh việc cướp quyền đăng nhập. Xin hãy nhấn nút “Back”, tải lại trang đó, rồi thử lại.",
+       "sessionfailure": "Dường như có trục trặc với phiên đăng nhập của bạn; thao tác này đã bị hủy để tránh việc cướp quyền đăng nhập. Xin hãy gửi lại biểu mẫu.",
        "changecontentmodel": "Thay đổi kiểu nội dung của một trang",
        "changecontentmodel-legend": "Thay đổi kiểu nội dung",
        "changecontentmodel-title-label": "Tên trang",
        "whatlinkshere": "Các liên kết đến đây",
        "whatlinkshere-title": "Các trang liên kết đến “$1”",
        "whatlinkshere-page": "Trang:",
-       "linkshere": "Các trang sau liên kết đến '''[[:$1]]''':",
-       "nolinkshere": "Không có trang nào liên kết đến '''[[:$1]]'''.",
-       "nolinkshere-ns": "Không có trang nào liên kết đến '''[[:$1]]''' trong không gian tên đã chọn.",
+       "linkshere-2": "Các trang sau liên kết đến '''$1''':",
+       "nolinkshere-2": "Không có trang nào liên kết đến '''$1'''.",
+       "nolinkshere-ns-2": "Không có trang nào liên kết đến '''$1''' trong không gian tên đã chọn.",
        "isredirect": "trang đổi hướng",
        "istemplate": "được nhúng vào",
        "isimage": "liên kết tập tin",
        "fix-double-redirects": "Cập nhật tất cả các trang đổi hướng chỉ đến tựa đề cũ",
        "move-leave-redirect": "Để lại trang đổi hướng",
        "protectedpagemovewarning": "'''Cảnh báo:''' Trang này đã bị khóa nên chỉ có các thành viên có quyền quản lý mới có thể di chuyển được.\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
-       "semiprotectedpagemovewarning": "'''Lưu ý:''' Trang này đã bị khóa nên chỉ có các thành viên có tài khoản mới có thể di chuyển được.\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
+       "semiprotectedpagemovewarning": "<strong>Lưu ý:</strong> Trang này đã bị khóa nên chỉ có các thành viên tự xác nhận có thể di chuyển được.\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
        "move-over-sharedrepo": "[[:$1]] đã tồn tại trong kho dùng chung. Nếu đổi tên tập tin thành tên này thì sẽ ghi đè lên tập tin dùng chung.",
        "file-exists-sharedrepo": "Bạn đã chọn tên tập tin trùng với tập tin nằm trong kho dùng chung.\nXin hãy chọn tên khác.",
        "export": "Xuất các trang",
        "group-bot.css": "/* Mã CSS tại đây sẽ chỉ ảnh hưởng đến các bot */",
        "group-sysop.css": "/* Mã CSS tại đây sẽ chỉ ảnh hưởng đến các bảo quản viên */",
        "group-bureaucrat.css": "/* Mã CSS tại đây sẽ chỉ ảnh hưởng đến các hành chính viên */",
+       "common.json": "/* Bất kỳ mã JSON ở đây sẽ được tải cho tất cả các thành viên khi tải một trang nào đó lên. */",
        "common.js": "/* Bất kỳ mã JavaScript ở đây sẽ được tải cho tất cả các thành viên khi tải một trang nào đó lên. */",
        "group-autoconfirmed.js": "/* Mã JavaScript tại đây sẽ chỉ được tải cho các thành viên tự động xác nhận */",
        "group-user.js": "/* Mã JavaScript tại đây sẽ chỉ được tải cho các thành viên có tài khoản */",
        "autosumm-replace": "Đã thay thế cả nội dung bằng “$1”",
        "autoredircomment": "Đổi hướng đến [[$1]]",
        "autosumm-removed-redirect": "Xoá đổi hướng đến trang [[$1]]",
-       "autosumm-changed-redirect-target": "Thay đổi trang đích của đổi hướng từ [[$1]] sang [[S2]]",
+       "autosumm-changed-redirect-target": "Thay đổi trang đích của đổi hướng từ [[$1]] sang [[$2]]",
        "autosumm-new": "Tạo trang mới với nội dung “$1”",
        "autosumm-newblank": "Đã tạo trang trống",
        "size-bytes": "$1 byte",
        "version-specialpages": "Trang đặc biệt",
        "version-parserhooks": "Hook trong bộ xử lý",
        "version-variables": "Biến",
+       "version-editors": "Trình soạn",
        "version-antispam": "Chống spam",
        "version-other": "Phần mở rộng khác",
        "version-mediahandlers": "Bộ xử lý phương tiện",
        "version-poweredby-others": "những người khác",
        "version-poweredby-translators": "các biên dịch viên translatewiki.net",
        "version-credits-summary": "Chúng tôi muốn công nhận những người sau đã đóng góp vào [[Special:Version|MediaWiki]].",
-       "version-license-info": "MediaWiki là phần mềm tự do; bạn được phép tái phân phối và/hoặc sửa đổi nó theo những điều khoản của Giấy phép Công cộng GNU do Quỹ Phần mềm Tự do xuất bản; phiên bản 2 hay bất kỳ phiên bản nào mới hơn nào của Giấy phép.\n\nMediaWiki được phân phối với hy vọng rằng nó sẽ hữu ích, nhưng '''không có bất kỳ một bảo đảm nào cả''', ngay cả những bảo đảm ngụ ý cho '''các mục đích thương mại''' hoặc cho '''một mục đích đặc biệt nào đó'''. Xem Giấy phép Công cộng GNU để biết thêm chi tiết.\n\nCó lẽ bạn đã nhận [{{SERVER}}{{SCRIPTPATH}}/COPYING bản sao Giấy phép Công cộng GNU] đi kèm với tác phẩm này; nếu không, hãy viết thư đến:\n Free Software Foundation, Inc.\n 51 Franklin St., Fifth Floor\n Boston, MA 02110-1301\n USA\nhoặc [//www.gnu.org/licenses/old-licenses/gpl-2.0.html đọc nó trực tuyến].",
+       "version-license-info": "MediaWiki là phần mềm tự do; bạn được phép tái phân phối và/hoặc sửa đổi nó theo những điều khoản của Giấy phép Công cộng GNU do Quỹ Phần mềm Tự do xuất bản; phiên bản 2 hay bất kỳ phiên bản nào mới hơn nào của Giấy phép.\n\nMediaWiki được phân phối với hy vọng rằng nó sẽ hữu ích, nhưng <em>KHÔNG CÓ BẤT KỲ MỘT BAO ĐẢM NÀO CẢ</em>, ngay cả những bảo đảm ngụ ý cho <strong>CÁC MỤC ĐÍCH THƯƠNG MẠI</strong> hoặc cho <strong>MỘT MỤC ĐÍCH ĐẶC BIỆT NÀO ĐÓ</strong>. Xem Giấy phép Công cộng GNU để biết thêm chi tiết.\n\nCó lẽ bạn đã nhận [{{SERVER}}{{SCRIPTPATH}}/COPYING bản sao Giấy phép Công cộng GNU] đi kèm với tác phẩm này; nếu không, hãy viết thư đến:\n Free Software Foundation, Inc.\n 51 Franklin St., Fifth Floor\n Boston, MA 02110-1301\n USA\nhoặc [//www.gnu.org/licenses/old-licenses/gpl-2.0.html đọc nó trực tuyến].",
        "version-software": "Phần mềm được cài đặt",
        "version-software-product": "Phần mềm",
        "version-software-version": "Phiên bản",
        "limitreport-templateargumentsize-value": "$1/$2 byte",
        "limitreport-expansiondepth": "Độ sâu bung cao nhất",
        "limitreport-expensivefunctioncount": "Số lời gọi hàm cú pháp cần mức độ xử lý cao",
+       "limitreport-unstrip-size-value": "$1/$2 byte",
        "expandtemplates": "Bung bản mẫu",
-       "expand_templates_intro": "Trang đặc biệt này sẽ nhận vào văn bản và bung tất cả các bản mẫu trong nó ra một cách đệ quy cho đến hết. Nó cũng bung cả những hàm cú pháp như <code><nowiki>{{</nowiki>#language:…}}</code>, và những biến số như <code><nowiki>{{</nowiki>CURRENTDAY}}</code>. Thực ra nó bung các dữ liệu bình thường đặt trong ngoặc móc.",
+       "expand_templates_intro": "Trang đặc biệt này sẽ nhận vào mã wiki và bung tất cả các bản mẫu trong nó ra một cách đệ quy cho đến hết. Nó cũng bung cả những hàm cú pháp như <code><nowiki>{{</nowiki>#language:…}}</code>, và những biến số như <code><nowiki>{{</nowiki>CURRENTDAY}}</code>. Thực ra nó bung các dữ liệu bình thường đặt trong ngoặc móc.",
        "expand_templates_title": "Tên của trang văn cảnh (để phân tích {{FULLPAGENAME}} v.v.):",
-       "expand_templates_input": "Mã nguồn để bung:",
+       "expand_templates_input": "Mã wiki để bung:",
        "expand_templates_output": "Kết quả",
        "expand_templates_xml_output": "Xuất XML",
        "expand_templates_html_output": "Mã nguồn HTML thô",
        "expand_templates_preview": "Xem trước",
        "expand_templates_preview_fail_html": "<em>{{SITENAME}} cho phép mã nguồn HTML thô và dữ liệu phiên bị mất, nên bản xem trước bị ẩn để tránh tấn công JavaScript.</em>\n\n<strong>Nếu bạn thực sự muốn xem trước mã nguồn này, xin hãy thử lại nữa.</strong>\nNếu vẫn không được, hãy thử [[Special:UserLogout|đăng xuất]] rồi đăng nhập lại, và kiểm tra rằng trình duyệt của bạn cho phép các cookie của trang Web này.",
        "expand_templates_preview_fail_html_anon": "<em>{{SITENAME}} cho phép mã nguồn HTML thô và dữ liệu phiên bị mất, nên bản xem trước bị ẩn để tránh tấn công JavaScript.</em>\n\n<strong>Nếu bạn thực sự muốn xem trước mã nguồn này, xin hãy thử lại nữa.</strong>\nNếu vẫn không được, hãy [[Special:UserLogin|đăng nhập]] và thử lại lần nữa.",
-       "expand_templates_input_missing": "Bạn phải cung cấp văn bản nhập.",
+       "expand_templates_input_missing": "Bạn phải cung cấp mã wiki đầu vào.",
        "pagelanguage": "Thay đổi ngôn ngữ của trang",
        "pagelang-name": "Trang",
        "pagelang-language": "Ngôn ngữ",
        "unlinkaccounts-success": "Đã gỡ liên kết tài khoản.",
        "authenticationdatachange-ignored": "Tác vụ thay đổi dữ liệu xác thực không được xử lý. Có lẽ nhà cung cấp chưa được cấu hình?",
        "userjsispublic": "Xin lưu ý: Các trang con JavaScript không nên chứa dữ liệu bí mật, vì những người dùng khác có thể xem các trang này.",
+       "userjsonispublic": "Xin lưu ý: Các trang con JSON không nên chứa tin mật vì mọi người có thể xem trang.",
        "usercssispublic": "Xin lưu ý: Các trang con CSS không nên chứa dữ liệu bí mật, vì những người dùng khác có thể xem các trang này.",
        "restrictionsfield-badip": "Địa chỉ hoặc dải IP không hợp lệ: $1.",
        "restrictionsfield-label": "Các dải IP được cho phép:",
        "pagedata-title": "Dữ liệu về trang",
        "pagedata-text": "Trang này cung cấp giao diện dữ liệu cho các trang. Xin hãy cung cấp tên trang trong URL dùng cú pháp trang con.\n* Chế độ đàm phán nội dung được áp dụng tùy theo đầu đề Accept (chấp nhận) của trình khách của bạn. Điều này có nghĩa rằng dữ liệu trang được cung cấp dưới định dạng thích hợp nhất đối với trình khác của bạn.",
        "pagedata-not-acceptable": "Không tìm thấy định dạng phù hợp. Các kiểu MIME được hỗ trợ: $1",
-       "pagedata-bad-title": "Tiêu đề không hợp lệ: $1."
+       "pagedata-bad-title": "Tiêu đề không hợp lệ: $1.",
+       "unregistered-user-config": "Vì lý do bảo mật, các trang con JavaScript, CSS, và JSON của trang cá nhân không được tải cho những người dùng chưa đăng nhập.",
+       "passwordpolicies": "Quy định mật khẩu",
+       "passwordpolicies-summary": "Bảng này cho biết các quy định mật khẩu được áp dùng vào các nhóm người dùng được cấu hình tại wiki này.",
+       "passwordpolicies-group": "Nhóm",
+       "passwordpolicies-policies": "Quy định",
+       "passwordpolicies-policy-minimalpasswordlength": "Mật khẩu phải có ít nhất $1 ký tự",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Mật khẩu phải có ít nhất $1 ký tự để cho bạn đăng nhập",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Mật khẩu không thể khớp với tên người dùng",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Mật khẩu không thể khớp với các mật khẩu trong danh sách đen",
+       "passwordpolicies-policy-maximalpasswordlength": "Mật khẩu không thể vượt quá $1 ký tự",
+       "passwordpolicies-policy-passwordcannotbepopular": "Mật khẩu không thể {{PLURAL:$1|là mật khẩu phổ biến nhất|xuất hiện trong danh sách $1 mật khẩu phổ biến nhất}}"
 }
index a8988bf..6fa865f 100644 (file)
        "whatlinkshere": "Linggs af däj Saidn",
        "whatlinkshere-title": "Sajdn, di af „$1“ fârwajsn",
        "whatlinkshere-page": "Sajdn:",
-       "linkshere": "Dii afgfiirdn sajdn fârwajsn af ''„[[:$1]]“''':",
-       "nolinkshere": "Ka Seidn verlingt af '''„[[:$1]]“'''.",
+       "linkshere-2": "Dii afgfiirdn sajdn fârwajsn af ''„$1“''':",
+       "nolinkshere-2": "Ka Seidn verlingt af '''„$1“'''.",
        "isredirect": "Wajdârlajdungssajdn",
        "istemplate": "Foorlaachn-ajbindung",
        "isimage": "Daddeilink",
index 43a7b83..3526cd8 100644 (file)
        "whatlinkshere": "Yüms isio",
        "whatlinkshere-title": "Pads ad \"$1\" yumöls",
        "whatlinkshere-page": "Pad:",
-       "linkshere": "Pads sököl payümons ko '''[[:$1]]''':",
-       "nolinkshere": "Pads nonik peyümons lü '''[[:$1]]'''.",
-       "nolinkshere-ns": "Pads nonik yumons lü pad: '''[[:$1]]''' in nemaspad pevälöl.",
+       "linkshere-2": "Pads sököl payümons ko '''$1''':",
+       "nolinkshere-2": "Pads nonik peyümons lü '''$1'''.",
+       "nolinkshere-ns-2": "Pads nonik yumons lü pad: '''$1''' in nemaspad pevälöl.",
        "isredirect": "lüodükömapad",
        "istemplate": "ninükam",
        "isimage": "yüm ragiva",
        "fileduplicatesearch-result-1": "Ragiv: „$1“ no labon telükoti kuratik.",
        "fileduplicatesearch-result-n": "Ragiv: „$1“ labon {{PLURAL:$2|telükoti kuratik bal|telükotis kuratik $2}}.",
        "specialpages": "Pads patik",
+       "specialpages-note-restricted": "* Pads patik nomik.\n* <span class=\"mw-specialpagerestricted\">Pads patik pemiedüköl.</span>",
        "specialpages-group-maintenance": "Nunods tefü kiped",
        "specialpages-group-other": "Pads patik votik",
        "specialpages-group-login": "Nunädön oki / jafön kali",
index f888f7b..97d736b 100644 (file)
        "whatlinkshere": "Linkid tänne",
        "whatlinkshere-title": "Cüľľed, kummad näütellä cüľľelle \"$1\"",
        "whatlinkshere-page": "Cülci:",
-       "linkshere": "Vahtiaavilt cülciilt on linkki cüľľelle '''[[:$1]]''':",
-       "nolinkshere": "Mitäid eb viitata '''[[:$1]]-sõ'''",
+       "linkshere-2": "Vahtiaavilt cülciilt on linkki cüľľelle '''$1''':",
+       "nolinkshere-2": "Mitäid eb viitata '''$1-sõ'''",
        "isredirect": "mešaituzcülci",
        "istemplate": "sisällütüz šabloonii",
        "isimage": "kuvalinkki",
index 9b0c24a..fbac9a3 100644 (file)
        "whatlinkshere": "Siiäq näütäjäq lingiq",
        "whatlinkshere-title": "Leheq, miä näütäseq lehe \"$1\" pääle",
        "whatlinkshere-page": "Leht:",
-       "linkshere": "Lehe <b>[[:$1]]</b> pääle näütäseq lingiq lehti päält:",
-       "nolinkshere": "Lehe <b>[[:$1]]</b> pääle näütä-i linke ütegi lehe päält.",
-       "nolinkshere-ns": "Valitun nimeruumin näütä-i ütegi lehe päält linke lehe '''[[:$1]]''' pääle.",
+       "linkshere-2": "Lehe <b>$1</b> pääle näütäseq lingiq lehti päält:",
+       "nolinkshere-2": "Lehe <b>$1</b> pääle näütä-i linke ütegi lehe päält.",
+       "nolinkshere-ns-2": "Valitun nimeruumin näütä-i ütegi lehe päält linke lehe '''$1''' pääle.",
        "isredirect": "ümbresaatmislehekülg",
        "istemplate": "pruugit näüdüssen",
        "isimage": "teedüstülink",
        "fileduplicatesearch-filename": "Teedüstünimi:",
        "fileduplicatesearch-submit": "Otsiq",
        "specialpages": "Tallitusleheküleq",
+       "specialpages-note-restricted": "* Hariliguq tallitusleheq.\n* <strong class=\"mw-specialpagerestricted\">Piiredüq tallitusleheq.</strong>",
        "specialpages-group-maintenance": "Kõrranpidämisteedüseq",
        "specialpages-group-other": "Muuq tallitusleheq",
        "specialpages-group-login": "Nimega sisseminek / Pruukjanime luuminõ",
index 946da53..20a8a69 100644 (file)
        "whatlinkshere": "Pådjes ki loynut chal",
        "whatlinkshere-title": "Pådjes ki loynut aviè «$1»",
        "whatlinkshere-page": "Pådje:",
-       "linkshere": "Les pådjes ki shuvèt ont des loyéns viè '''[[:$1]]''':",
-       "nolinkshere": "Nole pådje avou des loyéns viè '''[[:$1]]'''.",
+       "linkshere-2": "Les pådjes ki shuvèt ont des loyéns viè '''$1''':",
+       "nolinkshere-2": "Nole pådje avou des loyéns viè '''$1'''.",
        "isredirect": "pådje di redjiblaedje",
        "isimage": "loyén viè l' fitchî",
        "whatlinkshere-prev": "{{PLURAL:$1|di dvant|$1 di dvant}}",
index b03b0a9..7f8ae9a 100644 (file)
        "whatlinkshere": "Mga nasumpay dinhi",
        "whatlinkshere-title": "Mga pakli nga nasumpay ngadto ha \"$1\"",
        "whatlinkshere-page": "Pakli:",
-       "linkshere": "An masunod nga mga pakli in nasumpay ha '''[[:$1]]''':",
-       "nolinkshere": "Waray mga pakli nga nasumpay ha '''[[:$1]]'''",
+       "linkshere-2": "An masunod nga mga pakli in nasumpay ha '''$1''':",
+       "nolinkshere-2": "Waray mga pakli nga nasumpay ha '''$1'''",
        "isredirect": "Redirek nga pakli",
        "istemplate": "transklusyon",
        "isimage": "sumpay han fayl",
index f1cbdda..80f245a 100644 (file)
        "whatlinkshere": "Xët yi mu lëkkalool",
        "whatlinkshere-title": "Xët yi lëkkalook wii « $1 »",
        "whatlinkshere-page": "Xët :",
-       "linkshere": "Xët yii ci suuf am nañ ab lëkkalekaay buy jëm <b>[[:$1]]</b> :",
-       "nolinkshere": "Amul wenn xët wu lëkkalook wii <b>[[:$1]]</b>.",
-       "nolinkshere-ns": "Amul wenn xët wu lëkkalook wii '''[[:$1]]''' ci barabu tur bi nga tànn.",
+       "linkshere-2": "Xët yii ci suuf am nañ ab lëkkalekaay buy jëm <b>$1</b> :",
+       "nolinkshere-2": "Amul wenn xët wu lëkkalook wii <b>$1</b>.",
+       "nolinkshere-ns-2": "Amul wenn xët wu lëkkalook wii '''$1''' ci barabu tur bi nga tànn.",
        "isredirect": "Xëtu jubluwaat",
        "istemplate": "mboole",
        "isimage": "lëkkalekaayu dencukaay bi",
index 3e1f16e..0136f2e 100644 (file)
        "whatlinkshere": "链进来点啥",
        "whatlinkshere-title": "链接到“$1”个页面",
        "whatlinkshere-page": "页面:",
-       "linkshere": "下头个页链到[[:$1]]:",
-       "nolinkshere": "呒不页面链到<strong>[[:$1]]</strong>。",
+       "linkshere-2": "下头个页链到$1:",
+       "nolinkshere-2": "呒不页面链到<strong>$1</strong>。",
        "isredirect": "转戳页",
        "istemplate": "包括",
        "isimage": "文件鏈接",
index 4bec10d..8fb37e0 100644 (file)
        "whatlinkshere": "Эн һазрур заалһуд",
        "whatlinkshere-title": "«$1» гидг нерәдлһтә халхд заалдг халхс",
        "whatlinkshere-page": "Халх:",
-       "linkshere": "Тер халхс '''[[:$1]]''' халхд заалдг:",
+       "linkshere-2": "Тер халхс '''$1''' халхд заалдг:",
        "isredirect": "авч оддг халх",
        "istemplate": "оруллһн",
        "isimage": "зургин  заалһ",
index aec1a47..1930403 100644 (file)
        "whatlinkshere": "სოვრეშე რე თე ხასჷლა წურაფილი",
        "whatlinkshere-title": "ხასჷლეფი, ნამუთ გინორცხილ რე $1-შა",
        "whatlinkshere-page": "ხასჷლა:",
-       "linkshere": "გეჸვენჯ ხასჷლეფი გინარცხუაფუ '''[[:$1]]'''-ეფს",
-       "nolinkshere": "ნამთინ ხასილა ვა რე გინორცხილ '''[[:$1]]'''-შა.",
+       "linkshere-2": "გეჸვენჯ ხასჷლეფი გინარცხუაფუ '''$1'''-ეფს",
+       "nolinkshere-2": "ნამთინ ხასილა ვა რე გინორცხილ '''$1'''-შა.",
        "isredirect": "გინოწურაფაშ ხასჷლა",
        "istemplate": "ტრანსკლუზია",
        "isimage": "ფაილიშ რცხი",
        "fileduplicatesearch-submit": "გორუა",
        "specialpages": "გჷშაკერძაფილი ხასჷლეფი",
        "specialpages-note-top": "ლეგენდა",
+       "specialpages-note-restricted": "* ჩვეულებრივი სპეცგვერდები.\n* <span class=\"mw-specialpagerestricted\">სპეცგვერდები შეზღუდული წვდომით.</span>",
        "specialpages-group-maintenance": "ტექნიკური მომსახურების ანგარიშები",
        "specialpages-group-other": "სხვა სპეციალური გვერდები",
        "specialpages-group-login": "მიშულა/ანგარიშიშ გონწყუმა",
index c9a0170..200fc66 100644 (file)
        "whatlinkshere": "װאָס פֿאַרבינדט אַהער",
        "whatlinkshere-title": "בלעטער וואס פֿארבינדן צו $1",
        "whatlinkshere-page": "בלאַט:",
-       "linkshere": "די פאלגנדע בלעטער פארבינדן צום בלאט '''[[:$1]]''':",
-       "nolinkshere": "קיין שום בלאט פארבינדט נישט צו '''[[:$1]]'''.",
-       "nolinkshere-ns": "קיין בלעטער פֿאַרבינדן נישט צו '''[[:$1]]''' אינעם אויסגעקליבענעם נאמענטייל.",
+       "linkshere-2": "די פאלגנדע בלעטער פארבינדן צום בלאט '''$1''':",
+       "nolinkshere-2": "קיין שום בלאט פארבינדט נישט צו '''$1'''.",
+       "nolinkshere-ns-2": "קיין בלעטער פֿאַרבינדן נישט צו '''$1''' אינעם אויסגעקליבענעם נאמענטייל.",
        "isredirect": "ווײַטערפירן בלאט",
        "istemplate": "אײַנשליסן",
        "isimage": "!טעקע לינק",
        "fileduplicatesearch-noresults": "קיין טעקע מיטן נאמען \"$1\" נישט געטראפֿן.",
        "specialpages": "ספעציעלע בלעטער",
        "specialpages-note-top": "לעגענדע",
+       "specialpages-note-restricted": "* נארמאַלע באַזונדערע בלעטער.\n* <span class=\"mw-specialpagerestricted\">באַגרענעצטע באַזונדערע בלעטער.</span>",
        "specialpages-group-maintenance": "אויפֿהאַלטונג באַריכטן",
        "specialpages-group-other": "אַנדערע ספעציעלע בלעטער",
        "specialpages-group-login": "ארײַנלאגירן / שאַפֿן קאנטע",
index e86700b..0618976 100644 (file)
        "recentchangeslinked-feed": "Àtúnṣe tó báramu",
        "recentchangeslinked-toolbox": "Àtúnṣe tó báramu",
        "recentchangeslinked-title": "Àtúnṣe tó báramu mọ́ \"$1\"",
-       "recentchangeslinked-summary": "Àkójọ àwọn àtúnṣe tí a sẹ̀sẹ̀ ṣe sí àwọn ojúewé tó jápọ̀ wá láti ojúewé pàtó kan (tàbí sí ìkan nìnú ẹ̀ka pàtó kan).\nÀwọn ojúewé inú [[Special:Watchlist|ìmójútó yín]] jẹ́ '''kedere'''.",
+       "recentchangeslinked-summary": "Ẹ tẹ orúkọ ojúewé láti rí àwọn àtúnṣe lórí àwọn ojúewé tí wọ́n jápọ̀ sí tàbí jápọ̀ wá láti ọ̀dọ̀ ojúewé nà. (Láti rí àwọn ojúewé inú ẹ̀ka, ẹ tẹ {{ns:category}}:Orúkọ ẹ̀ka).\nÀwọn àtúnṣe ojúewé inú [[Special:Watchlist|Ìtòjọ àmójútó yín]] ni àwọn tó hàn <strong>kedere</strong>.",
        "recentchangeslinked-page": "Orúkọ ojúewé:",
        "recentchangeslinked-to": "Àfihàn àwọn àtúnṣe sí àwọn ojúewé tójápọ̀ mọ́ ojúewé ọ̀hún dípò",
        "upload": "Ìrùsókè fáìlì",
        "whatlinkshere": "Ìjápọ̀ mọ́ ojúewé yí",
        "whatlinkshere-title": "Àwọn ojúewé tó jápọ̀ mọ́ \"$1\"",
        "whatlinkshere-page": "Ojúewé:",
-       "linkshere": "Àwọn ojúewé wọ̀nyí jápọ̀ mọ́ '''[[:$1]]''':",
-       "nolinkshere": "Kò sí ojúewé tó jápọ̀ mọ́ '''[[:$1]]'''.",
-       "nolinkshere-ns": "Kò sí ojúewé kankan tó jápọ̀ mọ́ '''[[:$1]]''' nínú orúkọàyè yíyàn.",
+       "linkshere-2": "Àwọn ojúewé wọ̀nyí jápọ̀ mọ́ '''$1''':",
+       "nolinkshere-2": "Kò sí ojúewé tó jápọ̀ mọ́ '''$1'''.",
+       "nolinkshere-ns-2": "Kò sí ojúewé kankan tó jápọ̀ mọ́ '''$1''' nínú orúkọàyè yíyàn.",
        "isredirect": "àtúnjúwe ojúewé",
        "istemplate": "ìkómọ́ra",
        "isimage": "ìjápọ̀ fáìlì",
        "fileduplicatesearch-result-n": "Fáìlì \"$1\" ní {{PLURAL:$2|ìdáwòkọ jíjọra 1|ìdáwòkọ jíjọra $2}}.",
        "fileduplicatesearch-noresults": "Kò sí fáìlì tó únjẹ́ \"$1\".",
        "specialpages": "Àwọn ojúewé pàtàkì",
+       "specialpages-note-restricted": "* Àwọn ojúewé pàtàkì onídéédé.\n* <span class=\"mw-specialpagerestricted\">Àwọn ojúewé pàtàkì àìgbàláyè.</span>",
        "specialpages-group-maintenance": "Àwọn ìjábọ̀ ìtọ́jú",
        "specialpages-group-other": "Àwọn ojúewé pàtàkì míràn",
        "specialpages-group-login": "Ìwọlé / ìdá àpamọ́",
index 0710586..243da62 100644 (file)
@@ -33,7 +33,9 @@
                        "Asdfugil",
                        "Deryck Chan",
                        "Hello903hello",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Kanashimi",
+                       "Roy17"
                ]
        },
        "tog-underline": "連結加底線:",
        "cascadeprotected": "呢一版已經保護咗唔能夠編輯,因為佢係響以下嘅{{PLURAL:$1|一|幾}}頁度包含咗,當中啟用咗\"連串\"保護選項來保護嗰一版: $2",
        "namespaceprotected": "你無權編輯響'''$1'''空間名裏面嘅呢一版。",
        "customcssprotected": "你無權改呢版CSS,因為佢包含其他用戶嘅個人設定。",
+       "customjsonprotected": "你無權改呢版JSON,因為佢包含其他用戶嘅個人設定。",
        "customjsprotected": "你無權改呢版JavaScript,因為佢包含其他用戶嘅個人設定。",
        "mycustomcssprotected": "你無權改呢版CSS。",
+       "mycustomjsonprotected": "你無權改呢版JSON。",
        "mycustomjsprotected": "你無權改呢版JavaScript。",
        "myprivateinfoprotected": "你無權改呢版你嘅私人資料。",
        "mypreferencesprotected": "你無權改呢版你嘅個人設定。",
        "botpasswords-deleted-body": "{{GENDER:$2|用戶}}「$2」嘅機械人「$1」嘅密碼已經剷走咗。",
        "botpasswords-restriction-failed": "機械人密碼限制令到呢次簽到失敗。",
        "botpasswords-invalid-name": "呢個用戶名無機械人密碼分隔字(「$1」)",
+       "botpasswords-not-exist": "用戶「$1」無叫做「$2」嘅機械人密碼。",
+       "botpasswords-needs-reset": "{{GENDER:$1|用戶}}「$1」嘅機械人「$2」嘅密碼一定要重新改。",
        "resetpass_forbidden": "唔可以更改密碼",
        "resetpass_forbidden-reason": "改唔到密碼:$1",
        "resetpass-no-info": "你一定要登入咗去直接入來呢一版。",
        "subject-preview": "主題預覽:",
        "previewerrortext": "預覽你嘅修改嗰陣出錯。",
        "blockedtitle": "用戶已經封鎖",
-       "blockedtext": "你嘅用戶名或者 IP 位址已經被 $1 封咗。\n\n呢次封鎖係由$1所封嘅。當中嘅原因係''$2''。\n\n* 呢次封鎖嘅開始時間係:$8\n* 呢次封鎖嘅到期時間係:$6\n* 對於被封鎖者:$7\n\n你可以聯絡 $1 或者其他嘅[[{{MediaWiki:Grouppage-sysop}}|管理員]],討論呢次封鎖。\n除非你已經響你嘅[[Special:Preferences|戶口喜好設定]]入面設定咗有效嘅電郵地址,否則你係唔可以用「電郵呢個用戶」嘅功能。當設定咗一個有效嘅電郵地址之後,呢個功能係唔會封鎖嘅。\n\n你現時嘅 IP 位址係 $3 ,而個封鎖 ID 係 #$5。 請你喺你嘅查詢都註明以上封鎖嘅資料。",
+       "blockedtext": "<strong>你嘅用戶名或者IP地址已經俾人封咗。</strong>\n\n呢次封鎖係由$1所封嘅。\n俾咗嘅原因係<em>$2</em>。\n\n* 呢次封鎖嘅開始時間係:$8\n* 呢次封鎖嘅到期時間係:$6\n* 被封鎖者:$7\n\n你可以聯絡 $1 或者其他嘅[[{{MediaWiki:Grouppage-sysop}}|管理員]]討論呢次封鎖。\n除非你已經響你嘅[[Special:Preferences|戶口喜好設定]]入面設定咗有效嘅電郵地址,否則你係唔可以用「{{int:emailuser}}」嘅功能。當設定咗一個有效嘅電郵地址之後,呢個功能係唔會被封鎖嘅。\n你現時嘅IP地址係 $3 ,而個封鎖ID係 #$5。\n請喺你嘅查詢都註明以上封鎖嘅資料。",
        "autoblockedtext": "你嘅IP地址已經被自動封鎖,由於之前嘅另一位用戶係畀$1封咗。\n而封鎖嘅原因係:\n\n:''$2''\n\n* 呢次封鎖嘅開始時間係:$8\n* 呢次封鎖嘅到期時間係:$6\n* 對於被封鎖者:$7\n\n你可以聯絡 $1 或者其他嘅[[{{MediaWiki:Grouppage-sysop}}|管理員]],討論呢次封鎖。\n\n除非你已經響你嘅[[Special:Preferences|戶口喜好設定]]入面設定咗有效嘅電郵地址,否則你係唔可以用「電郵呢個用戶」嘅功能。當設定咗一個有效嘅電郵地址之後,呢個功能係唔會封鎖嘅。\n\n你現時用緊嘅 IP 地址係 $3,個封鎖 ID 係 #$5。 請喺你嘅查詢都註明呢個封鎖上面嘅資料。",
        "systemblockedtext": "你嘅用戶名或者IP地址已經俾MediaWiki自動封鎖。\n封鎖原因係:\n\n:<em>$2</em>\n\n* 開始時間:$8\n* 到期時間:$6\n* 目標用戶:$7\n\n你而家嘅IP地址係$3。\n當你作出任何查詢嘅時候,請包含以上所有資料。",
        "blockednoreason": "無原因畀低",
        "post-expand-template-argument-warning": "警告: 呢一版有最少一個模參數有太大嘅擴展大細。\n呢啲參數會被略過。",
        "post-expand-template-argument-category": "包含住略過模參數嘅版",
        "parser-template-loop-warning": "已偵測迴模: [[$1]]",
+       "template-loop-category": "有循環模嘅頁",
        "parser-template-recursion-depth-warning": "迴模深度限制超過咗 ($1)",
        "language-converter-depth-warning": "字體變換器深度限制超過咗 ($1)",
        "node-count-exceeded-category": "有頁面超出咗指定數",
        "prefs-dateformat": "日期格式",
        "prefs-timeoffset": "時間偏移",
        "prefs-advancedediting": "普通選項",
+       "prefs-developertools": "開發者工具",
        "prefs-editor": "編輯",
        "prefs-preview": "預覽",
        "prefs-advancedrc": "進階選項",
        "right-editcontentmodel": "改版面嘅內容模型",
        "right-editinterface": "編輯用戶界面",
        "right-editusercss": "編輯其他用戶嘅CSS檔",
+       "right-edituserjson": "編輯其他用戶嘅JSON檔",
        "right-edituserjs": "編輯其他用戶嘅JavaScript檔",
-       "right-editmyusercss": "編輯戶口嘅CSS文件",
-       "right-editmyuserjs": "編輯戶口嘅JavaScript文件",
+       "right-editmyusercss": "編輯你自己嘅用戶CSS檔",
+       "right-editmyuserjson": "編輯你自己嘅用戶JSON檔",
+       "right-editmyuserjs": "編輯你自己嘅用戶JavaScript檔",
        "right-viewmywatchlist": "睇你自己嘅監視一覽",
        "right-viewmyprivateinfo": "睇下個人信息(例如電郵或真名)",
        "right-editmyprivateinfo": "修改個人信息(例如電郵或真名)",
        "right-sendemail": "寄電郵畀其他用戶",
        "right-managechangetags": "開同(取消)啟用[[Special:Tags|標籤]]",
        "right-applychangetags": "套用[[Special:Tags|標籤]]到某個人嘅改動",
+       "right-deletechangetags": "由資料庫刪[[Special:Tags|標籤]]",
+       "grant-generic": "「$1」權限組合",
        "grant-group-page-interaction": "同版面互動",
        "grant-group-file-interaction": "同傳媒互動",
        "grant-group-watchlist-interaction": "同監視清單互動",
        "grant-group-email": "送電郵",
+       "grant-group-high-volume": "執行大量活動",
        "grant-group-customization": "自訂同設定",
        "grant-group-administration": "做管理行動",
        "grant-group-private-information": "存取你嘅私隱資料",
        "grant-editmywatchlist": "改你嘅監視清單",
        "grant-editpage": "改已經有嘅版",
        "grant-editprotected": "改保護咗嘅版",
+       "grant-highvolume": "大量編輯",
+       "grant-oversight": "收埋用戶同禁止顯示修訂",
+       "grant-sendemail": "寄電郵畀其他用戶",
        "grant-uploadfile": "上載新檔案",
        "grant-basic": "基本權利",
+       "grant-viewdeleted": "睇刪咗嘅檔同頁",
        "grant-viewmywatchlist": "睇你嘅監視清單",
        "newuserlogpage": "使用者開戶記錄",
        "newuserlogpagetext": "呢個係一個使用者開戶嘅日誌",
        "action-editcontentmodel": "改頁面內容模型",
        "action-managechangetags": "從數據庫開或刪走啲符",
        "action-applychangetags": "套用標籤到你嘅改動",
+       "action-purge": "清呢版個快取版本",
        "nchanges": "$1次更改",
        "enhancedrc-since-last-visit": "{{PLURAL:$1|你上次嚟之後}}有 $1 個",
        "enhancedrc-history": "歷史",
        "recentchanges-label-unpatrolled": "呢次編輯重未巡查過",
        "recentchanges-label-plusminus": "頁面位元組大細變化",
        "recentchanges-legend-heading": "<strong>標記:</strong>",
-       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (睇埋[[Special:NewPages|新開版]])",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (睇埋[[Special:NewPages|新版一覽]])",
        "recentchanges-submit": "顯示",
        "rcfilters-tag-remove": "剷走 $1",
        "rcfilters-legend-heading": "<strong>縮寫一覽:</strong>",
        "whatlinkshere": "有乜嘢連結來呢度",
        "whatlinkshere-title": "連到「$1」嘅頁",
        "whatlinkshere-page": "頁:",
-       "linkshere": "呢啲頁連結到'''[[:$1]]''':",
-       "nolinkshere": "無一頁連結到'''[[:$1]]'''。",
-       "nolinkshere-ns": "響已經揀咗嘅空間名無嘢連結到'''[[:$1]]'''。",
+       "linkshere-2": "呢啲頁連結到'''$1''':",
+       "nolinkshere-2": "無一頁連結到'''$1'''。",
+       "nolinkshere-ns-2": "響已經揀咗嘅空間名無嘢連結到'''$1'''。",
        "isredirect": "跳轉頁",
        "istemplate": "包含",
        "isimage": "檔案連結",
        "watchlistedit-normal-legend": "響監視清單度拎走",
        "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|標準編輯器]]。",
        "fileduplicatesearch-result-n": "個檔案 \"$1\" 有$2項完全相同嘅重覆。",
        "fileduplicatesearch-noresults": "檔案名\"$1\"找不到",
        "specialpages": "特別頁",
+       "specialpages-note-restricted": "* 標準特別頁。\n* <span class=\"mw-specialpagerestricted\">有限制嘅特別頁。</span>",
        "specialpages-group-maintenance": "維護報告",
        "specialpages-group-other": "其它特別頁",
        "specialpages-group-login": "簽到/開新戶口",
        "authmanager-email-help": "電郵地址",
        "authmanager-realname-label": "真名",
        "authmanager-realname-help": "用戶嘅真名",
-       "authprovider-resetpass-skip-label": "跳過"
+       "authprovider-resetpass-skip-label": "跳過",
+       "passwordpolicies": "密碼政策",
+       "passwordpolicies-summary": "爾度係對爾個wiki定義咗嘅用戶組來講有效嘅密碼政策一覽。",
+       "passwordpolicies-group": "組",
+       "passwordpolicies-policies": "政策",
+       "passwordpolicies-policy-minimalpasswordlength": "密碼一定要有至少$1個{{PLURAL:$1|字元}}長",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "密碼一定要有至少$1個{{PLURAL:$1|字元}}長先可以簽到",
+       "passwordpolicies-policy-passwordcannotmatchusername": "密碼唔可以同用戶名一樣",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "密碼唔可以同列入咗黑名單嘅密碼一樣",
+       "passwordpolicies-policy-maximalpasswordlength": "密碼一定要短過$1個{{PLURAL:$1|字元}}長",
+       "passwordpolicies-policy-passwordcannotbepopular": "密碼唔可以{{PLURAL:$1|係最常見嘅密碼|喺最常見嘅$1個密碼一覽度}}"
 }
index f8c6f24..a545f62 100644 (file)
        "whatlinkshere": "Links nae deze bladzie",
        "whatlinkshere-title": "Pagina's die verwiez'n nir \"$1\"",
        "whatlinkshere-page": "Pagina:",
-       "linkshere": "De volhende pagina's verwieze nir '''[[:$1]]''':",
-       "nolinkshere": "Hin enkele pagina verwies nir '''[[:$1]]'''.",
+       "linkshere-2": "De volhende pagina's verwieze nir '''$1''':",
+       "nolinkshere-2": "Hin enkele pagina verwies nir '''$1'''.",
        "isredirect": "deurverwiespagina",
        "istemplate": "ingevoegd as sjabloon",
        "isimage": "bestandsverwiezienge",
index cc2c27e..d72a4e9 100644 (file)
        "searchall": "ⴰⴽⴽ",
        "search-nonefound": "ⵓⵔ ⵍⵍⵉⵏⵜ ⵜⵢⴰⴼⵓⵜⵉⵏ ⵉⵎⵙⴰⵙⴰⵏ ⴷ ⵓⵙⵓⵜⵔ.",
        "mypreferences": "ⵉⵙⵎⵏⵢⵉⴼⵏ",
+       "prefs-watchlist-days": "ⵓⵙⵙⴰⵏ ⵜⵓⵙⴽⵏⵉⵏ ⴳ ⵓⵎⵓⵖ ⵓⵙⵎⵓⵇⵇⵍ",
+       "recentchangesdays": "ⵓⵙⵙⴰⵏ ⵜⵓⵙⴽⵏⵉⵏ ⴳ ⵉⵙⵏⴼⵉⵍⵏ ⵉⵎⴳⴳⵓⵔⴰ",
        "prefs-files": "ⵉⴼⴰⵢⵍⵓⵜⵏ",
        "youremail": "ⵉⵎⴰⵢⵍ:",
        "yourlanguage": "ⵜⵓⵜⵍⴰⵢⵜ:",
        "prefs-signature": "ⴰⵙⴳⵎⴹ",
        "userrights-reason": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
        "group-sysop": "ⵉⵏⵎⵀⴰⵍⵏ",
+       "right-edit": "ⵙⵏⴼⵍ ⵜⴰⵙⵏⵉⵡⵉⵏ",
        "right-upload": "ⵙⴽⵜⵔ ⵉⴼⴰⵢⵍⵓⵜⵏ",
        "right-upload_by_url": "ⵙⴽⵜⵔ ⴰⴼⴰⵢⵍⵓ ⵙⴳ URL",
        "right-writeapi": "ⴰⵙⵙⵎⵔⵙ ⵏ API ⵉ ⵜⵉⵔⵔⴰ",
        "recentchanges-label-plusminus": "ⵜⴰⵙⵎⴽⵜⴰ ⵏ ⵜⴰⵙⵏⴰ ⴰⴷ ⵜⵙⵙⵏⴼⵍ ⵙ ⵓⵎⴹⴰⵏ ⴰⴷ ⵏ ⵉⴱⴰⵢⵜⵏ",
        "recentchanges-legend-heading": "<strong>ⴰⵙⵙⴼⵔⵓ:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ⵥⵔ ⴰⵍⵜⵓ [[Special:NewPages|ⵜⴰⵍⴳⴰⵎⵜ ⵏ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵜⵉⵎⴰⵢⵏⵓⵜⵉⵏ]])",
+       "rcfilters-days-title": "ⵓⵙⵙⴰⵏ ⵉⵎⴳⴳⵓⵔⴰ",
+       "rcfilters-days-show-days": "$1 ⵏ {{PLURAL:$1|ⵡⴰⵙⵙ|ⵡⵓⵙⵙⴰⵏ}}",
        "rclistfrom": "ⵙⴽⵏ ⵉⵙⵏⴼⵍⵏ ⵉⵎⴰⵢⵏⵓⵜⵏ ⵙⴳ $2,$3",
        "rcshowhideminor": "$1 ⵉⵙⵏⴼⴰⵍ ⵓⵎⵥⵉⵢⵏ",
        "rcshowhideminor-show": "ⵙⴽⵏ",
        "randompage": "ⵜⴰⵙⵏⴰ ⵜⴰⴷⵀⵎⴰⵙⵜ",
        "statistics": "ⴰⵙⵏⵎⴽⵜⴰ",
        "statistics-pages": "ⵜⴰⵙⵏⵉⵡⵉⵏ",
+       "brokenredirects-edit": "ⵙⵏⴼⵍ",
        "brokenredirects-delete": "ⴽⴽⵙ",
        "withoutinterwiki-legend": "ⴰⵣⵡⵉⵔ",
        "nbytes": "$1 {{PLURAL:$1|ⴱⴰⵢⵜ|ⵉⴷ ⴱⴰⵢⵜ}}",
        "whatlinkshere": "ⵎⴰ ⴰⵢⴷ ⵉⵇⵇⵏⵏ ⵙ ⴷⴰ",
        "whatlinkshere-title": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⵉⵣⴷⵉⵏ ⵖⵔ $1",
        "whatlinkshere-page": "ⵜⴰⵙⵏⴰ:",
-       "linkshere": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⴰⴷ ⵣⴷⵉⵏ ⵖⵔ <strong>[[:$1]]</strong>:",
-       "nolinkshere": "ⵓⵔ ⵍⵍⵉⵏ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵉⵣⴷⵉⵏ ⵖⵔ <strong>[[:$1]]</strong>",
+       "linkshere-2": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⴰⴷ ⵣⴷⵉⵏ ⵖⵔ <strong>$1</strong>:",
+       "nolinkshere-2": "ⵓⵔ ⵍⵍⵉⵏ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵉⵣⴷⵉⵏ ⵖⵔ <strong>$1</strong>",
        "isredirect": "ⵙⵡⴰⵍⴰ ⵜⴰⵙⵏⴰ",
        "istemplate": "ⴰⵙⵙⵓⵎⵢ",
        "isimage": "ⴰⵙⵖⵓⵏ ⵏ ⵓⴼⴰⵢⵍⵓ",
        "show-big-image-preview": "ⵜⴰⵙⵎⴽⵜⴰ ⵏ ⵓⵣⵔⵉⵣⵡⴰⵔ ⴰⴷ: $1.",
        "show-big-image-other": "{{PLURAL:$2|ⵜⴰⴼⵙⴰⵢⵜ|ⵜⵉⴼⵙⴰⵢⵉⵏ}}: ⵢⴰⴹⵏ $1.",
        "show-big-image-size": "$1 × $2 ⵉⴷ ⴱⵉⴽⵙⵍ",
+       "days": "{{PLURAL:$1|$1 ⵡⴰⵙⵙ|$1 ⵡⵓⵙⵙⴰⵏ}}",
        "metadata": "ⵎⵉⵜⴰⴷⴰⵜⴰ",
        "metadata-help": "ⴰⵙⴷⴰⵡ ⴰ ⵢⵓⵎⴰ ⵉⵏⵖⵎⵉⵙⵏ ⵉⵎⵔⵏⴰⵏⵉⵏ, ⵉⵔⵡⴰⵙ ⵉⵙ ⴰⵙ ⵜⵜⵡⴰⵔⵏⵉⵏ ⵙ ⵍⴽⴰⵎⵉⵔⴰ ⵜⴰⵎⵓⵟⵟⵓⵏⵜ ⵏⵖ ⴰⵙⵏⴼⴰⵍ ⴰⵎⵓⵟⵟⵓⵏ ⵉⵜⵜⴰⵡⵙⵎⵔⵙⵏ ⴳ ⵓⵙⵏⴼⵍⵓⵍ ⵏ ⵓⵙⴷⴰⵡ ⴰ.\nⵉⵖ ⵉⵜⵜⵙⵏⴼⵍ ⵓⵙⴷⴰⵡ ⴰ ⵙⴳ ⵡⴰⴷⴷⴰⴷ ⵏⵙ ⴰⵎⵓⴷⴰⵏ, ⴽⵔⴰ ⵏ ⵉⴼⵔⵓⵔⵉⵜⵏ ⵓⵔ ⵔⴰⵏ ⵙⵓⵍ ⴳⵔⵏ ⴳ ⵓⵙⴷⴰⵡ ⵉⵜⵜⵙⵏⴼⵍⵏ.",
        "metadata-fields": "ⵉⴳⵔⴰⵏ ⵏ ⵎⵉⵜⴰⵉⵙⴼⴽⴰ ⵏ ⵜⵉⵡⵍⴰⴼⵉⵏ ⵏⵏⴰ ⵉⴼⵙⵔⵏ ⴳ ⵜⴱⵔⴰⵜ ⴰⴷ ⵔⴰⴷ ⵉⵍⵉⵏ ⴳ ⵜⴰⵙⵏⴰ ⵏ ⵓⵙⵏⵓⵎⵎⵍ ⵏ ⵜⴰⵡⵍⴰⴼⵜ ⴰⴽⵓⴷ ⵏⵏⴰ ⵉⵎⵓⵏ ⵓⵙⴽⵜⵓⵔ. ⵉⴳⵔⴰⵏ ⵢⴰⴹⵏ ⵔⴰⴷ ⴼⴼⵔⵏ ⵙ ⵓⵎⵕⴰⴹ.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|ⴰⵔⵛⵓⵎ|ⵉⵔⵛⵓⵎⵏ}}]]: $2)",
        "tags-active-yes": "ⵢⴰⵀ",
        "tags-active-no": "ⵓⵀⵓ",
+       "tags-edit": "ⵙⵏⴼⵍ",
        "tags-delete": "ⴽⴽⵙ",
        "tags-create-reason": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
        "tags-delete-reason": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
index 1eaf278..f81d57a 100644 (file)
        "subject-preview": "主题的预览:",
        "previewerrortext": "尝试预览您的更改时发生错误。",
        "blockedtitle": "用户被封禁",
-       "blockedtext": "<strong>您的用户名或IP地址已被封禁。</strong>\n\n执行封禁的管理员是$1。封禁原因是<em>$2</em>。\n\n* 开始时间:$8\n* 到期时间:$6\n* 目标用户:$7\n\n您可以联络$1或其他[[{{MediaWiki:Grouppage-sysop}}|管理员]]讨论该封禁。只有当您在[[Special:Preferences|系统设置]]确认了电子邮件地址且未被禁止使用“电邮联系”功能时,才可以使用它。您当前的IP地址是$3,该封禁ID是#$5。请在您做出的任何查询中包含所有上述详情。",
-       "autoblockedtext": "您的IP地址因曾被一位被$1封禁的用户使用而被自动封禁。封禁原因:\n\n:<em>$2</em>\n\n* 开始时间:$8\n* 到期时间:$6\n* 目标用户:$7\n\n您可以联系$1或其他[[{{MediaWiki:Grouppage-sysop}}|管理员]]申诉该封禁。\n\n请注意,只有当您已在[[Special:Preferences|系统设置]]确认了电子邮件地址且未被禁止使用“电邮联系”功能时,才能发送电子邮件联系管理员。\n\n您当前的IP地址为$3,该封禁ID为#$5。请在您做出的任何查询中包含所有上述详情。",
+       "blockedtext": "<strong>您的用户名或IP地址已被封禁。</strong>\n\n执行封禁的管理员是$1。封禁原因是<em>$2</em>。\n\n* 开始时间:$8\n* 到期时间:$6\n* 目标用户:$7\n\n您可以联络$1或其他[[{{MediaWiki:Grouppage-sysop}}|管理员]]讨论该封禁。只有当您在[[Special:Preferences|系统设置]]确认了电子邮件地址且未被禁止使用“{{int:emailuser}}”功能时,才可以使用它。您当前的IP地址是$3,该封禁ID是#$5。请在您做出的任何查询中包含所有上述详情。",
+       "autoblockedtext": "您的IP地址因曾被一位被$1封禁的用户使用而被自动封禁。封禁原因:\n\n:<em>$2</em>\n\n* 开始时间:$8\n* 到期时间:$6\n* 目标用户:$7\n\n您可以联系$1或其他[[{{MediaWiki:Grouppage-sysop}}|管理员]]申诉该封禁。\n\n请注意,只有当您已在[[Special:Preferences|系统设置]]确认了电子邮件地址且未被禁止使用“{{int:emailuser}}”功能时,才能发送电子邮件联系管理员。\n\n您当前的IP地址为$3,该封禁ID为#$5。请在您做出的任何查询中包含所有上述详情。",
        "systemblockedtext": "您的用户名或IP地址已被MediaWiki自动封禁。封禁原因:\n\n:<em>$2</em>\n\n* 开始时间:$8\n* 到期时间:$6\n* 目标用户:$7\n\n您当前的IP地址是$3。请在您做出的任何查询中包含所有上述详情。",
        "blockednoreason": "未给出原因",
        "whitelistedittext": "请$1以编辑页面。",
        "protectedtitles-submit": "显示标题",
        "listusers": "用户列表",
        "listusers-editsonly": "只显示有编辑的用户",
+       "listusers-temporarygroupsonly": "只显示在临时用户组中的用户",
        "listusers-creationsort": "按创建日期排序",
        "listusers-desc": "降序排序",
        "usereditcount": "$1次编辑",
        "apisandbox-dynamic-parameters-add-label": "添加参数:",
        "apisandbox-dynamic-parameters-add-placeholder": "参数名称",
        "apisandbox-dynamic-error-exists": "已存在名为“$1”的参数。",
+       "apisandbox-templated-parameter-reason": "此[[Special:ApiHelp/main#main/templatedparams|模板参数]]已基于$2的{{PLURAL:$1|值}}提供。",
        "apisandbox-deprecated-parameters": "弃用参数",
        "apisandbox-fetch-token": "自动填充令牌",
        "apisandbox-add-multi": "添加",
        "whatlinkshere": "链入页面",
        "whatlinkshere-title": "链接至“$1”的页面",
        "whatlinkshere-page": "页面:",
-       "linkshere": "以下页面链接至<strong>[[:$1]]</strong>:",
-       "nolinkshere": "没有页面链接至'''[[:$1]]'''。",
-       "nolinkshere-ns": "在所选的名字空间内没有页面链接到'''[[:$1]]'''。",
+       "linkshere-2": "以下页面链接至<strong>$1</strong>:",
+       "nolinkshere-2": "没有页面链接至<strong>$1</strong>。",
+       "nolinkshere-ns-2": "在所选的名字空间内没有页面链接到<strong>$1</strong>。",
        "isredirect": "重定向页面",
        "istemplate": "嵌入",
        "isimage": "文件链接",
        "pagedata-title": "页面数据",
        "pagedata-text": "此页面提供相关页面的数据界面。请在URL中,使用子页面语法提供页面标题。\n* 内容协商基于您客户端的接受标头应用。这意味着页面数据将以您客户端首选的格式提供。",
        "pagedata-not-acceptable": "没有找到匹配的格式。支持的MIME类型:$1",
-       "pagedata-bad-title": "无效标题:$1。"
+       "pagedata-bad-title": "无效标题:$1。",
+       "unregistered-user-config": "由于安全原因,JavaScript、CSS和JSON用户子页面不能为非注册用户加载。",
+       "passwordpolicies": "密码方针",
+       "passwordpolicies-summary": "这里是对本wiki定义的用户组而言,起作用的密码方针列表。",
+       "passwordpolicies-group": "组",
+       "passwordpolicies-policies": "方针",
+       "passwordpolicies-policy-minimalpasswordlength": "密码长度必须至少$1个{{PLURAL:$1|字符}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "密码长度必须至少$1个{{PLURAL:$1|字符}}才能登陆",
+       "passwordpolicies-policy-passwordcannotmatchusername": "密码不能与用户名相同",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "密码不能匹配特定列入黑名单的密码",
+       "passwordpolicies-policy-maximalpasswordlength": "密码长度必须少于$1个{{PLURAL:$1|字符}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "密码不能{{PLURAL:$1|是最常见的密码|在$1个最常见密码的列表中}}"
 }
index 3a14a15..53498bf 100644 (file)
@@ -97,7 +97,9 @@
                        "和平至上",
                        "Sanmosa",
                        "Dongzn",
-                       "Shangkuanlc"
+                       "Shangkuanlc",
+                       "Kanashimi",
+                       "Hello903hello"
                ]
        },
        "tog-underline": "底線標示連結:",
        "tog-watchlisthideminor": "隱藏監視清單中的次要修訂",
        "tog-watchlisthideliu": "隱藏監視清單中已登入使用者的編輯",
        "tog-watchlistreloadautomatically": "查詢條件變更時自動重新讀取監視清單(需要使用 JavaScript)",
-       "tog-watchlistunwatchlinks": "添加監視列表條目的直接(取消)監視鏈接(需要JavaScript才能打開功能)",
+       "tog-watchlistunwatchlinks": "為帶有變更的監試頁面添加直接(取消)監視標記({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}),需要 JavaScript 來打開功能",
        "tog-watchlisthideanons": "隱藏監視清單中匿名使用者的編輯",
        "tog-watchlisthidepatrolled": "隱藏監視清單中已巡查的編輯",
        "tog-watchlisthidecategorization": "隱藏頁面分類",
        "cascadeprotected": "此頁面被保護無法編輯,因為此頁面被以下開啟 \"連鎖保護\" 選項的{{PLURAL:$1|一頁|數頁}}保護頁面引用:\n$2",
        "namespaceprotected": "您沒有權限編輯 <strong>$1</strong> 命名空間的頁面。",
        "customcssprotected": "您並沒有權限編輯此 CSS 頁面,因為此頁面包含了其他使用者的個人設定。",
-       "customjsonprotected": "您沒有權限編輯此 CSS 頁面,因為此頁面包含了其他使用者的個人設定。",
+       "customjsonprotected": "您沒有權限編輯此JSON頁面,因為此頁面包含了其他使用者的個人設定。",
        "customjsprotected": "您並沒有權限編輯此 JavaScript 頁面,因為此頁面包含了其他使用者的個人設定。",
        "mycustomcssprotected": "您沒有權限編輯此 CSS 頁面。",
        "mycustomjsonprotected": "您沒有權限編輯此 JSON 頁面。",
        "noemailprefs": "在您的偏好設定中設定電子郵件地址,讓您可以使用這些功能。",
        "emailconfirmlink": "確認您的電子郵件地址",
        "invalidemailaddress": "無法接受格式不正確的電子郵件地址,請輸入正確的電子郵件地址格式或略過填寫該欄位。",
-       "cannotchangeemail": "此 Wiki 禁止更改帳號的電子郵件地址。",
+       "cannotchangeemail": "此 wiki 無法變更帳號的電子郵件地址。",
        "emaildisabled": "此網站不能傳送電子郵件。",
        "accountcreated": "已建立帳號",
        "accountcreatedtext": "使用者帳號 [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|對話]]) 已建立。",
        "botpasswords-existing": "已存在機器人密碼",
        "botpasswords-createnew": "建立新機器人密碼",
        "botpasswords-editexisting": "編輯已存在的機器人密碼",
+       "botpasswords-label-needsreset": "(密碼需要重新設定)",
        "botpasswords-label-appid": "機器人名稱:",
        "botpasswords-label-create": "建立",
        "botpasswords-label-update": "更新",
        "botpasswords-restriction-failed": "機器人密碼限制已拒絕此次登入。",
        "botpasswords-invalid-name": "指定的使用者名稱未包含機器人密碼分隔字元 (\"$1\")。",
        "botpasswords-not-exist": "使用者 \"$1\" 並沒有名稱為 \"$2\" 的機器人密碼。",
+       "botpasswords-needs-reset": "給{{GENDER:$1|使用者}}「$1」的機器人名稱「$2」該機器人密碼已重新設定。",
        "resetpass_forbidden": "無法變更密碼",
        "resetpass_forbidden-reason": "無法變更密碼:$1",
        "resetpass-no-info": "您必須直接登入存取這個頁面。",
        "subject-preview": "預覽主旨:",
        "previewerrortext": "嘗試預覽您的變更時發生錯誤。",
        "blockedtitle": "使用者已被封鎖",
-       "blockedtext": "<strong>您的使用者名稱或 IP 位址已被封鎖。</strong>\n\n您被 $1 封鎖,\n原因爲 <em>$2</em>。\n\n* 封鎖開始時間:$8\n* 封鎖結束時間:$6\n* 相關封鎖對象:$7\n\n您可以聯絡 $1 或其他的 [[{{MediaWiki:Grouppage-sysop}}|管理員]] 討論封鎖的相關問題。\n若您已在 [[Special:Preferences|偏好設定]] 中設定了一個有效的電子郵件地址,且尚未被封鎖郵件功能,則您可透過 \"Email 聯絡此使用者\" 的功能來聯絡相關管理員。\n您目前的 IP 位址是 $3,此次封鎖的 ID 為 #$5。\n請您在詢問時附註以上詳細訊息。",
-       "autoblockedtext": "因先前的另一位使用者被 $1 封鎖,您的 IP 位址已被自動封鎖。\n原因是:\n\n:<em>$2</em>\n\n* 封鎖開始時間:$8\n* 封鎖結束時間:$6\n* 相關封鎖對象:$7\n\n您可以聯絡 $1 或其他的 [[{{MediaWiki:Grouppage-sysop}}|管理員]] 討論封鎖的相關問題。\n若您已在 [[Special:Preferences|偏好設定]] 中設定了一個有效的電子郵件地址,且尚未被封鎖郵件功能,則您可透過 \"Email 聯絡此使用者\" 的功能來聯絡相關管理員。\n您目前的 IP 位址是 $3,此次封鎖的 ID 為 #$5。\n請您在詢問時附註以上詳細資料。",
+       "blockedtext": "<strong>您的使用者名稱或 IP 位址已被封鎖。</strong>\n\n您被 $1 封鎖,\n原因爲 <em>$2</em>。\n\n* 封鎖開始時間:$8\n* 封鎖結束時間:$6\n* 相關封鎖對象:$7\n\n您可以聯絡 $1 或其他的 [[{{MediaWiki:Grouppage-sysop}}|管理員]] 討論封鎖的相關問題。\n若您已在 [[Special:Preferences|偏好設定]] 中設定了一個有效的電子郵件地址,且尚未被封鎖郵件功能,則您可透過 \"{{int:emailuser}}\" 的功能來聯絡相關管理員。\n您目前的 IP 位址是 $3,此次封鎖的 ID 為 #$5。\n請您在詢問時附註以上詳細訊息。",
+       "autoblockedtext": "因先前的另一位使用者被 $1 封鎖,您的 IP 位址已被自動封鎖。\n原因是:\n\n:<em>$2</em>\n\n* 封鎖開始時間:$8\n* 封鎖結束時間:$6\n* 相關封鎖對象:$7\n\n您可以聯絡 $1 或其他的 [[{{MediaWiki:Grouppage-sysop}}|管理員]] 討論封鎖的相關問題。\n若您已在 [[Special:Preferences|偏好設定]] 中設定了一個有效的電子郵件地址,且尚未被封鎖郵件功能,則您可透過 \"{{int:emailuser}}\" 的功能來聯絡相關管理員。\n您目前的 IP 位址是 $3,此次封鎖的 ID 為 #$5。\n請您在詢問時附註以上詳細資料。",
        "systemblockedtext": "您的使用者名稱或 IP 位址已被 MediaWiki 自動封鎖,原因如下:\n\n:<em>$2</em>\n\n* 封鎖開始時間:$8\n* 封鎖結束時間:$6\n* 被封鎖的使用者:$7\n\n您目前的 IP 位址為 $3。\n請在做詢問時附上以上資訊。",
        "blockednoreason": "未說明原因",
        "whitelistedittext": "請先 $1 才可編輯頁面。",
        "blocked-notice-logextract": "此使用者目前已被封鎖。\n以下為最近的封鎖紀錄以供參考:",
        "clearyourcache": "<strong>注意:</strong>在您儲存之後您必須清除瀏覽器快取才可看到最新的變更。\n* <strong>Firefox / Safari:</strong>按住 <em>Shift</em> 時點選 <em>重新整理</em>,或按 <em>Ctrl-F5</em> 或 <em>Ctrl-R</em> (Mac 則為 <em>⌘-R</em>) \n* <strong>Google Chrome:</strong>按 <em>Ctrl-Shift-R</em> (Mac 則為 <em>⌘-Shift-R</em>) \n* <strong>Internet Explorer:</strong>按住 <em>Ctrl</em> 時點選 <em>重新整理</em>,或按 <em>Ctrl-F5</em>\n* <strong>Opera:</strong>前往 <em>選單 → 設定</em> (在 Mac 為 <em>Opera → 偏好設定</em>) 然後再到 <em>隱私 & 安全性 → 清除瀏覽資料 → 已快取的圖片與檔案</em>。",
        "usercssyoucanpreview": "<strong>提示:</strong>在儲存之前使用 \"{{int:showpreview}}\" 按鈕來測試您的新 CSS 。",
+       "userjsonyoucanpreview": "<strong>提示:</strong>在儲存之前使用 \"{{int:showpreview}}\" 按鈕來測試您的新 JSON。",
        "userjsyoucanpreview": "<strong>提示:</strong>在儲存之前使用 \"{{int:showpreview}}\" 按鈕來測試您的新 JavaScript 。",
        "usercsspreview": "<strong>您目前正預覽您的使用者 CSS,CSS 還尚未儲存!</strong>",
+       "userjsonpreview": "<strong>請注意您僅是在測試/預覽您的使用者 JSON 設定,內容還尚未儲存!</strong>",
        "userjspreview": "<strong>您目前正預覽您的使用者 JavaScript,JavaScript 還尚未儲存!</strong>",
        "sitecsspreview": "<strong>您目前正預覽此 CSS,CSS 還尚未儲存!</strong>",
+       "sitejsonpreview": "<strong>請注意您僅是在預覽此 JSON 設定,內容還尚未儲存!</strong>",
        "sitejspreview": "<strong>您目前正預覽此 JavaScript,JavaScript 還尚未儲存!</strong>",
        "userinvalidconfigtitle": "<strong>警告:</strong> 無此外觀樣式 \"$1\"。\n自訂的 .css、.json 和 .js 頁面要使用小寫標題,例如:{{ns:user}}:Foo/vector.css 與 {{ns:user}}:Foo/Vector.css 是不同的。",
        "updated": "(已更新)",
        "longpageerror": "<strong>錯誤:您所送出的文字內容共有 {{PLURAL:$1|1 KB|$1 KB}},已超出系統上限 {{PLURAL:$2|1 KB|$2 KB}}。</strong>\n\n無法儲存。",
        "readonlywarning": "<strong>警告:資料庫已被鎖定以進行維護,因此無法儲存您目前所做的編輯動作。</strong>\n您可先複製您的文字並貼上到文字檔案中儲存,稍後再儲存您編輯。\n\n鎖定資料庫的系統管理員有以下說明:$1",
        "protectedpagewarning": "<strong>警告:本頁已經被保護,只有擁有管理員權限的使用者才可編輯。</strong>\n以下提供最近的日誌以便參考:",
-       "semiprotectedpagewarning": "<strong>注意:</strong>本頁已經被保護,只有已註冊的使用者才可編輯。\n以下提供最近的日誌以便參考:",
+       "semiprotectedpagewarning": "<strong>注意:</strong>本頁已經被保護,只有自動確認使用者才可編輯。\n以下提供最近的日誌以便參考:",
        "cascadeprotectedwarning": "<strong>警告:</strong>由於本頁被下列{{PLURAL:$1|頁面|頁面}}嵌入,所以受連鎖保護。只有得到[[Special:ListGroupRights|特殊權限]]的使用者才可編輯。",
        "titleprotectedwarning": "<strong>警告:本頁面已被保護,需要 [[Special:ListGroupRights|特殊權限]] 方可建立。</strong>\n以下提供最近的日誌以便參考:",
        "templatesused": "此頁面使用了以下{{PLURAL:$1|模板}}:",
        "expansion-depth-exceeded-category-desc": "超出展開深度限制的頁面。",
        "expansion-depth-exceeded-warning": "頁面超出展開深度限制",
        "parser-unstrip-loop-warning": "偵測到 Unstrip 迴圈",
-       "unstrip-depth-warning": "Unstrip 遞迴超出限制 ($1)",
+       "unstrip-depth-warning": "Unstrip 深度超出限制 ($1)",
+       "unstrip-depth-category": "超出 unstrip 深度限制的頁面",
+       "unstrip-size-warning": "Unstrip 大小超出限制 ($1)",
+       "unstrip-size-category": "超出 unstrip 大小限制的頁面",
        "converter-manual-rule-error": "手動語言轉換規則時偵測到錯誤",
        "undo-success": "此編輯可以被還原。\n請檢查以下比較表,確認您是否要還原,然後儲存以下變更以完成編輯還原。",
        "undo-failure": "由於編輯的修訂間有衝突,此編輯不能還原。",
        "difference-multipage": "(頁面間的差異)",
        "lineno": "行 $1:",
        "compareselectedversions": "比較已選擇的修訂",
-       "showhideselectedversions": "更改已選擇修訂的顯示設定",
-       "editundo": "撤銷",
+       "showhideselectedversions": "變更已選擇修訂的顯示設定",
+       "editundo": "復原",
        "diff-empty": "(無差異)",
        "diff-multi-sameuser": "(未顯示同一使用者於中間所作的 $1 次修訂)",
        "diff-multi-otherusers": "(未顯示由 $2 位使用者於中間所作的 $1 次修訂)",
        "prefs-watchlist-edits": "監視清單中顯示的變更數量上限:",
        "prefs-watchlist-edits-max": "數量上限:1000",
        "prefs-watchlist-token": "監視清單金鑰:",
+       "prefs-watchlist-managetokens": "管理令牌",
        "prefs-misc": "其他",
        "prefs-resetpass": "變更密碼",
        "prefs-changeemail": "變更或移除電子郵件地址",
        "stub-threshold-disabled": "已停用",
        "recentchangesdays": "近期變更顯示的天數:",
        "recentchangesdays-max": "最多 $1 {{PLURAL:$1|天}}",
-       "recentchangescount": "預設顯示的編輯數:",
+       "recentchangescount": "在最近變更、頁面歷史、以及日誌裡,所預設顯示的編輯數:",
        "prefs-help-recentchangescount": "數量上限:1000",
        "prefs-help-watchlist-token2": "這是您的監視清單的網路訊息源所需密鑰。\n任何人只要知道密鑰就能夠讀取您的監視清單,所以請勿任意與它人共享。\n若有需要[[Special:ResetTokens|您可重設密鑰]]。",
+       "prefs-help-tokenmanagement": "您可以查看並重新設定您帳號裡用來存取您監視清單中訊息來源的密鑰。任何知道該密鑰的人皆可讀取您的監視清單,因此請不要將它分享出去。",
        "savedprefs": "已儲存您的偏好設定。",
        "savedrights": "已儲存 {{GENDER:$1|$1}} 的使用者權限。",
        "timezonelegend": "時區:",
        "rcfilters-savedqueries-already-saved": "這些過濾已被儲存。變更您的設定,來建立新的已儲存過濾。",
        "rcfilters-restore-default-filters": "還原預設過濾條件",
        "rcfilters-clear-all-filters": "清除所有過濾條件",
-       "rcfilters-show-new-changes": "顯示最新更改",
+       "rcfilters-show-new-changes": "檢視最新變更",
        "rcfilters-search-placeholder": "過濾變更(使用選單或搜尋過濾名稱)",
        "rcfilters-invalid-filter": "無效的過濾條件",
        "rcfilters-empty-filter": "沒有使用中的過濾條件。已顯示所有的貢獻。",
        "rcfilters-filter-editsbyself-label": "您的編輯",
        "rcfilters-filter-editsbyself-description": "您的貢獻",
        "rcfilters-filter-editsbyother-label": "其他人的變更",
-       "rcfilters-filter-editsbyother-description": "除了您以外的所有更改",
+       "rcfilters-filter-editsbyother-description": "除了您以外的所有變更。",
        "rcfilters-filtergroup-userExpLevel": "使用者註冊及經驗",
        "rcfilters-filter-user-experience-level-registered-label": "已註冊",
        "rcfilters-filter-user-experience-level-registered-description": "已登入編輯者。",
        "rcfilters-filter-humans-label": "人工 (非機器人)",
        "rcfilters-filter-humans-description": "由人類編輯者做出的編輯",
        "rcfilters-filtergroup-reviewstatus": "審查狀態",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "未手動或自動標記成已巡查的編輯。",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "未巡查",
+       "rcfilters-filter-reviewstatus-manual-description": "被手動標示為已巡查的編輯。",
+       "rcfilters-filter-reviewstatus-manual-label": "手動巡查",
+       "rcfilters-filter-reviewstatus-auto-description": "由高階使用者做出的編輯會自動標記成已巡查。",
+       "rcfilters-filter-reviewstatus-auto-label": "自動巡查",
        "rcfilters-filtergroup-significance": "重要性",
        "rcfilters-filter-minor-label": "次要編輯",
        "rcfilters-filter-minor-description": "作者已標示為次要的編輯。",
        "rcfilters-filter-watchlist-watched-label": "在監視清單內",
        "rcfilters-filter-watchlist-watched-description": "您的監視清單內的變更",
        "rcfilters-filter-watchlist-watchednew-label": "新監視清單的變更",
-       "rcfilters-filter-watchlist-watchednew-description": "更改後您尚未檢視的監視頁面變更。",
+       "rcfilters-filter-watchlist-watchednew-description": "變更後您尚未檢視的監視頁面變更。",
        "rcfilters-filter-watchlist-notwatched-label": "不在監視清單內",
        "rcfilters-filter-watchlist-notwatched-description": "除了更改您的監視頁面以外的任何事項。",
        "rcfilters-filtergroup-watchlistactivity": "監視列表活動",
        "rcfilters-filter-watchlistactivity-unseen-label": "未讀變更",
-       "rcfilters-filter-watchlistactivity-unseen-description": "自從更改發生以來,對您沒有訪問的頁面做出的更改。",
+       "rcfilters-filter-watchlistactivity-unseen-description": "自從變更發生以來,對您沒有造訪的頁面做出的變更。",
        "rcfilters-filter-watchlistactivity-seen-label": "已讀變更",
-       "rcfilters-filter-watchlistactivity-seen-description": "自從更改發生以來,對您已訪問的頁面做出的更改。",
+       "rcfilters-filter-watchlistactivity-seen-description": "自從變更發生以來,對您已造訪的頁面做出的變更。",
        "rcfilters-filtergroup-changetype": "變更類型",
        "rcfilters-filter-pageedits-label": "頁面編輯",
        "rcfilters-filter-pageedits-description": "對 Wiki 內容、討論、分類說明所做的編輯…",
        "rcfilters-filter-lastrevision-label": "最新修訂版本",
        "rcfilters-filter-lastrevision-description": "只包括對頁面的近期變更。",
        "rcfilters-filter-previousrevision-label": "不是最新修訂版本",
-       "rcfilters-filter-previousrevision-description": "所有不是「最新修訂版本」的更改。",
+       "rcfilters-filter-previousrevision-description": "所有不是「最新修訂版本」的變更。",
        "rcfilters-filter-excluded": "已排除",
        "rcfilters-tag-prefix-namespace-inverted": "<strong>:不是</strong>$1",
        "rcfilters-exclude-button-off": "排除選項",
        "rcfilters-view-tags-help-icon-tooltip": "了解更多關於標記編輯的資訊",
        "rcfilters-liveupdates-button": "動態更新",
        "rcfilters-liveupdates-button-title-on": "關閉動態更新",
-       "rcfilters-liveupdates-button-title-off": "顯示有發生的新更改",
-       "rcfilters-watchlist-markseen-button": "標記所有更改為已查看",
+       "rcfilters-liveupdates-button-title-off": "顯示有發生的新變更",
+       "rcfilters-watchlist-markseen-button": "標記所有變更為已看過",
        "rcfilters-watchlist-edit-watchlist-button": "編輯您的監視頁面列表",
        "rcfilters-watchlist-showupdated": "自更改發生以來,對您尚未訪問的頁面做出的更改以<strong>粗體</strong>顯示,並帶有實心圓形標記。",
-       "rcfilters-preference-label": "隱藏改進的最近更改版本",
+       "rcfilters-preference-label": "隱藏改善的最近變更版本",
        "rcfilters-preference-help": "返回到2017年介面重新設計版,並重新新增這以後增加的工具。",
-       "rcfilters-filter-showlinkedfrom-label": "顯示連結自該頁面的頁面上的更改",
+       "rcfilters-filter-showlinkedfrom-label": "顯示連結自此頁面的頁面上的變更",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>連結自</strong>指定頁面的頁面",
        "rcfilters-filter-showlinkedto-label": "顯示連結到該頁面的頁面上的更改",
        "rcfilters-filter-showlinkedto-option-label": "<strong>連結到</strong>指定頁面的頁面",
        "recentchangeslinked-feed": "相關變更",
        "recentchangeslinked-toolbox": "相關變更",
        "recentchangeslinked-title": "與 \"$1\" 相關的變更",
-       "recentchangeslinked-summary": "輸入頁面名稱,來查看頁面所連入或連出頁面的變更。(要查看分類成員的話,請輸入 Category:分類名稱)。會對在[[Special:Watchlist|您的監視清單]]上頁面更改為<strong>粗體</strong>顯示。",
+       "recentchangeslinked-summary": "輸入頁面名稱,來查看頁面所連入或連出頁面的變更。(要查看分類成員的話,請輸入{{ns:category}}:分類名稱)。會對在[[Special:Watchlist|您的監視清單]]上頁面更改為<strong>粗體</strong>顯示。",
        "recentchangeslinked-page": "頁面名稱:",
-       "recentchangeslinked-to": "顯示連結至指定頁面的變更",
+       "recentchangeslinked-to": "顯示連結至指定頁面的變更",
        "recentchanges-page-added-to-category": "[[:$1]] 已加入至分類",
        "recentchanges-page-added-to-category-bundled": "[[:$1]] 已加入至分類,[[Special:WhatLinksHere/$1|此頁面已被其他頁面引用]]",
        "recentchanges-page-removed-from-category": "[[:$1]] 已自分類移除",
        "deadendpages": "無連結頁面",
        "deadendpagestext": "以下在 {{SITENAME}} 中的頁面未連結到其他頁面。",
        "protectedpages": "受保護頁面",
+       "protectedpages-filters": "篩選:",
        "protectedpages-indef": "只顯示無限期的保護頁面",
        "protectedpages-summary": "此頁面列出目前受保護的頁面。 欲查詢受保護標題清單,請參考 [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]]。",
        "protectedpages-cascade": "只顯示連鎖的保護頁面",
        "protectedtitles-submit": "顯示標題",
        "listusers": "使用者清單",
        "listusers-editsonly": "只顯示有編輯的使用者",
+       "listusers-temporarygroupsonly": "僅顯示在臨時使用者群組的使用者",
        "listusers-creationsort": "依建立日期排序",
        "listusers-desc": "使用降冪排序",
        "usereditcount": "$1 次{{PLURAL:$1|編輯}}",
        "apisandbox-dynamic-parameters-add-label": "加入參數:",
        "apisandbox-dynamic-parameters-add-placeholder": "參數名稱",
        "apisandbox-dynamic-error-exists": "命名的參數 \"$1\" 已經存在。",
+       "apisandbox-templated-parameter-reason": "此[[Special:ApiHelp/main#main/templatedparams|模板參數]]基於 $2 裡的{{PLURAL:$1|值|值}}來提供。",
        "apisandbox-deprecated-parameters": "停用的參數",
        "apisandbox-fetch-token": "自動填寫密鑰",
        "apisandbox-add-multi": "新增",
        "unprotectedarticle": "已解除 \"[[$1]]\" 的保護",
        "movedarticleprotection": "已移動 \"[[$2]]\" 的保護設定至 \"[[$1]]\"",
        "protectedarticle-comment": "{{GENDER:$2|受保護}} \"[[$1]]\"",
-       "modifiedarticleprotection-comment": "{{GENDER:$2|已更改}} \"[[$1]]\" 的保護層級",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|已變更}} \"[[$1]]\" 的保護層級",
        "unprotectedarticle-comment": "{{GENDER:$2|已移除}} \"[[$1]]\" 的保護",
        "protect-title": "變更 \"$1\" 的保護層級",
        "protect-title-notallowed": "檢視 \"$1\" 的保護層級",
        "whatlinkshere": "連結至此的頁面",
        "whatlinkshere-title": "連結至「$1」的頁面",
        "whatlinkshere-page": "頁面:",
-       "linkshere": "以下頁面連結至 <strong>[[:$1]]</strong>:",
-       "nolinkshere": "沒有頁面連結至 <strong>[[:$1]]</strong>。",
-       "nolinkshere-ns": "已選擇的命名空間中沒有頁面連結到 [[:$1]]。",
+       "linkshere-2": "以下頁面連結至 <strong>$1</strong>:",
+       "nolinkshere-2": "沒有頁面連結至 <strong>$1</strong>。",
+       "nolinkshere-ns-2": "已選擇的命名空間中沒有頁面連結到 $1。",
        "isredirect": "重新導向頁面",
        "istemplate": "引用",
        "isimage": "檔案連結",
        "blocklog-showlog": "此使用者先前被封鎖過。\n以下為封鎖紀錄以供參考:",
        "blocklog-showsuppresslog": "此使用者先前被封鎖並且隱藏過。\n以下為禁止顯示紀錄以供參考:",
        "blocklogentry": "已封鎖 [[$1]] 的期限至 $2 $3",
-       "reblock-logentry": "更改 [[$1]] 的封鎖期限至 $2 $3",
+       "reblock-logentry": "變更 [[$1]] 的封鎖設定,到期時間為 $2 $3",
        "blocklogtext": "此為使用者的封鎖及取消封鎖動作的記錄。\n未列出自動封鎖的 IP 位址。\n請參考 [[Special:BlockList|封鎖清單]] 中的目前正在作業的阻止與封鎖。",
        "unblocklogentry": "已解除封鎖 $1",
        "block-log-flags-anononly": "僅限匿名使用者",
        "ipb_expiry_temp": "隱藏使用者名稱的封鎖不可設定期限。",
        "ipb_hide_invalid": "無法禁止顯示此帳號;它擁有超過 $1 次的編輯。",
        "ipb_already_blocked": "已經封鎖 \"$1\"。",
-       "ipb-needreblock": "$1 已經被封鎖。您是否想更改設定?",
+       "ipb-needreblock": "$1 已經被封鎖。您是否想變更設定?",
        "ipb-otherblocks-header": "其他{{PLURAL:$1|封鎖}}",
        "unblock-hideuser": "由於此使用者名稱已被設為隱藏,您無法解除封鎖這個使用者。",
        "ipb_cant_unblock": "錯誤:查無封鎖 ID $1,可能已被解除封鎖。",
        "fix-double-redirects": "更新所有指向原標題的重新導向頁面",
        "move-leave-redirect": "留下重新導向頁面",
        "protectedpagemovewarning": "<strong>警告:</strong>本頁已經被保護,只有擁有管理員權限的使用者才可移動。\n以下提供最近的日誌以便參考:",
-       "semiprotectedpagemovewarning": "<strong>注意:</strong>本頁已經被保護,只有已註冊的使用者才可移動。\n以下提供最近的日誌以便參考:",
+       "semiprotectedpagemovewarning": "<strong>注意:</strong>本頁已經被保護,只有自動確認使用者才可移動。\n以下提供最近的日誌以便參考:",
        "move-over-sharedrepo": "[[:$1]] 已存在於共用檔案庫,將檔案移動到此標題會覆蓋該共用檔案。",
        "file-exists-sharedrepo": "選擇的檔案名稱於共用檔案庫已有其他檔案使用。\n請改選擇其他名稱。",
        "export": "匯出頁面",
        "group-bot.css": "/* 此 CSS 會影響機器人 */",
        "group-sysop.css": "/* 這裡的 CSS 會影響管理員 */",
        "group-bureaucrat.css": "/* 此 CSS 會影響行政員 */",
+       "common.json": "/* 在此的任一 JavaScript 會為全部使用者在所有頁面裡載入。 */",
        "common.js": "/* 此 JavaScript 會用於使用者載入的每一個頁面。 */",
        "group-sysop.js": "/* 這裡的 JavaScript 會影響管理員 */",
        "anonymous": "{{SITENAME}} 的匿名{{PLURAL:$1|使用者}}",
        "tag-mw-new-redirect-description": "建立新重新導向或更改頁面為重新導向的編輯",
        "tag-mw-removed-redirect": "移除重新導向",
        "tag-mw-removed-redirect-description": "將現有重新導向更改為非重新導向的編輯",
-       "tag-mw-changed-redirect-target": "重新導向目標更改",
-       "tag-mw-changed-redirect-target-description": "更改重新導向目標的編輯",
+       "tag-mw-changed-redirect-target": "重新導向目標變更",
+       "tag-mw-changed-redirect-target-description": "變更重新導向目標的編輯",
        "tag-mw-blank": "清空",
        "tag-mw-blank-description": "清空頁面的編輯",
        "tag-mw-replace": "替換",
        "tag-mw-replace-description": "移除超過90%頁面內容的編輯",
        "tag-mw-rollback": "回退",
        "tag-mw-rollback-description": "使用回退連結回退上一編輯的編輯",
-       "tag-mw-undo": "撤銷",
+       "tag-mw-undo": "復原",
        "tag-mw-undo-description": "使用撤銷連結來撤銷上一筆編輯的編輯數",
        "tags-title": "標籤",
        "tags-intro": "此頁面列出所有可用來標示編輯內容的標籤以及這些標籤所代表的意思。",
        "logentry-delete-event": "$1 {{GENDER:$2|已更改}} $3 中 {{PLURAL:$5|1 筆日誌|$5 筆日誌}}的可見性:$4",
        "logentry-delete-revision": "$1 {{GENDER:$2|已更改}}頁面 $3 中 {{PLURAL:$5|1 筆修訂|$5 筆修訂}}的可見性:$4",
        "logentry-delete-event-legacy": "$1 {{GENDER:$2|已變更}} $3 中日誌的可見性",
-       "logentry-delete-revision-legacy": "$1 {{GENDER:$2|已更改}}頁面 $3 中修訂的可見性",
+       "logentry-delete-revision-legacy": "$1 {{GENDER:$2|已變更}}頁面 $3 中修訂的可見性",
        "logentry-suppress-delete": "$1 {{GENDER:$2|已禁止顯示}}頁面 $3",
        "logentry-suppress-event": "$1 {{GENDER:$2|已暗中更改}} $3 中 {{PLURAL:$5|1 筆日誌|$5 筆日誌}}的可見性:$4",
        "logentry-suppress-revision": "$1 {{GENDER:$2|已暗中更改}}頁面 $3 中 {{PLURAL:$5|1 筆修訂|$5 筆修訂}}的可見性:$4",
        "logentry-protect-unprotect": "$1 {{GENDER:$2|已移除}} $3 的保護",
        "logentry-protect-protect": "$1 {{GENDER:$2|已保護}} $3 $4",
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|已保護}} $3 $4 [連鎖]",
-       "logentry-protect-modify": "$1 {{GENDER:$2|已更改}} $3 的保護層級 $4",
-       "logentry-protect-modify-cascade": "$1 {{GENDER:$2|已更改}} $3 的保護層級 $4 [連鎖]",
+       "logentry-protect-modify": "$1 {{GENDER:$2|已變更}} $3 的保護層級 $4",
+       "logentry-protect-modify-cascade": "$1 {{GENDER:$2|已變更}} $3 的保護層級 $4 [連鎖]",
        "logentry-rights-rights": "$1已將{{GENDER:$6|$3}}的使用者群組從$4{{GENDER:$2|更改}}至$5",
-       "logentry-rights-rights-legacy": "$1 {{GENDER:$2|已更改}} $3 的群組成員資格",
+       "logentry-rights-rights-legacy": "$1 {{GENDER:$2|已變更}} $3 的群組成員資格",
        "logentry-rights-autopromote": "$1 已自動{{GENDER:$2|提升}}從 $4 成為 $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|已上傳}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|上傳了}}新版本的 $3",
        "duration-centuries": "$1世紀",
        "duration-millennia": "$1千年",
        "rotate-comment": "已順時針旋轉圖片 $1 {{PLURAL:$1|度|度}}",
-       "limitreport-title": "析器分析資料:",
+       "limitreport-title": "析器分析資料:",
        "limitreport-cputime": "CPU 使用時間",
        "limitreport-cputime-value": "$1 秒",
        "limitreport-walltime": "實際使用時間",
        "limitreport-templateargumentsize": "模板參數大小",
        "limitreport-templateargumentsize-value": "$1/$2 個{{PLURAL:$2|位元組}}",
        "limitreport-expansiondepth": "最高展開深度",
-       "limitreport-expensivefunctioncount": "高消耗解析器函數次數",
+       "limitreport-expensivefunctioncount": "高度耗費剖析器函數次數",
+       "limitreport-unstrip-depth": "Unstrip 迴圈深度",
        "limitreport-unstrip-depth-value": "$1/$2",
+       "limitreport-unstrip-size": "Unstrip 傳遞擴充大小",
        "limitreport-unstrip-size-value": "$1/$2{{PLURAL:$2|位元組}}",
        "expandtemplates": "展開模板",
        "expand_templates_intro": "本特殊頁面會將 wiki 文字中的模板展開,可以包含支援的解析器語法,如 <code><nowiki>{{</nowiki>#language:…}}</code> 與變數如 <code><nowiki>{{</nowiki>CURRENTDAY}}</code>。\n實際上,絕大部分在雙括號中的內容都會被展開。",
        "pagelang-nonexistent-page": "頁面 $1 不存在。",
        "pagelang-unchanged-language": "頁面 $1 的語言已經設為 $2。",
        "pagelang-unchanged-language-default": "頁面 $1 的語言已經設為 wiki 的預設內容語言。",
-       "pagelang-db-failed": "資料庫更改頁面語言失敗。",
+       "pagelang-db-failed": "資料庫變更頁面語言失敗。",
        "right-pagelang": "變更頁面語言",
        "action-pagelang": "變更頁面語言",
        "log-name-pagelang": "語言變更日誌",
        "log-description-pagelang": "此頁為頁面語言的變更日誌。",
-       "logentry-pagelang-pagelang": "$1 {{GENDER:$2|已更改}}頁面 $3 的語言從 $4 到 $5",
+       "logentry-pagelang-pagelang": "$1 已將 $3 的語言從 $4 {{GENDER:$2|變更}}至 $5",
        "default-skin-not-found": "哎呀!您於 <code dir=\"ltr\">$wgDefaultSkin</code> 設定的 Wiki 預設外觀 <code>$1</code> 無法使用。\n\n您的安裝程序應包含以下{{PLURAL:$4|外觀}}。請參考 [https://www.mediawiki.org/wiki/Manual:Skin_configuration 操作手冊:外觀設定] 以取得如何{{PLURAL:$4|開啟外觀並設為預設值}}的資訊。\n\n$2\n\n; 若您才剛安裝完 MediaWiki:\n: 您大概是使用 git 或直接透過原始碼使用其他方法安裝,這種情況是正常的。請嘗試安裝 [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org 的外觀目錄] 中的部份外觀使用以下方式:\n:* 下載 [https://www.mediawiki.org/wiki/Special:MyLanguage/Download tarball 安裝程式],該程式包含數個外觀與擴充套件。您可以複製並貼上至 <code>skins/</code> 目錄。\n:* 自 [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org] 下載個別外觀 tarball。\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins 使用 Git 下載外觀]。\n: 若您是 MediaWiki 的開發人員,這麼做應該不會影響到您的 git 儲存庫。\n\n; 若您才剛升級 MediaWiki:\n: MediaWiki 1.24 與較新的版本不再自動開啟已安裝的外觀 (請參考 [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery 操作手冊:外觀自動搜尋])。您可以將下列{{PLURAL:$5|行}}貼上至 <code>LocalSettings.php</code> 來開啟{{PLURAL:$5|所有}}目前已經安裝的{{PLURAL:$5|外觀}}:\n\n<pre dir=\"ltr\">$3</pre>\n\n; 若您才剛修改 <code>LocalSettings.php</code>:\n: 請再次確認您輸入的外觀名稱是否有誤。",
        "default-skin-not-found-no-skins": "哎呀!您於 <code>$wgDefaultSkin</code> 設定的 Wiki 預設外觀 <code>$1</code> 無法使用。\n\n您未安裝任何的外觀。\n\n; 若您才剛安裝完或升級完 MediaWiki:\n: 您大概是使用 git 或直接透過原始碼使用其他方法安裝,這種情況是正常的。 MediaWiki 1.24 或較新的版本在主要儲存庫中不再包含任何的外觀。 請嘗試安裝 [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org 的外觀目錄] 中的部份外觀使用以下方式:\n:* 下載 [https://www.mediawiki.org/wiki/Special:MyLanguage/Download tarball 安裝程式],該程式包含數個外觀與擴充套件。 您可以複製並貼上至 <code>skins/</code> 目錄。\n:* 自 [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org] 下載個別外觀 tarball。\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins 使用 Git 下載外觀]。\n: 若您是 MediaWiki 的開發人員,這麼做應該不會影響到您的 git 儲存庫。 請參考 [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Skin_configuration 操作手冊:外觀設定] 以取得如何開啟外觀並設為預設值的資訊。",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (已開啟)",
        "authmanager-authplugin-setpass-failed-title": "密碼變更失敗",
        "authmanager-authplugin-setpass-failed-message": "認証外掛已拒絕密碼變更。",
        "authmanager-authplugin-create-fail": "認証外掛已拒絕帳號建立。",
-       "authmanager-authplugin-setpass-denied": "認証外掛不允許更改密碼。",
+       "authmanager-authplugin-setpass-denied": "驗證外掛程式不允許變更密碼。",
        "authmanager-authplugin-setpass-bad-domain": "無效網域。",
        "authmanager-autocreate-noperm": "不允許自動帳號建立。",
        "authmanager-autocreate-exception": "自動帳號建立因發生錯誤臨時關閉。",
        "unlinkaccounts-success": "已取消連結帳號。",
        "authenticationdatachange-ignored": "認證資料變更未被處理,可能未設定提供者?",
        "userjsispublic": "請注意:JavaScript 子頁面可被其他使用者檢視,不應包含機密資料。",
+       "userjsonispublic": "請注意:JSON 子頁面可被其它使用者檢視,因此不應包含機密資料。",
        "usercssispublic": "請注意:CSS 子頁面可被其他使用者檢視,不應包含機密資料。",
        "restrictionsfield-badip": "無效的 IP 位址或範圍:$1",
        "restrictionsfield-label": "允許的 IP 範圍:",
        "pagedata-title": "頁面資料",
        "pagedata-text": "此頁面提供了至頁面的資料介面。請使用子頁面語法在 URL 裡提供頁面標題。\n* 內容協商會基於您客戶端接受標頭來套用,這代表頁面資料會以由您客戶端所首選格式來提供。",
        "pagedata-not-acceptable": "查無符合的格式,支援的 MIME 類型有:$1",
-       "pagedata-bad-title": "無效的標題:$1。"
+       "pagedata-bad-title": "無效的標題:$1。",
+       "unregistered-user-config": "基於安全緣故未註冊的使用者不會載入 JavaScript、CSS,以及 JSON 使用者子頁面。",
+       "passwordpolicies": "密碼方針",
+       "passwordpolicies-summary": "這是定義在此 wiki 上可用於使用者群組的有效密碼方針清單。",
+       "passwordpolicies-group": "群組",
+       "passwordpolicies-policies": "方針",
+       "passwordpolicies-policy-minimalpasswordlength": "密碼必須至少 $1 個{{PLURAL:$1|字元|字元}}長度",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "密碼必須至少 $1 個{{PLURAL:$1|字元|字元}}長度以用於登入",
+       "passwordpolicies-policy-passwordcannotmatchusername": "密碼不可以和使用者名稱相同",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "密碼不可以同於被列入黑名單的特定密碼",
+       "passwordpolicies-policy-maximalpasswordlength": "密碼必須小於 $1 個{{PLURAL:$1|字元|字元}}長度",
+       "passwordpolicies-policy-passwordcannotbepopular": "密碼不可以是{{PLURAL:$1|常用密碼內容|在清單中的編號 $1 常用密碼}}"
 }
index f16aab4..131172a 100644 (file)
@@ -71,7 +71,7 @@
        "rev-deleted-comment": "(註釋已除)",
        "rev-deleted-event": "(日誌已除)",
        "revdelete-suppress-text": "壓制'''只'''應用於以下的情況:\n* 不合適的個人資料\n*: ''地址、電話號碼、身份證號碼等。''",
-       "editundo": "撤銷",
+       "editundo": "復原",
        "prefs-user-pages": "用戶頁面",
        "username": "{{GENDER:$1|用戶名稱}}:",
        "prefs-help-gender": "可選:用於軟件中的性別指定。此項資料將會被公開。",
index 16a12de..7a7370f 100644 (file)
@@ -468,6 +468,7 @@ $specialPageAliases = [
        'PagesWithProp'             => [ 'PagesWithProp', 'Pageswithprop', 'PagesByProp', 'Pagesbyprop' ],
        'PageData'                  => [ 'PageData' ],
        'PageLanguage'              => [ 'PageLanguage' ],
+       'PasswordPolicies'          => [ 'PasswordPolicies' ],
        'PasswordReset'             => [ 'PasswordReset' ],
        'PermanentLink'             => [ 'PermanentLink', 'PermaLink' ],
        'Preferences'               => [ 'Preferences' ],
index eed5e7f..e0676a6 100644 (file)
@@ -42,7 +42,10 @@ $specialPageAliases = [
        'Allmessages'               => [ 'TodosLosMensajes', 'Todos_los_mensajes' ],
        'AllMyUploads'              => [ 'TodasMisSubidas', 'Todas_mis_subidas', 'TodosMisArchivos', 'Todos_mis_archivos' ],
        'Allpages'                  => [ 'Todas', 'Todas_las_páginas' ],
+       'ApiHelp'                   => [ 'AyudaAPI', 'Ayuda_de_la_API' ],
+       'ApiSandbox'                => [ 'Zona_de_pruebas_de_la_API' ],
        'Ancientpages'              => [ 'PáginasAntiguas', 'Páginas_antiguas' ],
+       'Autoblocklist'             => [ 'Lista_de_bloqueos_automáticos' ],
        'Badtitle'                  => [ 'Título_incorrecto' ],
        'Blankpage'                 => [ 'PáginaEnBlanco', 'Blanquear_página', 'BlanquearPágina', 'Página_en_blanco' ],
        'Block'                     => [ 'Bloquear' ],
@@ -97,6 +100,7 @@ $specialPageAliases = [
        'Myuploads'                 => [ 'MisArchivosSubidos', 'Mis_archivos_subidos' ],
        'Newimages'                 => [ 'NuevasImágenes', 'Nuevas_imágenes' ],
        'Newpages'                  => [ 'PáginasNuevas', 'Páginas_nuevas' ],
+       'PasswordPolicies'          => [ 'Política_de_contraseñas' ],
        'PasswordReset'             => [ 'RestablecerContraseña', 'Restablecer_contraseña' ],
        'PermanentLink'             => [ 'EnlacePermanente', 'Enlace_permanente' ],
        'Preferences'               => [ 'Preferencias' ],
index 16d1f7e..eccb66b 100644 (file)
@@ -28,3 +28,116 @@ $namespaceNames = [
        NS_CATEGORY         => "Dalala",
        NS_CATEGORY_TALK    => "Lo'iya_dalala",
 ];
+
+$specialPageAliases = [
+       'Activeusers'               => [ 'TaOhu\'uwoAktif' ],
+       'Allmessages'               => [ 'Nga\'amilaTahuli' ],
+       'AllMyUploads'              => [ 'Nga\'amilaDiletohu\'u', 'Nga\'amilaBerkasi\'u' ],
+       'Allpages'                  => [ 'Nga\'amilaHalaman' ],
+       'ApiHelp'                   => [ 'ApiWubodu' ],
+       'ApiSandbox'                => [ 'ApiBakiLoHungayo' ],
+       'Ancientpages'              => [ 'HalamanMulolo' ],
+       'AutoblockList'             => [ 'AutoblockDaputari', 'DaputariAutoblocks' ],
+       'Badtitle'                  => [ 'JudulMoleto' ],
+       'Blankpage'                 => [ 'HalamanKosongi' ],
+       'Block'                     => [ 'BlockTaOhu\'uwo' ],
+       'Booksources'               => [ 'BukuBungo' ],
+       'BotPasswords'              => [ 'BotTaheU\'unti' ],
+       'BrokenRedirects'           => [ 'BrokenLopobale' ],
+       'Categories'                => [ 'Dalala' ],
+       'ChangeContentModel'        => [ 'Boli\'aTuangoModel' ],
+       'ChangeCredentials'         => [ 'Boli\'aKredensial' ],
+       'ChangeEmail'               => [ 'Boli\'aEmail' ],
+       'ChangePassword'            => [ 'Boli\'aPassword', 'Tulo\'iPass', 'Tulo\'iPassword' ],
+       'ComparePages'              => [ 'PopotadengaHlaman' ],
+       'Confirmemail'              => [ 'KomfirmEmail' ],
+       'Contributions'             => [ 'Kontributor', 'Kontrib' ],
+       'CreateAccount'             => [ 'MohutuAkun' ],
+       'Deadendpages'              => [ 'HalamanBuntu' ],
+       'DeletedContributions'      => [ 'LulutaKontribusi' ],
+       'DoubleRedirects'           => [ 'DubuluRedirects' ],
+       'EditTags'                  => [ 'Boli\'aTags' ],
+       'EditWatchlist'             => [ 'Boli\'aHeAwasiyalo' ],
+       'Emailuser'                 => [ 'EmailTaOhu\'uwo', 'Email' ],
+       'ExpandTemplates'           => [ 'DuhengiTemplates' ],
+       'Export'                    => [ 'Ekspor' ],
+       'Fewestrevisions'           => [ 'RevisiNgo\'idi' ],
+       'FileDuplicateSearch'       => [ 'LoloheBerkasDubulu' ],
+       'GoToInterwiki'             => [ 'NtaliOdeInterwiki' ],
+       'Invalidateemail'           => [ 'TilalaTanggalEmail' ],
+       'BlockList'                 => [ 'BlockDaputari', 'DaputariBlocks', 'IPBlockDputari' ],
+       'LinkSearch'                => [ 'LoloheWumbuta' ],
+       'LinkAccounts'              => [ 'WumbutaAkun' ],
+       'Listadmins'                => [ 'DaputariAdmins' ],
+       'Listbots'                  => [ 'DaputariBots' ],
+       'Listfiles'                 => [ 'DaputariBerkas', 'BerkasDaputari', 'DaputariGambari' ],
+       'Listgrouprights'           => [ 'DaputariGroupRights', 'TaOhu\'uwoGroupRights' ],
+       'Listgrants'                => [ 'DaputariGrants' ],
+       'Listredirects'             => [ 'DaputariLopobale' ],
+       'ListDuplicatedFiles'       => [ 'DaputariBerkasDubulu', 'DaputariBerkasDubulu' ],
+       'Listusers'                 => [ 'DaputariTaOhu\'uwo', 'TaOhu\'uwoDaputari' ],
+       'Lonelypages'               => [ 'HalamanTutuwawu', 'OrphanedHalaman' ],
+       'Longpages'                 => [ 'HalamanHayahaya\'o' ],
+       'MediaStatistics'           => [ 'MediaStatistik' ],
+       'MIMEsearch'                => [ 'MIMELolohe' ],
+       'Mostcategories'            => [ 'DalalaUda\'a' ],
+       'Mostimages'                => [ 'WumbutaBerkasUda\'a', 'BerkasUda\'a', 'GambariUdara' ],
+       'Mostinterwikis'            => [ 'InterwikiUda\'a' ],
+       'Mostlinked'                => [ 'HalamanWumbutaUda\'a', 'WumbutaUda\'a' ],
+       'Mostlinkedcategories'      => [ 'WumbutaDalalaUda\'a', 'DalalaUda\'aPilomake' ],
+       'Mostlinkedtemplates'       => [ 'HalamanTranscludedUda\'a', 'WumbutaUda\'aTemplate', 'TemplateUda\'aPilomake' ],
+       'Mostrevisions'             => [ 'Boli\'oUda\'a' ],
+       'Movepage'                  => [ 'MoheyiHalaman' ],
+       'Mycontributions'           => [ 'Kontribusi\'u' ],
+       'MyLanguage'                => [ 'Bahasa\'u' ],
+       'Mypage'                    => [ 'Halamani\'u' ],
+       'Mytalk'                    => [ 'Lo\'iya\'u' ],
+       'Myuploads'                 => [ 'Diletohu\'u', 'Berkasi\'u' ],
+       'Newimages'                 => [ 'BerkasBohu', 'GambariBaohu' ],
+       'Newpages'                  => [ 'HalamanBohu' ],
+       'PagesWithProp'             => [ 'PagesWithProp', 'Pageswithprop', 'PagesByProp', 'Pagesbyprop' ],
+       'PageData'                  => [ 'DataHalaman' ],
+       'PageLanguage'              => [ 'BahasaHalaman' ],
+       'PasswordReset'             => [ 'ResetTaheU\'unti' ],
+       'PermanentLink'             => [ 'WumbutaKakali', 'WumbKakali' ],
+       'Preferences'               => [ 'Preperensi' ],
+       'Prefixindex'               => [ 'PrefixIndeks' ],
+       'Protectedpages'            => [ 'HalamanOdudaha' ],
+       'Protectedtitles'           => [ 'JudulOdudaha' ],
+       'Randompage'                => [ 'Totonula', 'HalamanTotonula' ],
+       'RandomInCategory'          => [ 'TotonulaLoDalala' ],
+       'Randomredirect'            => [ 'TotonulaMopobale' ],
+       'Randomrootpage'            => [ 'TotonulaRootpage' ],
+       'Recentchanges'             => [ 'BoheliLoboli\'aMola' ],
+       'Recentchangeslinked'       => [ 'WumbutaBoheliLoboli\'aMola', 'RelatedLoboli\'a' ],
+       'Redirect'                  => [ 'Mopobale' ],
+       'RemoveCredentials'         => [ 'YinggilaKredensial' ],
+       'Revisiondelete'            => [ 'MolulutoRevisi' ],
+       'Search'                    => [ 'Lolohe' ],
+       'Shortpages'                => [ 'HalamanLimbu\'o' ],
+       'Specialpages'              => [ 'HalamanSpesial' ],
+       'Statistics'                => [ 'Statistik', 'Stat' ],
+       'TrackingCategories'        => [ 'TrackingDalala' ],
+       'Uncategorizedcategories'   => [ 'DalalaJaOdalala' ],
+       'Uncategorizedimages'       => [ 'BerkasJaOdalala', 'GambariJaOdalala' ],
+       'Uncategorizedpages'        => [ 'HalamanJaOdalala' ],
+       'Uncategorizedtemplates'    => [ 'TemplateJaOdalala' ],
+       'Undelete'                  => [ 'BataliMoluluto' ],
+       'UnlinkAccounts'            => [ 'BataliyaWumbutaLoAkun' ],
+       'Unusedcategories'          => [ 'DalalaJaPilomake' ],
+       'Unusedimages'              => [ 'BerkasJaPilomake', 'GambariJaPilomake' ],
+       'Unusedtemplates'           => [ 'TemplateJaPilomake' ],
+       'Unwatchedpages'            => [ 'HalamanJaOdudaha' ],
+       'Upload'                    => [ 'Detohe' ],
+       'UploadStash'               => [ 'DetoheStash' ],
+       'Userlogin'                 => [ 'TumuwotoTaOhu\'uwo', 'Tumuwoto' ],
+       'Userlogout'                => [ 'LumuwaloTaOhu\'uwo', 'Lumuwalo' ],
+       'Version'                   => [ 'Versi' ],
+       'Wantedcategories'          => [ 'DalalaOtohilawo' ],
+       'Wantedfiles'               => [ 'BerkasOtohilawo' ],
+       'Wantedpages'               => [ 'HalamanOtohilawo', 'WumbutaLorusa' ],
+       'Wantedtemplates'           => [ 'TemplateOtohilawo' ],
+       'Watchlist'                 => [ 'DaputariHe\'awasiyalo' ],
+       'Whatlinkshere'             => [ 'WoloWumbutaTeye' ],
+       'Withoutinterwiki'          => [ 'Diya\'aInterwiki' ]
+];
index 4c75a51..94aac60 100644 (file)
@@ -29,7 +29,7 @@
 
 /**
  * @copyright Copyright © 2006, Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  */
 
 $linkTrail = '/^([a-zA-ZĀāČčĒēĢģĪīĶķĻļŅņŠšŪūŽž]+)(.*)$/sDu';
index 7572c67..816cff0 100644 (file)
@@ -35,8 +35,8 @@
  */
 
 /**
- * @license http://www.gnu.org/copyleft/fdl.html GNU Free Documentation License
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ * @license GFDL-1.3-or-later
+ * @license GPL-2.0-or-later
  *
  * @see https://meta.wikimedia.org/w/index.php?title=LanguageNn.php&action=history
  * @see https://nn.wikipedia.org/w/index.php?title=Brukar:Dittaeva/LanguageNn.php&action=history
diff --git a/languages/messages/MessagesShy_latn.php b/languages/messages/MessagesShy_latn.php
new file mode 100644 (file)
index 0000000..6cc4400
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+/** Shawiya (Latin script) (Tachawit)
+ *
+ * To improve a translation please visit https://translatewiki.net
+ *
+ * @ingroup Language
+ * @file
+ *
+ */
index 18eb9fa..e607992 100644 (file)
@@ -11,6 +11,8 @@
  * @author Reedy
  */
 
+$fallback = 'pt';
+
 $namespaceNames = [
        NS_MEDIA            => 'Media',
        NS_SPECIAL          => 'Espesiál',
index 409afb5..9bab37c 100644 (file)
@@ -28,7 +28,7 @@ require_once __DIR__ . '/Maintenance.php';
  *
  * @since 1.28
  */
-class AddRFCAndPMIDInterwiki extends LoggedUpdateMaintenance {
+class AddRFCandPMIDInterwiki extends LoggedUpdateMaintenance {
        public function __construct() {
                parent::__construct();
                $this->addDescription( 'Add RFC and PMID to the interwiki database table' );
@@ -91,5 +91,5 @@ class AddRFCAndPMIDInterwiki extends LoggedUpdateMaintenance {
        }
 }
 
-$maintClass = AddRFCAndPMIDInterwiki::class;
+$maintClass = AddRFCandPMIDInterwiki::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index 4953343..b0ee966 100644 (file)
@@ -11,7 +11,7 @@ require_once $basePath . '/maintenance/Maintenance.php';
  *
  * @since 1.29
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Florian Schmidt
  */
 class AddSite extends Maintenance {
diff --git a/maintenance/archives/patch-change_tag-tag_id.sql b/maintenance/archives/patch-change_tag-tag_id.sql
new file mode 100644 (file)
index 0000000..15b1c95
--- /dev/null
@@ -0,0 +1,7 @@
+--
+-- Add ctd_tag_id to change_tag table to normalize it
+--
+ALTER TABLE /*_*/change_tag
+  ADD COLUMN ct_tag_id int unsigned NULL;
+
+CREATE INDEX /*i*/change_tag_tag_id_id ON /*_*/change_tag (ct_tag_id,ct_rc_id,ct_rev_id,ct_log_id);
diff --git a/maintenance/archives/patch-externallinks-el_index_60-drop-default.sql b/maintenance/archives/patch-externallinks-el_index_60-drop-default.sql
new file mode 100644 (file)
index 0000000..f9242c5
--- /dev/null
@@ -0,0 +1,2 @@
+-- @since 1.32
+ALTER TABLE /*$wgDBprefix*/externallinks ALTER COLUMN el_index_60 DROP DEFAULT;
diff --git a/maintenance/categoryChangesAsRdf.php b/maintenance/categoryChangesAsRdf.php
new file mode 100644 (file)
index 0000000..a12cda7
--- /dev/null
@@ -0,0 +1,542 @@
+<?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
+ *
+ */
+use Wikimedia\Purtle\RdfWriter;
+use Wikimedia\Purtle\TurtleRdfWriter;
+use Wikimedia\Rdbms\IDatabase;
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Maintenance script to provide RDF representation of the recent changes in category tree.
+ *
+ * @ingroup Maintenance
+ * @since 1.30
+ */
+class CategoryChangesAsRdf extends Maintenance {
+       /**
+        * Insert query
+        */
+       const SPARQL_INSERT = <<<SPARQL
+INSERT DATA {
+%s
+};
+
+SPARQL;
+
+       /**
+        * Delete/Insert query
+        */
+       const SPARQL_DELETE_INSERT = <<<SPARQLDI
+DELETE {
+?category ?x ?y
+} INSERT {
+%s
+} WHERE {
+   VALUES ?category {
+     %s
+   }
+};
+
+SPARQLDI;
+
+       /**
+        * @var RdfWriter
+        */
+       private $rdfWriter;
+       /**
+        * Categories RDF helper.
+        * @var CategoriesRdf
+        */
+       private $categoriesRdf;
+
+       private $startTS;
+       private $endTS;
+
+       /**
+        * List of processed page IDs,
+        * so we don't try to process same thing twice
+        * @var int[]
+        */
+       protected $processed = [];
+
+       public function __construct() {
+               parent::__construct();
+
+               $this->addDescription( "Generate RDF dump of category changes in a wiki." );
+
+               $this->setBatchSize( 200 );
+               $this->addOption( 'output', "Output file (default is stdout). Will be overwritten.", false,
+                       true, 'o' );
+               $this->addOption( 'start', 'Starting timestamp (inclusive), in ISO or Mediawiki format.',
+                       true, true, 's' );
+               $this->addOption( 'end', 'Ending timestamp (exclusive), in ISO or Mediawiki format.', true,
+                       true, 'e' );
+       }
+
+       /**
+        * Initialize external service classes.
+        */
+       public function initialize() {
+               // SPARQL Update syntax is close to Turtle format, so we can use Turtle writer.
+               $this->rdfWriter = new TurtleRdfWriter();
+               $this->categoriesRdf = new CategoriesRdf( $this->rdfWriter );
+       }
+
+       public function execute() {
+               global $wgRCMaxAge;
+
+               $this->initialize();
+
+               $startTS = new MWTimestamp( $this->getOption( "start" ) );
+               $endTS = new MWTimestamp( $this->getOption( "end" ) );
+               $now = new MWTimestamp();
+
+               if ( $now->getTimestamp() - $startTS->getTimestamp() > $wgRCMaxAge ) {
+                       $this->error( "Start timestamp too old, maximum RC age is $wgRCMaxAge!" );
+               }
+               if ( $now->getTimestamp() - $endTS->getTimestamp() > $wgRCMaxAge ) {
+                       $this->error( "End timestamp too old, maximum RC age is $wgRCMaxAge!" );
+               }
+
+               $this->startTS = $startTS->getTimestamp();
+               $this->endTS = $endTS->getTimestamp();
+
+               $outFile = $this->getOption( 'output', 'php://stdout' );
+               if ( $outFile === '-' ) {
+                       $outFile = 'php://stdout';
+               }
+
+               $output = fopen( $outFile, 'wb' );
+
+               $this->categoriesRdf->setupPrefixes();
+               $this->rdfWriter->start();
+
+               $prefixes = $this->getRdf();
+               // We have to strip @ from prefix, since SPARQL UPDATE doesn't use them
+               // Also strip dot at the end.
+               $prefixes = preg_replace( [ '/^@/m', '/\s*[.]$/m' ], '', $prefixes );
+               fwrite( $output, $prefixes );
+
+               $dbr = $this->getDB( DB_REPLICA, [ 'vslow' ] );
+
+               // Deletes go first because if the page was deleted, other changes
+               // do not matter. This only gets true deletes, i.e. not pages that were restored.
+               $this->handleDeletes( $dbr, $output );
+               // Moves go before additions because if category is moved, we should not process creation
+               // as it would produce wrong data - because create row has old title
+               $this->handleMoves( $dbr, $output );
+               // We need to handle restores too since delete may have happened in previous update.
+               $this->handleRestores( $dbr, $output );
+               $this->handleAdds( $dbr, $output );
+               $this->handleChanges( $dbr, $output );
+
+               // Update timestamp
+               fwrite( $output, $this->updateTS( $this->endTS ) );
+       }
+
+       /**
+        * Get SPARQL for updating set of categories
+        * @param IDatabase $dbr
+        * @param string[] $deleteUrls List of URIs to be deleted, with <>
+        * @param string[] $pages List of categories: id => title
+        * @param string $mark Marks which operation requests the query
+        * @return string SPARQL query
+        */
+       private function getCategoriesUpdate( IDatabase $dbr, $deleteUrls, $pages, $mark ) {
+               if ( empty( $deleteUrls ) ) {
+                       return "";
+               }
+
+               if ( !empty( $pages ) ) {
+                       $this->writeParentCategories( $dbr, $pages );
+               }
+
+               return "# $mark\n" . sprintf( self::SPARQL_DELETE_INSERT,
+                               $this->getRdf(),
+                               implode( ' ', $deleteUrls ) );
+       }
+
+       /**
+        * Write data for a set of categories
+        * @param IDatabase $dbr
+        * @param string[] $pages List of categories: id => title
+        */
+       private function writeParentCategories( IDatabase $dbr, $pages ) {
+               foreach ( $this->getCategoryLinksIterator( $dbr, array_keys( $pages ) ) as $row ) {
+                       $this->categoriesRdf->writeCategoryLinkData( $pages[$row->cl_from], $row->cl_to );
+               }
+       }
+
+       /**
+        * Generate SPARQL Update code for updating dump timestamp
+        * @param string|int $timestamp Timestamp for last change
+        * @return string SPARQL Update query for timestamp.
+        */
+       public function updateTS( $timestamp ) {
+               $dumpUrl = '<' . $this->categoriesRdf->getDumpURI() . '>';
+               $ts = wfTimestamp( TS_ISO_8601, $timestamp );
+               $tsQuery = <<<SPARQL
+DELETE {
+  $dumpUrl schema:dateModified ?o .
+}
+WHERE {
+  $dumpUrl schema:dateModified ?o .
+};
+INSERT DATA {
+  $dumpUrl schema:dateModified "$ts"^^xsd:dateTime .
+}
+
+SPARQL;
+               return $tsQuery;
+       }
+
+       /**
+        * Set up standard iterator for retrieving category changes.
+        * @param IDatabase $dbr
+        * @param string[] $columns List of additional fields to get
+        * @param string[] $extra_tables List of additional tables to join
+        * @return BatchRowIterator
+        */
+       private function setupChangesIterator(
+               IDatabase $dbr,
+               array $columns = [],
+               array $extra_tables = []
+       ) {
+               $tables = [ 'recentchanges', 'page_props', 'category' ];
+               if ( $extra_tables ) {
+                       $tables += $extra_tables;
+               }
+               $it = new BatchRowIterator( $dbr,
+                       $tables,
+                       [ 'rc_timestamp' ],
+                       $this->mBatchSize
+               );
+               $this->addTimestampConditions( $it, $dbr );
+               $it->addJoinConditions(
+                       [
+                               'page_props' => [
+                                       'LEFT JOIN', [ 'pp_propname' => 'hiddencat', 'pp_page = rc_cur_id' ]
+                               ],
+                               'category' => [
+                                       'LEFT JOIN', [ 'cat_title = rc_title' ]
+                               ]
+                       ]
+               );
+               $it->setFetchColumns( array_merge( $columns, [
+                       'rc_title',
+                       'rc_cur_id',
+                       'pp_propname',
+                       'cat_pages',
+                       'cat_subcats',
+                       'cat_files'
+               ] ) );
+               return $it;
+       }
+
+       /**
+        * Fetch newly created categories
+        * @param IDatabase $dbr
+        * @return BatchRowIterator
+        */
+       protected function getNewCatsIterator( IDatabase $dbr ) {
+               $it = $this->setupChangesIterator( $dbr );
+               $it->addConditions( [
+                       'rc_namespace' => NS_CATEGORY,
+                       'rc_new' => 1,
+               ] );
+               return $it;
+       }
+
+       /**
+        * Fetch moved categories
+        * @param IDatabase $dbr
+        * @return BatchRowIterator
+        */
+       protected function getMovedCatsIterator( IDatabase $dbr ) {
+               $it = $this->setupChangesIterator( $dbr, [ 'page_title', 'page_namespace' ], [ 'page' ] );
+               $it->addConditions( [
+                       'rc_namespace' => NS_CATEGORY,
+                       'rc_new' => 0,
+                       'rc_log_type' => 'move',
+                       'rc_type' => RC_LOG,
+               ] );
+               $it->addJoinConditions( [
+                       'page' => [ 'INNER JOIN', 'rc_cur_id = page_id' ],
+               ] );
+               $this->addIndex( $it );
+               return $it;
+       }
+
+       /**
+        * Fetch deleted categories
+        * @param IDatabase $dbr
+        * @return BatchRowIterator
+        */
+       protected function getDeletedCatsIterator( IDatabase $dbr ) {
+               $it = new BatchRowIterator( $dbr,
+                       'recentchanges',
+                       [ 'rc_timestamp' ],
+                       $this->mBatchSize
+               );
+               $this->addTimestampConditions( $it, $dbr );
+               $it->addConditions( [
+                       'rc_namespace' => NS_CATEGORY,
+                       'rc_new' => 0,
+                       'rc_log_type' => 'delete',
+                       'rc_log_action' => 'delete',
+                       'rc_type' => RC_LOG,
+                       // We will fetch ones that do not have page record. If they do,
+                       // this means they were restored, thus restoring handler will pick it up.
+                       'NOT EXISTS (SELECT * FROM page WHERE page_id = rc_cur_id)',
+               ] );
+               $this->addIndex( $it );
+               $it->setFetchColumns( [ 'rc_cur_id', 'rc_title' ] );
+               return $it;
+       }
+
+       /**
+        * Fetch restored categories
+        * @param IDatabase $dbr
+        * @return BatchRowIterator
+        */
+       protected function getRestoredCatsIterator( IDatabase $dbr ) {
+               $it = $this->setupChangesIterator( $dbr );
+               $it->addConditions( [
+                       'rc_namespace' => NS_CATEGORY,
+                       'rc_new' => 0,
+                       'rc_log_type' => 'delete',
+                       'rc_log_action' => 'restore',
+                       'rc_type' => RC_LOG,
+                       // We will only fetch ones that have page record
+                       'EXISTS (SELECT page_id FROM page WHERE page_id = rc_cur_id)',
+               ] );
+               $this->addIndex( $it );
+               return $it;
+       }
+
+       /**
+        * Fetch categorization changes
+        * @param IDatabase $dbr
+        * @return BatchRowIterator
+        */
+       protected function getChangedCatsIterator( IDatabase $dbr ) {
+               $it = $this->setupChangesIterator( $dbr );
+               $it->addConditions( [
+                       'rc_namespace' => NS_CATEGORY,
+                       'rc_new' => 0,
+                       'rc_type' => [ RC_EDIT, RC_CATEGORIZE ],
+               ] );
+               $this->addIndex( $it );
+               return $it;
+       }
+
+       /**
+        * Add timestamp limits to iterator
+        * @param BatchRowIterator $it Iterator
+        * @param IDatabase $dbr
+        */
+       private function addTimestampConditions( BatchRowIterator $it, IDatabase $dbr ) {
+               $it->addConditions( [
+                       'rc_timestamp >= ' . $dbr->addQuotes( $dbr->timestamp( $this->startTS ) ),
+                       'rc_timestamp < ' . $dbr->addQuotes( $dbr->timestamp( $this->endTS ) ),
+               ] );
+       }
+
+       /**
+        * Need to force index, somehow on terbium the optimizer chooses wrong one
+        * @param BatchRowIterator $it
+        */
+       private function addIndex( BatchRowIterator $it ) {
+               $it->addOptions( [
+                       'USE INDEX' => [ 'recentchanges' => 'new_name_timestamp' ]
+               ] );
+       }
+
+       /**
+        * Get iterator for links for categories.
+        * @param IDatabase $dbr
+        * @param array $ids List of page IDs
+        * @return Traversable
+        */
+       protected function getCategoryLinksIterator( IDatabase $dbr, array $ids ) {
+               $it = new BatchRowIterator(
+                       $dbr,
+                       'categorylinks',
+                       [ 'cl_from', 'cl_to' ],
+                       $this->mBatchSize
+               );
+               $it->addConditions( [
+                       'cl_type' => 'subcat',
+                       'cl_from' => $ids
+               ] );
+               $it->setFetchColumns( [ 'cl_from', 'cl_to' ] );
+               return new RecursiveIteratorIterator( $it );
+       }
+
+       /**
+        * Get accumulated RDF.
+        * @return string
+        */
+       public function getRdf() {
+               return $this->rdfWriter->drain();
+       }
+
+       /**
+        * Handle category deletes.
+        * @param IDatabase $dbr
+        * @param resource $output File to write the output
+        */
+       public function handleDeletes( IDatabase $dbr, $output ) {
+               // This only does "true" deletes - i.e. those that the page stays deleted
+               foreach ( $this->getDeletedCatsIterator( $dbr ) as $batch ) {
+                       $deleteUrls = [];
+                       foreach ( $batch as $row ) {
+                               // This can produce duplicates, we don't care
+                               $deleteUrls[] = '<' . $this->categoriesRdf->labelToUrl( $row->rc_title ) . '>';
+                               $this->processed[$row->rc_cur_id] = true;
+                       }
+                       fwrite( $output, $this->getCategoriesUpdate( $dbr, $deleteUrls, [], "Deletes" ) );
+               }
+       }
+
+       /**
+        * Write category data to RDF.
+        * @param stdclass $row Database row
+        */
+       private function writeCategoryData( $row ) {
+               $this->categoriesRdf->writeCategoryData(
+                       $row->rc_title,
+                       $row->pp_propname === 'hiddencat',
+                       (int)$row->cat_pages - (int)$row->cat_subcats - (int)$row->cat_files,
+                       (int)$row->cat_subcats
+               );
+       }
+
+       /**
+        * @param IDatabase $dbr
+        * @param resource $output
+        */
+       public function handleMoves( IDatabase $dbr, $output ) {
+               foreach ( $this->getMovedCatsIterator( $dbr ) as $batch ) {
+                       $pages = [];
+                       $deleteUrls = [];
+                       foreach ( $batch as $row ) {
+                               $deleteUrls[] = '<' . $this->categoriesRdf->labelToUrl( $row->rc_title ) . '>';
+
+                               if ( isset( $this->processed[$row->rc_cur_id] ) ) {
+                                       // We already captured this one before
+                                       continue;
+                               }
+
+                               if ( $row->page_namespace != NS_CATEGORY ) {
+                                       // If page was moved out of Category:, we'll just delete
+                                       continue;
+                               }
+                               $row->rc_title = $row->page_title;
+                               $this->writeCategoryData( $row );
+                               $pages[$row->rc_cur_id] = $row->page_title;
+                               $this->processed[$row->rc_cur_id] = true;
+                       }
+
+                       fwrite( $output, $this->getCategoriesUpdate( $dbr, $deleteUrls, $pages, "Moves" ) );
+               }
+       }
+
+       /**
+        * @param IDatabase $dbr
+        * @param resource $output
+        */
+       public function handleRestores( IDatabase $dbr, $output ) {
+               fwrite( $output, "# Restores\n" );
+               // This will only find those restores that were not deleted later.
+               foreach ( $this->getRestoredCatsIterator( $dbr ) as $batch ) {
+                       $pages = [];
+                       foreach ( $batch as $row ) {
+                               if ( isset( $this->processed[$row->rc_cur_id] ) ) {
+                                       // We already captured this one before
+                                       continue;
+                               }
+                               $this->writeCategoryData( $row );
+                               $pages[$row->rc_cur_id] = $row->rc_title;
+                               $this->processed[$row->rc_cur_id] = true;
+                       }
+
+                       if ( empty( $pages ) ) {
+                               continue;
+                       }
+
+                       $this->writeParentCategories( $dbr, $pages );
+
+                       fwrite( $output, sprintf( self::SPARQL_INSERT, $this->getRdf() ) );
+               }
+       }
+
+       /**
+        * @param IDatabase $dbr
+        * @param resource $output
+        */
+       public function handleAdds( IDatabase $dbr, $output ) {
+               fwrite( $output, "# Additions\n" );
+               foreach ( $this->getNewCatsIterator( $dbr ) as $batch ) {
+                       $pages = [];
+                       foreach ( $batch as $row ) {
+                               if ( isset( $this->processed[$row->rc_cur_id] ) ) {
+                                       // We already captured this one before
+                                       continue;
+                               }
+                               $this->writeCategoryData( $row );
+                               $pages[$row->rc_cur_id] = $row->rc_title;
+                               $this->processed[$row->rc_cur_id] = true;
+                       }
+
+                       if ( empty( $pages ) ) {
+                               continue;
+                       }
+
+                       $this->writeParentCategories( $dbr, $pages );
+                       fwrite( $output, sprintf( self::SPARQL_INSERT, $this->getRdf() ) );
+               }
+       }
+
+       /**
+        * @param IDatabase $dbr
+        * @param resource $output
+        */
+       public function handleChanges( IDatabase $dbr, $output ) {
+               foreach ( $this->getChangedCatsIterator( $dbr ) as $batch ) {
+                       $pages = [];
+                       $deleteUrls = [];
+                       foreach ( $batch as $row ) {
+                               if ( isset( $this->processed[$row->rc_cur_id] ) ) {
+                                       // We already captured this one before
+                                       continue;
+                               }
+                               $this->writeCategoryData( $row );
+                               $pages[$row->rc_cur_id] = $row->rc_title;
+                               $this->processed[$row->rc_cur_id] = true;
+                               $deleteUrls[] = '<' . $this->categoriesRdf->labelToUrl( $row->rc_title ) . '>';
+                       }
+
+                       fwrite( $output, $this->getCategoriesUpdate( $dbr, $deleteUrls, $pages, "Changes" ) );
+               }
+       }
+}
+
+$maintClass = CategoryChangesAsRdf::class;
+require_once RUN_MAINTENANCE_IF_MAIN;
index 546825b..2b47056 100644 (file)
@@ -37,7 +37,7 @@ require_once __DIR__ . '/cleanupTable.inc';
  *
  * @ingroup Maintenance
  */
-class CapsCleanup extends TableCleanup {
+class CleanupCaps extends TableCleanup {
 
        private $user;
        private $namespace;
@@ -86,7 +86,7 @@ class CapsCleanup extends TableCleanup {
                $target = Title::makeTitle( $row->page_namespace, $upper );
                if ( $target->exists() ) {
                        // Prefix "CapsCleanup" to bypass the conflict
-                       $target = Title::newFromText( __CLASS__ . '/' . $display );
+                       $target = Title::newFromText( 'CapsCleanup/' . $display );
                }
                $ok = $this->movePage(
                        $current,
@@ -169,5 +169,5 @@ class CapsCleanup extends TableCleanup {
        }
 }
 
-$maintClass = CapsCleanup::class;
+$maintClass = CleanupCaps::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index fbdc7c2..90364e2 100644 (file)
@@ -32,7 +32,7 @@ require_once __DIR__ . '/cleanupTable.inc';
  *
  * @ingroup Maintenance
  */
-class ImageCleanup extends TableCleanup {
+class CleanupImages extends TableCleanup {
        protected $defaultParams = [
                'table' => 'image',
                'conds' => [],
@@ -220,5 +220,5 @@ class ImageCleanup extends TableCleanup {
        }
 }
 
-$maintClass = ImageCleanup::class;
+$maintClass = CleanupImages::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index 5b441f9..234e1b1 100644 (file)
@@ -38,6 +38,7 @@ class TitleCleanup extends TableCleanup {
        public function __construct() {
                parent::__construct();
                $this->addDescription( 'Script to clean up broken, unparseable titles' );
+               $this->batchSize = 1000;
        }
 
        /**
index 61cd9c2..d255348 100644 (file)
@@ -33,7 +33,7 @@ require_once __DIR__ . '/Maintenance.php';
  *
  * @ingroup Maintenance
  */
-class UploadStashCleanup extends Maintenance {
+class CleanupUploadStash extends Maintenance {
 
        public function __construct() {
                parent::__construct();
@@ -152,5 +152,5 @@ class UploadStashCleanup extends Maintenance {
        }
 }
 
-$maintClass = UploadStashCleanup::class;
+$maintClass = CleanupUploadStash::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index 64d39dd..5e3aee7 100644 (file)
@@ -36,7 +36,7 @@ require_once __DIR__ . '/cleanupTable.inc';
  *
  * @ingroup Maintenance
  */
-class WatchlistCleanup extends TableCleanup {
+class CleanupWatchlist extends TableCleanup {
        protected $defaultParams = [
                'table' => 'watchlist',
                'index' => [ 'wl_user', 'wl_namespace', 'wl_title' ],
@@ -95,5 +95,5 @@ class WatchlistCleanup extends TableCleanup {
        }
 }
 
-$maintClass = WatchlistCleanup::class;
+$maintClass = CleanupWatchlist::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index ef5a30d..de611ec 100644 (file)
@@ -35,7 +35,7 @@ require_once __DIR__ . '/Maintenance.php';
  * @since 1.27
  * @ingroup Maintenance
  */
-class GenerateCommonPassword extends Maintenance {
+class CreateCommonPasswordCdb extends Maintenance {
        public function __construct() {
                global $IP;
                parent::__construct();
@@ -114,5 +114,5 @@ class GenerateCommonPassword extends Maintenance {
        }
 }
 
-$maintClass = GenerateCommonPassword::class;
+$maintClass = CreateCommonPasswordCdb::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
diff --git a/maintenance/deduplicateArchiveRevId.php b/maintenance/deduplicateArchiveRevId.php
new file mode 100644 (file)
index 0000000..dad79b0
--- /dev/null
@@ -0,0 +1,209 @@
+<?php
+
+use Wikimedia\Rdbms\IDatabase;
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Maintenance script that cleans up archive rows with duplicated ar_rev_id,
+ * both within archive and between archive and revision.
+ *
+ * @ingroup Maintenance
+ * @since 1.32
+ */
+class DeduplicateArchiveRevId extends LoggedUpdateMaintenance {
+
+       /** @var array|null */
+       private $arActorQuery = null;
+
+       private $deleted = 0;
+       private $reassigned = 0;
+
+       public function __construct() {
+               parent::__construct();
+               $this->addDescription(
+                       'Clean up duplicate ar_rev_id, both within archive and between archive and revision.'
+               );
+               $this->setBatchSize( 10000 );
+       }
+
+       protected function getUpdateKey() {
+               return __CLASS__;
+       }
+
+       protected function doDBUpdates() {
+               $this->output( "Deduplicating ar_rev_id...\n" );
+
+               $dbw = $this->getDB( DB_MASTER );
+
+               $minId = $dbw->selectField( 'archive', 'MIN(ar_rev_id)', [], __METHOD__ );
+               $maxId = $dbw->selectField( 'archive', 'MAX(ar_rev_id)', [], __METHOD__ );
+               $batchSize = $this->getBatchSize();
+
+               $this->arActorQuery = ActorMigration::newMigration()->getJoin( 'ar_user' );
+               $revActorQuery = ActorMigration::newMigration()->getJoin( 'rev_user' );
+
+               for ( $id = $minId; $id <= $maxId; $id += $batchSize ) {
+                       $endId = min( $maxId, $id + $batchSize - 1 );
+
+                       $this->beginTransaction( $dbw, __METHOD__ );
+
+                       // Lock the archive and revision table rows for the IDs we're checking
+                       // to try to prevent deletions or undeletions from confusing things.
+                       $dbw->selectRowCount(
+                               'archive',
+                               1,
+                               [ 'ar_rev_id >= ' . (int)$id, 'ar_rev_id <= ' . (int)$endId ],
+                               __METHOD__,
+                               [ 'FOR UPDATE' ]
+                       );
+                       $dbw->selectRowCount(
+                               'revision',
+                               1,
+                               [ 'rev_id >= ' . (int)$id, 'rev_id <= ' . (int)$endId ],
+                               __METHOD__,
+                               [ 'LOCK IN SHARE MODE' ]
+                       );
+
+                       // Figure out the ar_rev_ids we actually need to look at
+                       $res = $dbw->select(
+                               [ 'archive', 'revision' ] + $revActorQuery['tables'],
+                               [ 'rev_id', 'rev_timestamp', 'rev_sha1' ] + $revActorQuery['fields'],
+                               [ 'ar_rev_id >= ' . (int)$id, 'ar_rev_id <= ' . (int)$endId ],
+                               __METHOD__,
+                               [ 'DISTINCT' ],
+                               [ 'revision' => [ 'JOIN', 'ar_rev_id = rev_id' ] ] + $revActorQuery['joins']
+                       );
+                       $revRows = [];
+                       foreach ( $res as $row ) {
+                               $revRows[$row->rev_id] = $row;
+                       }
+
+                       $arRevIds = $dbw->selectFieldValues(
+                               [ 'archive' ],
+                               'ar_rev_id',
+                               [ 'ar_rev_id >= ' . (int)$id, 'ar_rev_id <= ' . (int)$endId ],
+                               __METHOD__,
+                               [ 'GROUP BY' => 'ar_rev_id', 'HAVING' => 'COUNT(*) > 1' ]
+                       );
+                       $arRevIds = array_values( array_unique( array_merge( $arRevIds, array_keys( $revRows ) ) ) );
+
+                       if ( $arRevIds ) {
+                               $this->processArRevIds( $dbw, $arRevIds, $revRows );
+                       }
+
+                       $this->output( "... $id-$endId\n" );
+                       $this->commitTransaction( $dbw, __METHOD__ );
+               }
+
+               $this->output(
+                       "Finished deduplicating ar_rev_id. $this->deleted rows deleted, "
+                       . "$this->reassigned assigned new IDs.\n"
+               );
+               return true;
+       }
+
+       /**
+        * Process a set of ar_rev_ids
+        * @param IDatabase $dbw
+        * @param int[] $arRevIds IDs to process
+        * @param object[] $revRows Existing revision-table row data
+        */
+       private function processArRevIds( IDatabase $dbw, array $arRevIds, array $revRows ) {
+               // Select all the data we need for deduplication
+               $res = $dbw->select(
+                       [ 'archive' ] + $this->arActorQuery['tables'],
+                       [ 'ar_id', 'ar_rev_id', 'ar_namespace', 'ar_title', 'ar_timestamp', 'ar_sha1' ]
+                               + $this->arActorQuery['fields'],
+                       [ 'ar_rev_id' => $arRevIds ],
+                       __METHOD__,
+                       [],
+                       $this->arActorQuery['joins']
+               );
+
+               // Determine which rows we need to delete or reassign
+               $seen = [];
+               $toDelete = [];
+               $toReassign = [];
+               foreach ( $res as $row ) {
+                       // Revision-table row exists?
+                       if ( isset( $revRows[$row->ar_rev_id] ) ) {
+                               $revRow = $revRows[$row->ar_rev_id];
+
+                               // Record the rev_id as seen, so the code below will always delete or reassign.
+                               if ( !isset( $seen[$revRow->rev_id] ) ) {
+                                       $seen[$revRow->rev_id] = [
+                                               'first' => "revision row",
+                                       ];
+                               }
+
+                               // Delete the archive row if it seems to be the same regardless
+                               // of page, because moves can change IDs and titles.
+                               if ( $row->ar_timestamp === $revRow->rev_timestamp &&
+                                       $row->ar_sha1 === $revRow->rev_sha1 &&
+                                       $row->ar_user === $revRow->rev_user &&
+                                       $row->ar_user_text === $revRow->rev_user_text
+                               ) {
+                                       $this->output(
+                                               "Row $row->ar_id duplicates revision row for rev_id $revRow->rev_id, deleting\n"
+                                       );
+                                       $toDelete[] = $row->ar_id;
+                                       continue;
+                               }
+                       }
+
+                       $key = $this->getSeenKey( $row );
+                       if ( !isset( $seen[$row->ar_rev_id] ) ) {
+                               // This rev_id hasn't even been seen yet, nothing to do besides record it.
+                               $seen[$row->ar_rev_id] = [
+                                       'first' => "archive row $row->ar_id",
+                                       $key => $row->ar_id,
+                               ];
+                       } elseif ( !isset( $seen[$row->ar_rev_id][$key] ) ) {
+                               // The rev_id was seen, but not this particular change. Reassign it.
+                               $seen[$row->ar_rev_id][$key] = $row->ar_id;
+                               $this->output(
+                                       "Row $row->ar_id conflicts with {$seen[$row->ar_rev_id]['first']} "
+                                       . "for rev_id $row->ar_rev_id, reassigning\n"
+                               );
+                               $toReassign[] = $row->ar_id;
+                       } else {
+                               // The rev_id was seen with a row that matches this change. Delete it.
+                               $this->output(
+                                       "Row $row->ar_id duplicates archive row {$seen[$row->ar_rev_id][$key]} "
+                                       . "for rev_id $row->ar_rev_id, deleting\n"
+                               );
+                               $toDelete[] = $row->ar_id;
+                       }
+               }
+
+               // Perform the updates
+               if ( $toDelete ) {
+                       $dbw->delete( 'archive', [ 'ar_id' => $toDelete ], __METHOD__ );
+                       $this->deleted += $dbw->affectedRows();
+               }
+               if ( $toReassign ) {
+                       $this->reassigned += PopulateArchiveRevId::reassignArRevIds( $dbw, $toReassign );
+               }
+       }
+
+       /**
+        * Make a key identifying a "unique" change from a row
+        * @param object $row
+        * @return string
+        */
+       private function getSeenKey( $row ) {
+               return implode( "\n", [
+                       $row->ar_namespace,
+                       $row->ar_title,
+                       $row->ar_timestamp,
+                       $row->ar_sha1,
+                       $row->ar_user,
+                       $row->ar_user_text,
+               ] );
+       }
+
+}
+
+$maintClass = "DeduplicateArchiveRevId";
+require_once RUN_MAINTENANCE_IF_MAIN;
index c1935a7..82bb928 100644 (file)
@@ -31,8 +31,7 @@ class DeleteAutoPatrolLogs extends Maintenance {
                $this->addOption( 'dry-run', 'Print debug info instead of actually deleting' );
                $this->addOption(
                        'check-old',
-                       'Check old patrol logs (for deleting old format autopatrols).' .
-                               'Note that this will not delete rows older than 2011 (MediaWiki 1.18).'
+                       'Check old patrol logs (for deleting old format autopatrols).'
                );
                $this->addOption(
                        'before',
@@ -156,17 +155,27 @@ class DeleteAutoPatrolLogs extends Maintenance {
                $autopatrols = [];
                foreach ( $result as $row ) {
                        $last = $row->log_id;
-                       Wikimedia\suppressWarnings();
-                       $params = unserialize( $row->log_params );
-                       Wikimedia\restoreWarnings();
+                       $logEntry = DatabaseLogEntry::newFromRow( $row );
+                       $params = $logEntry->getParameters();
+                       if ( !is_array( $params ) ) {
+                               continue;
+                       }
 
-                       // Skipping really old rows, before 2011
-                       if ( !is_array( $params ) || !array_key_exists( '6::auto', $params ) ) {
+                       // This logic belongs to PatrolLogFormatter::getMessageKey
+                       // and LogFormatter::extractParameters the 'auto' value is logically presented as key [5].
+                       // For legacy case the logical key is index + 3, meaning [2].
+                       // For the modern case, the logical key is index - 1 meaning [6].
+                       if ( array_key_exists( '6::auto', $params ) ) {
+                               // Between 2011-2016 autopatrol logs
+                               $auto = $params['6::auto'] === true;
+                       } elseif ( $logEntry->isLegacy() === true && array_key_exists( 2, $params ) ) {
+                               // Pre-2011 autopatrol logs
+                               $auto = $params[2] === '1';
+                       } else {
                                continue;
                        }
 
-                       $auto = $params['6::auto'];
-                       if ( $auto ) {
+                       if ( $auto === true ) {
                                $autopatrols[] = $row->log_id;
                        }
                }
index 4bfc574..b4df20f 100644 (file)
@@ -29,7 +29,7 @@ require_once __DIR__ . '/Maintenance.php';
  *
  * @ingroup Maintenance
  */
-class UploadDumper extends Maintenance {
+class DumpUploads extends Maintenance {
        public function __construct() {
                parent::__construct();
                $this->addDescription( 'Generates list of uploaded files which can be fed to tar or similar.
@@ -124,5 +124,5 @@ By default, outputs relative paths against the parent directory of $wgUploadDire
        }
 }
 
-$maintClass = UploadDumper::class;
+$maintClass = DumpUploads::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index 736b12b..4456c75 100644 (file)
@@ -9,7 +9,7 @@ require_once $basePath . '/maintenance/Maintenance.php';
  *
  * @since 1.25
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Daniel Kinzler
  */
 class ExportSites extends Maintenance {
index a60942f..a04de08 100644 (file)
@@ -29,7 +29,7 @@ require_once __DIR__ . '/Maintenance.php';
  *
  * @ingroup Maintenance
  */
-class TestFileOpPerformance extends Maintenance {
+class FileOpPerfTest extends Maintenance {
        public function __construct() {
                parent::__construct();
                $this->addDescription( 'Test fileop performance' );
@@ -141,5 +141,5 @@ class TestFileOpPerformance extends Maintenance {
        }
 }
 
-$maintClass = TestFileOpPerformance::class;
+$maintClass = FileOpPerfTest::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index c70b8be..f5861e5 100644 (file)
@@ -71,11 +71,13 @@ class FixExtLinksProtocolRelative extends LoggedUpdateMaintenance {
                                                'el_from' => $row->el_from,
                                                'el_to' => $row->el_to,
                                                'el_index' => "http:{$row->el_index}",
+                                               'el_index_60' => substr( "http:{$row->el_index}", 0, 60 ),
                                        ],
                                        [
                                                'el_from' => $row->el_from,
                                                'el_to' => $row->el_to,
                                                'el_index' => "https:{$row->el_index}",
+                                               'el_index_60' => substr( "https:{$row->el_index}", 0, 60 ),
                                        ]
                                ], __METHOD__, [ 'IGNORE' ]
                        );
index dbaeb86..3d34be1 100644 (file)
@@ -28,7 +28,7 @@ require_once __DIR__ . '/Maintenance.php';
  *
  * @ingroup Maintenance
  */
-class MaintenanceFormatInstallDoc extends Maintenance {
+class FormatInstallDoc extends Maintenance {
        function __construct() {
                parent::__construct();
                $this->addArg( 'path', 'The file name to format', false );
@@ -72,5 +72,5 @@ class MaintenanceFormatInstallDoc extends Maintenance {
        }
 }
 
-$maintClass = MaintenanceFormatInstallDoc::class;
+$maintClass = FormatInstallDoc::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index c0c6284..554e373 100644 (file)
@@ -30,7 +30,7 @@ use MediaWiki\MediaWikiServices;
  *
  * @ingroup Maintenance
  */
-class GetSlaveServer extends Maintenance {
+class GetReplicaServer extends Maintenance {
        public function __construct() {
                parent::__construct();
                $this->addOption( "group", "Query group to check specifically" );
@@ -53,5 +53,5 @@ class GetSlaveServer extends Maintenance {
        }
 }
 
-$maintClass = GetSlaveServer::class;
+$maintClass = GetReplicaServer::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index be6cc05..6859eb4 100644 (file)
@@ -9,7 +9,7 @@ require_once $basePath . '/maintenance/Maintenance.php';
  *
  * @since 1.25
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Daniel Kinzler
  */
 class ImportSites extends Maintenance {
index fafc1c6..d30a077 100644 (file)
@@ -67,11 +67,11 @@ class GenerateCollationData extends Maintenance {
 
                // 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";
+               $allkeysURL = "https://www.unicode.org/Public/UCA/<Unicode version>/allkeys.txt";
+               $ucdallURL = "https://www.unicode.org/Public/<Unicode version>/ucdxml/ucd.all.grouped.zip";
 
                if ( !$allkeysPresent || !$ucdallPresent ) {
-                       $icuVersion = IcuCollation::getICUVersion();
+                       $icuVersion = INTL_ICU_VERSION;
                        $unicodeVersion = IcuCollation::getUnicodeVersionForICU();
 
                        $error = "";
@@ -88,16 +88,7 @@ class GenerateCollationData extends Maintenance {
                        }
 
                        $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", "<" ) ) {
+                       if ( 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" )
index 90ca41e..af47d65 100644 (file)
@@ -35,7 +35,7 @@ class GenerateNormalizerDataAr extends Maintenance {
                parent::__construct();
                $this->addDescription( 'Generate the normalizer data file for Arabic' );
                $this->addOption( 'unicode-data-file', 'The local location of the data file ' .
-                       'from http://unicode.org/Public/UNIDATA/UnicodeData.txt', false, true );
+                       'from https://unicode.org/Public/6.0.0/ucd/UnicodeData.txt', false, true );
        }
 
        public function getDbType() {
@@ -61,7 +61,7 @@ class GenerateNormalizerDataAr extends Maintenance {
                        $this->fatalError( 'Unable to open the data file.' );
                }
 
-               // For the file format, see http://www.unicode.org/reports/tr44/
+               // For the file format, see https://www.unicode.org/reports/tr44/
                $fieldNames = [
                        'Code',
                        'Name',
@@ -122,7 +122,11 @@ class GenerateNormalizerDataAr extends Maintenance {
                }
 
                global $IP;
-               file_put_contents( "$IP/serialized/normalize-ar.ser", serialize( $pairs ) );
+               file_put_contents( "$IP/languages/data/normalize-ar.php", wfMakeStaticArrayFile(
+                       $pairs,
+                       'File created by generateNormalizerDataAr.php'
+               ) );
+
                echo "ar: " . count( $pairs ) . " pairs written.\n";
        }
 }
index 664f06c..5b75d8b 100644 (file)
@@ -42,7 +42,7 @@ class GenerateNormalizerDataMl extends Maintenance {
 
        public function execute() {
                $hexPairs = [
-                       # From http://unicode.org/versions/Unicode5.1.0/#Malayalam_Chillu_Characters
+                       # From https://www.unicode.org/versions/Unicode5.1.0/#Malayalam_Chillu_Characters
                        '0D23 0D4D 200D' => '0D7A',
                        '0D28 0D4D 200D' => '0D7B',
                        '0D30 0D4D 200D' => '0D7C',
@@ -61,7 +61,11 @@ class GenerateNormalizerDataMl extends Maintenance {
                }
 
                global $IP;
-               file_put_contents( "$IP/serialized/normalize-ml.ser", serialize( $pairs ) );
+               file_put_contents( "$IP/languages/data/normalize-ml.php", wfMakeStaticArrayFile(
+                       $pairs,
+                       'File created by generateNormalizerDataMl.php'
+               ) );
+
                echo "ml: " . count( $pairs ) . " pairs written.\n";
        }
 }
index abe08e4..88128ae 100755 (executable)
@@ -301,7 +301,7 @@ def PHPArray(table):
 
 def main():
     # Get Unihan.zip:
-    url = 'http://www.unicode.org/Public/%s/ucd/Unihan.zip' % UNIHAN_VER
+    url = 'https://www.unicode.org/Public/%s/ucd/Unihan.zip' % UNIHAN_VER
     han_dest = 'Unihan-%s.zip' % UNIHAN_VER
     download(url, han_dest)
 
diff --git a/maintenance/mssql/archives/patch-change_tag-tag_id.sql b/maintenance/mssql/archives/patch-change_tag-tag_id.sql
new file mode 100644 (file)
index 0000000..869ee11
--- /dev/null
@@ -0,0 +1,7 @@
+--
+-- Add ctd_tag_id to change_tag table to normalize it
+--
+ALTER TABLE /*_*/change_tag
+  ADD COLUMN ct_tag_id int NULL CONSTRAINT ctd_tag_id__fk FOREIGN KEY REFERENCES /*_*/change_tag_def(ctd_id);
+
+CREATE INDEX /*i*/change_tag_tag_id_id ON /*_*/change_tag (ct_tag_id,ct_rc_id,ct_rev_id,ct_log_id);
diff --git a/maintenance/mssql/archives/patch-externallinks-el_index_60-drop-default.sql b/maintenance/mssql/archives/patch-externallinks-el_index_60-drop-default.sql
new file mode 100644 (file)
index 0000000..7755e66
--- /dev/null
@@ -0,0 +1,13 @@
+DECLARE @sql nvarchar(max)
+SET @sql=''
+
+SELECT @sql= @sql + 'ALTER TABLE /*_*/externallinks DROP CONSTRAINT ' + df.name + '; '
+FROM sys.default_constraints df
+JOIN sys.columns c
+       ON c.object_id = df.parent_object_id
+       AND c.column_id = df.parent_column_id
+WHERE
+       df.parent_object_id =  OBJECT_ID('/*_*/externallinks')
+       AND c.name = 'el_index_60';--
+
+EXEC sp_executesql @sql;
index 858260b..fbe207d 100644 (file)
@@ -549,8 +549,7 @@ CREATE TABLE /*_*/externallinks (
 
   -- This is el_index truncated to 60 bytes to allow for sortable queries that
   -- aren't supported by a partial index.
-  -- @todo Drop the default once this is deployed everywhere and code is populating it.
-  el_index_60 varbinary(60) NOT NULL default ''
+  el_index_60 varbinary(60) NOT NULL
 );
 
 CREATE INDEX /*i*/el_from ON /*_*/externallinks (el_from);
@@ -1404,7 +1403,9 @@ CREATE TABLE /*_*/change_tag (
   -- Tag applied
   ct_tag nvarchar(255) NOT NULL,
   -- Parameters for the tag, presently unused
-  ct_params nvarchar(max) NULL
+  ct_params nvarchar(max) NULL,
+  -- Foreign key to change_tag_def row
+  ct_tag_id int NULL CONSTRAINT ctd_tag_id__fk FOREIGN KEY REFERENCES /*_*/change_tag_def(ctd_id)
 );
 
 CREATE UNIQUE INDEX /*i*/change_tag_rc_tag ON /*_*/change_tag (ct_rc_id,ct_tag);
@@ -1412,7 +1413,7 @@ CREATE UNIQUE INDEX /*i*/change_tag_log_tag ON /*_*/change_tag (ct_log_id,ct_tag
 CREATE UNIQUE INDEX /*i*/change_tag_rev_tag ON /*_*/change_tag (ct_rev_id,ct_tag);
 -- Covering index, so we can pull all the info only out of the index.
 CREATE INDEX /*i*/change_tag_tag_id ON /*_*/change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id);
-
+CREATE INDEX /*i*/change_tag_tag_id_id ON /*_*/change_tag (ct_tag_id,ct_rc_id,ct_rev_id,ct_log_id);
 
 -- Rollup table to pull a LIST of tags simply without ugly GROUP_CONCAT
 -- that only works on MySQL 4.1+
index 3c83921..bbe4469 100644 (file)
@@ -37,7 +37,7 @@ use Wikimedia\Rdbms\IMaintainableDatabase;
  *
  * @ingroup Maintenance
  */
-class NamespaceConflictChecker extends Maintenance {
+class NamespaceDupes extends Maintenance {
 
        /**
         * @var IMaintainableDatabase
@@ -616,5 +616,5 @@ class NamespaceConflictChecker extends Maintenance {
        }
 }
 
-$maintClass = NamespaceConflictChecker::class;
+$maintClass = NamespaceDupes::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
diff --git a/maintenance/oracle/archives/patch-change_tag-tag_id.sql b/maintenance/oracle/archives/patch-change_tag-tag_id.sql
new file mode 100644 (file)
index 0000000..1f4067c
--- /dev/null
@@ -0,0 +1,6 @@
+--
+-- Add ctd_tag_id to change_tag table to normalize it
+--
+ALTER TABLE &mw_prefix.change_tag ADD ( ct_tag_id NUMBER DEFAULT NULL );
+
+CREATE INDEX &mw_prefix.change_tag_i02 ON &mw_prefix.change_tag (ct_tag_id,ct_rc_id,ct_rev_id,ct_log_id);
index df74f64..6e36752 100644 (file)
@@ -942,13 +942,15 @@ CREATE TABLE &mw_prefix.change_tag (
   ct_log_id NUMBER NULL,
   ct_rev_id NUMBER NULL,
   ct_tag VARCHAR2(255) NOT NULL,
-  ct_params BLOB NULL
+  ct_params BLOB NULL,
+  ct_tag_id NUMBER NULL,
 );
 ALTER TABLE &mw_prefix.change_tag ADD CONSTRAINT &mw_prefix.change_tag_pk PRIMARY KEY (ct_id);
 CREATE UNIQUE INDEX &mw_prefix.change_tag_u01 ON &mw_prefix.change_tag (ct_rc_id,ct_tag);
 CREATE UNIQUE INDEX &mw_prefix.change_tag_u02 ON &mw_prefix.change_tag (ct_log_id,ct_tag);
 CREATE UNIQUE INDEX &mw_prefix.change_tag_u03 ON &mw_prefix.change_tag (ct_rev_id,ct_tag);
 CREATE INDEX &mw_prefix.change_tag_i01 ON &mw_prefix.change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id);
+CREATE INDEX &mw_prefix.change_tag_i02 ON &mw_prefix.change_tag (ct_tag_id,ct_rc_id,ct_rev_id,ct_log_id);
 
 CREATE TABLE &mw_prefix.tag_summary (
   ts_id NUMBER NOT NULL,
index b87a716..cf2fe54 100644 (file)
@@ -46,7 +46,7 @@
  * @file
  * @ingroup Maintenance
  * @author Antoine Musso <hashar at free dot fr>
- * @license GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  */
 
 require_once __DIR__ . '/Maintenance.php';
index b8b9e68..e493506 100644 (file)
@@ -32,6 +32,10 @@ require_once __DIR__ . '/Maintenance.php';
  * @since 1.31
  */
 class PopulateArchiveRevId extends LoggedUpdateMaintenance {
+
+       /** @var array|null Dummy revision row */
+       private static $dummyRev = null;
+
        public function __construct() {
                parent::__construct();
                $this->addDescription( 'Populate ar_rev_id in pre-1.5 rows' );
@@ -58,7 +62,6 @@ class PopulateArchiveRevId extends LoggedUpdateMaintenance {
                        return true;
                }
 
-               $rev = $this->makeDummyRevisionRow( $dbw );
                $count = 0;
                while ( true ) {
                        wfWaitForSlaves();
@@ -75,47 +78,60 @@ class PopulateArchiveRevId extends LoggedUpdateMaintenance {
                                return true;
                        }
 
-                       try {
-                               $updates = $dbw->doAtomicSection( __METHOD__, function ( $dbw, $fname ) use ( $arIds, $rev ) {
-                                       // Create new rev_ids by inserting dummy rows into revision and then deleting them.
-                                       $dbw->insert( 'revision', array_fill( 0, count( $arIds ), $rev ), $fname );
-                                       $revIds = $dbw->selectFieldValues(
-                                               'revision',
-                                               'rev_id',
-                                               [ 'rev_timestamp' => $rev['rev_timestamp'] ],
-                                               $fname
-                                       );
-                                       if ( !is_array( $revIds ) ) {
-                                               throw new UnexpectedValueException( 'Failed to insert dummy revisions' );
-                                       }
-                                       if ( count( $revIds ) !== count( $arIds ) ) {
-                                               throw new UnexpectedValueException(
-                                                       'Tried to insert ' . count( $arIds ) . ' dummy revisions, but found '
-                                                       . count( $revIds ) . ' matching rows.'
-                                               );
-                                       }
-                                       $dbw->delete( 'revision', [ 'rev_id' => $revIds ], $fname );
-
-                                       return array_combine( $arIds, $revIds );
-                               } );
-                       } catch ( UnexpectedValueException $ex ) {
-                               $this->fatalError( $ex->getMessage() );
-                       }
+                       $count += self::reassignArRevIds( $dbw, $arIds, [ 'ar_rev_id' => null ] );
+
+                       $min = min( $arIds );
+                       $max = max( $arIds );
+                       $this->output( " ... $min-$max\n" );
+               }
+       }
 
-                       foreach ( $updates as $arId => $revId ) {
-                               $dbw->update(
-                                       'archive',
-                                       [ 'ar_rev_id' => $revId ],
-                                       [ 'ar_id' => $arId, 'ar_rev_id' => null ],
-                                       __METHOD__
+       /**
+        * Assign new ar_rev_ids to a set of ar_ids.
+        * @param IDatabase $dbw
+        * @param int[] $arIds
+        * @param array $conds Extra conditions for the update
+        * @return int Number of updated rows
+        */
+       public static function reassignArRevIds( IDatabase $dbw, array $arIds, array $conds = [] ) {
+               if ( !self::$dummyRev ) {
+                       self::$dummyRev = self::makeDummyRevisionRow( $dbw );
+               }
+
+               $updates = $dbw->doAtomicSection( __METHOD__, function ( $dbw, $fname ) use ( $arIds ) {
+                       // Create new rev_ids by inserting dummy rows into revision and then deleting them.
+                       $dbw->insert( 'revision', array_fill( 0, count( $arIds ), self::$dummyRev ), $fname );
+                       $revIds = $dbw->selectFieldValues(
+                               'revision',
+                               'rev_id',
+                               [ 'rev_timestamp' => self::$dummyRev['rev_timestamp'] ],
+                               $fname
+                       );
+                       if ( !is_array( $revIds ) ) {
+                               throw new UnexpectedValueException( 'Failed to insert dummy revisions' );
+                       }
+                       if ( count( $revIds ) !== count( $arIds ) ) {
+                               throw new UnexpectedValueException(
+                                       'Tried to insert ' . count( $arIds ) . ' dummy revisions, but found '
+                                       . count( $revIds ) . ' matching rows.'
                                );
-                               $count += $dbw->affectedRows();
                        }
+                       $dbw->delete( 'revision', [ 'rev_id' => $revIds ], $fname );
 
-                       $min = min( array_keys( $updates ) );
-                       $max = max( array_keys( $updates ) );
-                       $this->output( " ... $min-$max\n" );
+                       return array_combine( $arIds, $revIds );
+               } );
+
+               $count = 0;
+               foreach ( $updates as $arId => $revId ) {
+                       $dbw->update(
+                               'archive',
+                               [ 'ar_rev_id' => $revId ],
+                               [ 'ar_id' => $arId ] + $conds,
+                               __METHOD__
+                       );
+                       $count += $dbw->affectedRows();
                }
+               return $count;
        }
 
        /**
@@ -123,31 +139,41 @@ class PopulateArchiveRevId extends LoggedUpdateMaintenance {
         *
         * The row will have a wildly unlikely timestamp, and possibly a generic
         * user and comment, but will otherwise be derived from a revision on the
-        * wiki's main page.
+        * wiki's main page or some other revision in the database.
         *
         * @param IDatabase $dbw
         * @return array
         */
-       private function makeDummyRevisionRow( IDatabase $dbw ) {
+       private static function makeDummyRevisionRow( IDatabase $dbw ) {
                $ts = $dbw->timestamp( '11111111111111' );
+               $rev = null;
+
                $mainPage = Title::newMainPage();
-               if ( !$mainPage ) {
-                       $this->fatalError( 'Main page does not exist' );
+               $pageId = $mainPage ? $mainPage->getArticleId() : null;
+               if ( $pageId ) {
+                       $rev = $dbw->selectRow(
+                               'revision',
+                               '*',
+                               [ 'rev_page' => $pageId ],
+                               __METHOD__,
+                               [ 'ORDER BY' => 'rev_timestamp ASC' ]
+                       );
                }
-               $pageId = $mainPage->getArticleId();
-               if ( !$pageId ) {
-                       $this->fatalError( $mainPage->getPrefixedText() . ' has no ID' );
+
+               if ( !$rev ) {
+                       // No main page? Let's see if there are any revisions at all
+                       $rev = $dbw->selectRow(
+                               'revision',
+                               '*',
+                               [],
+                               __METHOD__,
+                               [ 'ORDER BY' => 'rev_timestamp ASC' ]
+                       );
                }
-               $rev = $dbw->selectRow(
-                       'revision',
-                       '*',
-                       [ 'rev_page' => $pageId ],
-                       __METHOD__,
-                       [ 'ORDER BY' => 'rev_timestamp ASC' ]
-               );
                if ( !$rev ) {
-                       $this->fatalError( $mainPage->getPrefixedText() . ' has no revisions' );
+                       throw new UnexpectedValueException( 'No revisions are available to copy' );
                }
+
                unset( $rev->rev_id );
                $rev = (array)$rev;
                $rev['rev_timestamp'] = $ts;
@@ -166,7 +192,7 @@ class PopulateArchiveRevId extends LoggedUpdateMaintenance {
                        __METHOD__
                );
                if ( $any ) {
-                       $this->fatalError( "... Why does your database contain a revision dated $ts?" );
+                       throw new UnexpectedValueException( "... Why does your database contain a revision dated $ts?" );
                }
 
                return $rev;
diff --git a/maintenance/populateExternallinksIndex60.php b/maintenance/populateExternallinksIndex60.php
new file mode 100644 (file)
index 0000000..9b029fe
--- /dev/null
@@ -0,0 +1,89 @@
+<?php
+/**
+ * Populates the el_index_60 field in the externallinks table.
+ *
+ * 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 populates the el_index_60 field in the externallinks
+ * table.
+ *
+ * @ingroup Maintenance
+ * @since 1.32
+ */
+class PopulateExternallinksIndex60 extends LoggedUpdateMaintenance {
+       public function __construct() {
+               parent::__construct();
+               $this->addDescription(
+                       'Populates the el_index_60 field in the externallinks table' );
+               $this->setBatchSize( 200 );
+       }
+
+       protected function getUpdateKey() {
+               return 'populate externallinks.el_index_60';
+       }
+
+       protected function updateSkippedMessage() {
+               return 'externallinks.el_index_60 already populated.';
+       }
+
+       protected function doDBUpdates() {
+               $dbw = $this->getDB( DB_MASTER );
+               $this->output( "Populating externallinks.el_index_60...\n" );
+
+               $count = 0;
+               $start = 0;
+               $last = $dbw->selectField( 'externallinks', 'MAX(el_id)', '', __METHOD__ );
+               while ( $start <= $last ) {
+                       $end = $start + $this->mBatchSize;
+                       $this->output( "el_id $start - $end of $last\n" );
+                       $res = $dbw->select( 'externallinks', [ 'el_id', 'el_index' ],
+                               [
+                                       "el_id > $start",
+                                       "el_id <= $end",
+                                       'el_index_60' => '',
+                               ],
+                               __METHOD__,
+                               [ 'ORDER BY' => 'el_id' ]
+                       );
+                       foreach ( $res as $row ) {
+                               $count++;
+                               $dbw->update( 'externallinks',
+                                       [
+                                               'el_index_60' => substr( $row->el_index, 0, 60 ),
+                                       ],
+                                       [
+                                               'el_id' => $row->el_id,
+                                       ], __METHOD__, [ 'IGNORE' ]
+                               );
+                       }
+                       wfWaitForSlaves();
+                       $start = $end;
+               }
+               $this->output( "Done, $count rows updated.\n" );
+
+               return true;
+       }
+}
+
+$maintClass = "PopulateExternallinksIndex60";
+require_once RUN_MAINTENANCE_IF_MAIN;
index 1a53359..cf0eb2f 100644 (file)
@@ -373,7 +373,7 @@ CREATE TABLE externallinks (
   el_from     INTEGER     NOT NULL  REFERENCES page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
   el_to       TEXT        NOT NULL,
   el_index    TEXT        NOT NULL,
-  el_index_60 BYTEA       NOT NULL  DEFAULT ''
+  el_index_60 BYTEA       NOT NULL
 );
 ALTER SEQUENCE externallinks_el_id_seq OWNED BY externallinks.el_id;
 CREATE INDEX externallinks_from_to ON externallinks (el_from,el_to);
@@ -807,13 +807,15 @@ CREATE TABLE change_tag (
   ct_log_id  INTEGER      NULL,
   ct_rev_id  INTEGER      NULL,
   ct_tag     TEXT     NOT NULL,
-  ct_params  TEXT         NULL
+  ct_params  TEXT         NULL,
+  ct_tag_id  INTEGER      NULL
 );
 ALTER SEQUENCE change_tag_ct_id_seq OWNED BY change_tag.ct_id;
 CREATE UNIQUE INDEX change_tag_rc_tag ON change_tag(ct_rc_id,ct_tag);
 CREATE UNIQUE INDEX change_tag_log_tag ON change_tag(ct_log_id,ct_tag);
 CREATE UNIQUE INDEX change_tag_rev_tag ON change_tag(ct_rev_id,ct_tag);
 CREATE INDEX change_tag_tag_id ON change_tag(ct_tag,ct_rc_id,ct_rev_id,ct_log_id);
+CREATE INDEX change_tag_tag_id_id ON change_tag(ct_tag_id,ct_rc_id,ct_rev_id,ct_log_id);
 
 CREATE SEQUENCE tag_summary_ts_id_seq;
 CREATE TABLE tag_summary (
index 4458901..d90a4a7 100644 (file)
@@ -20,7 +20,7 @@
  * @file
  * @ingroup Maintenance
  * @author Rob Church <robchur@gmail.com>
- * @license GNU General Public Licence 2.0 or later
+ * @license GPL-2.0-or-later
  */
 
 use Wikimedia\Rdbms\IDatabase;
index 231001d..889ab42 100755 (executable)
@@ -43,15 +43,15 @@ rm -r "$REPO_DIR/$TARGET_DIR"
 
 # Core and thematic code and styling
 mkdir -p "$REPO_DIR/$TARGET_DIR"
-cp ./node_modules/oojs-ui/dist/oojs-ui-core.js{,.map} "$REPO_DIR/$TARGET_DIR"
+cp ./node_modules/oojs-ui/dist/oojs-ui-core.js{,.map.json} "$REPO_DIR/$TARGET_DIR"
 cp ./node_modules/oojs-ui/dist/oojs-ui-core-{wikimediaui,apex}.css "$REPO_DIR/$TARGET_DIR"
-cp ./node_modules/oojs-ui/dist/oojs-ui-widgets.js{,.map} "$REPO_DIR/$TARGET_DIR"
+cp ./node_modules/oojs-ui/dist/oojs-ui-widgets.js{,.map.json} "$REPO_DIR/$TARGET_DIR"
 cp ./node_modules/oojs-ui/dist/oojs-ui-widgets-{wikimediaui,apex}.css "$REPO_DIR/$TARGET_DIR"
-cp ./node_modules/oojs-ui/dist/oojs-ui-toolbars.js{,.map} "$REPO_DIR/$TARGET_DIR"
+cp ./node_modules/oojs-ui/dist/oojs-ui-toolbars.js{,.map.json} "$REPO_DIR/$TARGET_DIR"
 cp ./node_modules/oojs-ui/dist/oojs-ui-toolbars-{wikimediaui,apex}.css "$REPO_DIR/$TARGET_DIR"
-cp ./node_modules/oojs-ui/dist/oojs-ui-windows.js{,.map} "$REPO_DIR/$TARGET_DIR"
+cp ./node_modules/oojs-ui/dist/oojs-ui-windows.js{,.map.json} "$REPO_DIR/$TARGET_DIR"
 cp ./node_modules/oojs-ui/dist/oojs-ui-windows-{wikimediaui,apex}.css "$REPO_DIR/$TARGET_DIR"
-cp ./node_modules/oojs-ui/dist/oojs-ui-{wikimediaui,apex}.js{,.map} "$REPO_DIR/$TARGET_DIR"
+cp ./node_modules/oojs-ui/dist/oojs-ui-{wikimediaui,apex}.js{,.map.json} "$REPO_DIR/$TARGET_DIR"
 
 # i18n
 mkdir -p "$REPO_DIR/$TARGET_DIR/i18n"
index 64eca95..39a5c5f 100644 (file)
@@ -32,7 +32,7 @@ use Wikimedia\Rdbms\IDatabase;
  *
  * @ingroup Maintenance
  */
-class BatchedQueryRunner extends Maintenance {
+class RunBatchedQuery extends Maintenance {
        public function __construct() {
                parent::__construct();
                $this->addDescription(
@@ -111,5 +111,5 @@ class BatchedQueryRunner extends Maintenance {
        }
 }
 
-$maintClass = BatchedQueryRunner::class;
+$maintClass = RunBatchedQuery::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index 08f009b..1adb13e 100644 (file)
@@ -26,7 +26,7 @@
  * @author Brion Vibber
  * @author Rob Church <robchur@gmail.com>
  *
- * @license GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  */
 
 require_once __DIR__ . '/Maintenance.php';
diff --git a/maintenance/sqlite/archives/patch-externallinks-el_index_60-drop-default.sql b/maintenance/sqlite/archives/patch-externallinks-el_index_60-drop-default.sql
new file mode 100644 (file)
index 0000000..1d82f4d
--- /dev/null
@@ -0,0 +1,21 @@
+-- To change the default on one column, sqlite requires we copy the whole table
+
+CREATE TABLE /*_*/externallinks_tmp (
+  el_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
+  el_from int unsigned NOT NULL default 0,
+  el_to blob NOT NULL,
+  el_index blob NOT NULL,
+  el_index_60 varbinary(60) NOT NULL
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/externallinks_tmp
+       SELECT el_id, el_from, el_to, el_index, el_index_60 FROM /*_*/externallinks;
+
+DROP TABLE /*_*/externallinks;
+ALTER TABLE /*_*/externallinks_tmp RENAME TO /*_*/externallinks;
+
+CREATE INDEX /*i*/el_from ON /*_*/externallinks (el_from, el_to(40));
+CREATE INDEX /*i*/el_to ON /*_*/externallinks (el_to(60), el_from);
+CREATE INDEX /*i*/el_index ON /*_*/externallinks (el_index(60));
+CREATE INDEX /*i*/el_index_60 ON /*_*/externallinks (el_index_60, el_id);
+CREATE INDEX /*i*/el_from_index_60 ON /*_*/externallinks (el_from, el_index_60, el_id);
index a67e261..a9b9b9e 100644 (file)
@@ -104,7 +104,7 @@ class CompressOld extends Maintenance {
                global $wgDBname;
                if ( !function_exists( "gzdeflate" ) ) {
                        $this->fatalError( "You must enable zlib support in PHP to compress old revisions!\n" .
-                               "Please see http://www.php.net/manual/en/ref.zlib.php\n" );
+                               "Please see https://secure.php.net/manual/en/ref.zlib.php\n" );
                }
 
                $type = $this->getOption( 'type', 'concat' );
index 34c63ed..53c1529 100644 (file)
@@ -932,8 +932,7 @@ CREATE TABLE /*_*/externallinks (
 
   -- This is el_index truncated to 60 bytes to allow for sortable queries that
   -- aren't supported by a partial index.
-  -- @todo Drop the default once this is deployed everywhere and code is populating it.
-  el_index_60 varbinary(60) NOT NULL default ''
+  el_index_60 varbinary(60) NOT NULL
 ) /*$wgDBTableOptions*/;
 
 -- Forward index, for page edit, save
@@ -1843,10 +1842,12 @@ CREATE TABLE /*_*/change_tag (
   ct_log_id int unsigned NULL,
   -- REVID for the change
   ct_rev_id int unsigned NULL,
-  -- Tag applied
+  -- Tag applied, this will go away and be replaced with ct_tag_id
   ct_tag varchar(255) NOT NULL,
   -- Parameters for the tag; used by some extensions
-  ct_params blob NULL
+  ct_params blob NULL,
+  -- Foreign key to change_tag_def row, this will be "NOT NULL" once populated
+  ct_tag_id int unsigned NULL
 ) /*$wgDBTableOptions*/;
 
 CREATE UNIQUE INDEX /*i*/change_tag_rc_tag ON /*_*/change_tag (ct_rc_id,ct_tag);
@@ -1854,7 +1855,7 @@ CREATE UNIQUE INDEX /*i*/change_tag_log_tag ON /*_*/change_tag (ct_log_id,ct_tag
 CREATE UNIQUE INDEX /*i*/change_tag_rev_tag ON /*_*/change_tag (ct_rev_id,ct_tag);
 -- Covering index, so we can pull all the info only out of the index.
 CREATE INDEX /*i*/change_tag_tag_id ON /*_*/change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id);
-
+CREATE INDEX /*i*/change_tag_tag_id_id ON /*_*/change_tag (ct_tag_id,ct_rc_id,ct_rev_id,ct_log_id);
 
 -- Rollup table to pull a LIST of tags simply without ugly GROUP_CONCAT
 -- that only works on MySQL 4.1+
index bb62067..99290f4 100644 (file)
@@ -73,7 +73,9 @@
 
                // Hide "other" textboxes by default
                // Should not be done in CSS for javascript disabled compatibility
-               $( '.enabledByOther' ).closest( '.config-block' ).hide();
+               if ( !$( '#config__NamespaceType_other' ).is( ':checked' ) ) {
+                       $( '.enabledByOther' ).closest( '.config-block' ).hide();
+               }
 
                // Enable/disable "other" textboxes
                $( '.enableForOther' ).click( function () {
index b9b2161..b92ff2e 100644 (file)
@@ -46,8 +46,8 @@ $response->header( 'Cache-control: max-age=600' );
 print '<?xml version="1.0"?>';
 print Xml::openElement( 'OpenSearchDescription',
        [
-               'xmlns' => 'http://a9.com/-/spec/opensearch/1.1/',
-               'xmlns:moz' => 'http://www.mozilla.org/2006/browser/search/' ] );
+               'xmlns' => 'http://www.opensearch.org/Specifications/OpenSearch/1.1',
+               'xmlns:moz' => 'https://www.mozilla.org/2006/browser/search/' ] );
 
 /* The spec says the ShortName must be no longer than 16 characters,
  * but 16 is *realllly* short. In practice, browsers don't appear to care
index e9048ec..1f23b1a 100644 (file)
     "grunt": "1.0.1",
     "grunt-banana-checker": "0.6.0",
     "grunt-contrib-copy": "1.0.0",
-    "grunt-contrib-watch": "1.0.0",
+    "grunt-contrib-watch": "1.0.1",
     "grunt-eslint": "20.1.0",
     "grunt-jsonlint": "1.1.0",
     "grunt-karma": "2.0.0",
     "grunt-stylelint": "0.10.0",
-    "karma": "1.7.1",
+    "karma": "2.0.2",
     "karma-chrome-launcher": "2.2.0",
     "karma-firefox-launcher": "1.0.1",
     "karma-mocha-reporter": "2.2.5",
     "karma-qunit": "2.0.1",
     "postcss-less": "1.1.5",
-    "qunit": "2.5.0",
+    "qunit": "2.6.0",
     "stylelint": "9.2.0",
     "stylelint-config-wikimedia": "0.4.3",
     "wdio-junit-reporter": "0.2.0",
     "wdio-mediawiki": "file:tests/selenium/wdio-mediawiki",
-    "wdio-mocha-framework": "0.5.8",
+    "wdio-mocha-framework": "0.5.13",
     "wdio-sauce-service": "0.3.1",
     "wdio-spec-reporter": "0.0.5",
     "webdriverio": "4.12.0"
index 0fe5dd7..e624dc3 100644 (file)
@@ -136,7 +136,7 @@ return [
 
        'mediawiki.skinning.content.externallinks' => [
                'styles' => [
-                       'resources/src/mediawiki.skinning/content.externallinks.css' => [ 'media' => 'screen' ],
+                       'resources/src/mediawiki.skinning/content.externallinks.less' => [ 'media' => 'screen' ],
                ],
        ],
 
@@ -216,15 +216,6 @@ return [
        'jquery.expandableField' => [
                'scripts' => 'resources/src/jquery/jquery.expandableField.js',
        ],
-       'jquery.farbtastic' => [
-               'scripts' => 'resources/src/jquery/jquery.farbtastic.js',
-               'styles' => 'resources/src/jquery/jquery.farbtastic.css',
-               'dependencies' => 'jquery.colorUtil',
-       ],
-       'jquery.footHovzer' => [
-               'scripts' => 'resources/src/jquery/jquery.footHovzer.js',
-               'styles' => 'resources/src/jquery/jquery.footHovzer.css',
-       ],
        'jquery.form' => [
                'scripts' => 'resources/lib/jquery/jquery.form.js',
        ],
@@ -307,8 +298,8 @@ return [
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'jquery.spinner' => [
-               'scripts' => 'resources/src/jquery/jquery.spinner.js',
-               'styles' => 'resources/src/jquery/jquery.spinner.css',
+               'scripts' => 'resources/src/jquery.spinner/spinner.js',
+               'styles' => 'resources/src/jquery.spinner/spinner.css',
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'jquery.jStorage' => [
@@ -325,6 +316,7 @@ return [
                'scripts' => 'resources/src/jquery/jquery.tabIndex.js',
        ],
        'jquery.tablesorter' => [
+               'targets' => [ 'desktop', 'mobile' ],
                'scripts' => 'resources/src/jquery.tablesorter/jquery.tablesorter.js',
                'styles' => 'resources/src/jquery.tablesorter/jquery.tablesorter.less',
                'messages' => [ 'sort-descending', 'sort-ascending' ],
@@ -894,75 +886,73 @@ return [
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.api' => [
-               'scripts' => 'resources/src/mediawiki.api.js',
+               'scripts' => [
+                       'resources/src/mediawiki.api/index.js',
+                       'resources/src/mediawiki.api/category.js',
+                       'resources/src/mediawiki.api/edit.js',
+                       'resources/src/mediawiki.api/login.js',
+                       'resources/src/mediawiki.api/messages.js',
+                       'resources/src/mediawiki.api/options.js',
+                       'resources/src/mediawiki.api/parse.js',
+                       'resources/src/mediawiki.api/rollback.js',
+                       'resources/src/mediawiki.api/upload.js',
+                       'resources/src/mediawiki.api/user.js',
+                       'resources/src/mediawiki.api/watch.js',
+               ],
                'dependencies' => [
+                       'mediawiki.Title',
                        'mediawiki.util',
                        'user.tokens',
                ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.api.category' => [
-               'scripts' => 'resources/src/mediawiki.api.category.js',
-               'dependencies' => [
-                       'mediawiki.api',
-                       'mediawiki.Title',
-               ],
+               'deprecated' => 'Use "mediawiki.api" instead.',
+               'dependencies' => 'mediawiki.api',
        ],
        'mediawiki.api.edit' => [
-               'scripts' => 'resources/src/mediawiki.api.edit.js',
+               'deprecated' => 'Use "mediawiki.api" instead.',
                'dependencies' => [
                        'mediawiki.api',
-                       'mediawiki.user',
                ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.api.login' => [
-               'scripts' => 'resources/src/mediawiki.api.login.js',
+               'deprecated' => 'Use "mediawiki.api" instead.',
                'dependencies' => 'mediawiki.api',
        ],
        'mediawiki.api.options' => [
-               'scripts' => 'resources/src/mediawiki.api.options.js',
+               'deprecated' => 'Use "mediawiki.api" instead.',
                'dependencies' => 'mediawiki.api',
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.api.parse' => [
-               'scripts' => 'resources/src/mediawiki.api.parse.js',
+               'deprecated' => 'Use "mediawiki.api" instead.',
                'dependencies' => 'mediawiki.api',
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.api.upload' => [
-               'scripts' => 'resources/src/mediawiki.api.upload.js',
-               'dependencies' => [
-                       'mediawiki.api',
-                       'mediawiki.api.edit',
-               ],
+               'deprecated' => 'Use "mediawiki.api" instead.',
+               'dependencies' => 'mediawiki.api',
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.api.user' => [
-               'scripts' => 'resources/src/mediawiki.api.user.js',
-               'dependencies' => [
-                       'mediawiki.api',
-               ],
+               'deprecated' => 'Use "mediawiki.api" instead.',
+               'dependencies' => 'mediawiki.api',
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.api.watch' => [
-               'scripts' => 'resources/src/mediawiki.api.watch.js',
-               'dependencies' => [
-                       'mediawiki.api',
-               ],
+               'deprecated' => 'Use "mediawiki.api" instead.',
+               'dependencies' => 'mediawiki.api',
        ],
        'mediawiki.api.messages' => [
-               'scripts' => 'resources/src/mediawiki.api.messages.js',
-               'dependencies' => [
-                       'mediawiki.api',
-               ],
+               'deprecated' => 'Use "mediawiki.api" instead.',
+               'dependencies' => 'mediawiki.api',
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.api.rollback' => [
-               'scripts' => 'resources/src/mediawiki.api.rollback.js',
-               'dependencies' => [
-                       'mediawiki.api',
-               ],
+               'deprecated' => 'Use "mediawiki.api" instead.',
+               'dependencies' => 'mediawiki.api',
        ],
        'mediawiki.content.json' => [
                'styles' => 'resources/src/mediawiki.content.json.less',
@@ -975,13 +965,14 @@ return [
        ],
        'mediawiki.debug' => [
                'scripts' => [
+                       'resources/src/mediawiki.debug/jquery.footHovzer.js',
                        'resources/src/mediawiki.debug/debug.js',
                ],
                'styles' => [
+                       'resources/src/mediawiki.debug/jquery.footHovzer.css',
                        'resources/src/mediawiki.debug/debug.less',
                ],
                'dependencies' => [
-                       'jquery.footHovzer',
                        'oojs-ui-core',
                ],
        ],
@@ -1153,7 +1144,7 @@ return [
                        'resources/src/mediawiki.messagePoster.wikitext/WikitextMessagePoster.js',
                ],
                'dependencies' => [
-                       'mediawiki.api.edit',
+                       'mediawiki.api',
                        'mediawiki.messagePoster',
                ],
                'targets' => [ 'desktop', 'mobile' ],
@@ -1234,7 +1225,7 @@ return [
        'mediawiki.Upload' => [
                'scripts' => 'resources/src/mediawiki.Upload.js',
                'dependencies' => [
-                       'mediawiki.api.upload',
+                       'mediawiki.api',
                ],
        ],
        'mediawiki.ForeignUpload' => [
@@ -1334,7 +1325,7 @@ return [
                        'mediawiki.widgets.CategoryMultiselectWidget',
                        'mediawiki.widgets.DateInputWidget',
                        'mediawiki.jqueryMsg',
-                       'mediawiki.api.messages',
+                       'mediawiki.api',
                        'moment',
                        'mediawiki.libs.jpegmeta',
                ],
@@ -1375,7 +1366,6 @@ return [
                'scripts' => 'resources/src/mediawiki.user.js',
                'dependencies' => [
                        'mediawiki.api',
-                       'mediawiki.api.user',
                        'mediawiki.storage',
                        'user.options',
                        'user.tokens',
@@ -1655,6 +1645,7 @@ return [
        ],
 
        'mediawiki.language.months' => [
+               'targets' => [ 'desktop', 'mobile' ],
                'scripts' => 'resources/src/mediawiki.language/mediawiki.language.months.js',
                'dependencies' => 'mediawiki.language',
                'messages' => array_merge(
@@ -1743,7 +1734,7 @@ return [
        'mediawiki.page.watch.ajax' => [
                'scripts' => 'resources/src/mediawiki.page.watch.ajax.js',
                'dependencies' => [
-                       'mediawiki.api.watch',
+                       'mediawiki.api',
                        'mediawiki.notify',
                        'mediawiki.util',
                        'mediawiki.Title',
@@ -1768,7 +1759,7 @@ return [
        'mediawiki.page.rollback' => [
                'scripts' => 'resources/src/mediawiki.page.rollback.js',
                'dependencies' => [
-                       'mediawiki.api.rollback',
+                       'mediawiki.api',
                        'mediawiki.notify',
                        'mediawiki.util',
                        'jquery.spinner',
@@ -1816,7 +1807,6 @@ return [
                        'mediawiki.String',
                        'oojs',
                        'mediawiki.api',
-                       'mediawiki.api.options',
                        'mediawiki.jqueryMsg',
                        'mediawiki.Uri',
                        'mediawiki.user',
@@ -1998,18 +1988,21 @@ return [
        ],
        'mediawiki.special' => [
                'styles' => [
-                       'resources/src/mediawiki.special/mediawiki.special.css',
-                       'resources/src/mediawiki.special/mediawiki.special.userrights.css',
+                       'resources/src/mediawiki.special/special.css',
+                       'resources/src/mediawiki.special/apisandbox.css',
+                       'resources/src/mediawiki.special/comparepages.less',
+                       'resources/src/mediawiki.special/edittags.css',
+                       'resources/src/mediawiki.special/movePage.css',
+                       'resources/src/mediawiki.special/pagesWithProp.css',
+                       'resources/src/mediawiki.special/upload.css',
+                       'resources/src/mediawiki.special/userrights.css',
+                       'resources/src/mediawiki.special/watchlist.css',
                ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
-       'mediawiki.special.apisandbox.styles' => [
-               'targets' => [ 'desktop', 'mobile' ],
-               'styles' => 'resources/src/mediawiki.special/mediawiki.special.apisandbox.top.css',
-       ],
        'mediawiki.special.apisandbox' => [
-               'styles' => 'resources/src/mediawiki.special/mediawiki.special.apisandbox.css',
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.apisandbox.js',
+               'styles' => 'resources/src/mediawiki.special.apisandbox/apisandbox.css',
+               'scripts' => 'resources/src/mediawiki.special.apisandbox/apisandbox.js',
                'targets' => [ 'desktop', 'mobile' ],
                'dependencies' => [
                        'mediawiki.api',
@@ -2038,6 +2031,7 @@ return [
                        'apisandbox-dynamic-parameters-add-label',
                        'apisandbox-dynamic-parameters-add-placeholder',
                        'apisandbox-dynamic-error-exists',
+                       'apisandbox-templated-parameter-reason',
                        'apisandbox-deprecated-parameters',
                        'apisandbox-no-parameters',
                        'api-help-param-limit',
@@ -2074,10 +2068,13 @@ return [
                        'apisandbox-multivalue-all-values',
                        'api-format-prettyprint-status',
                        'blanknamespace',
+                       'comma-separator',
+                       'word-separator',
+                       'and'
                ],
        ],
        'mediawiki.special.block' => [
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.block.js',
+               'scripts' => 'resources/src/mediawiki.special.block.js',
                'dependencies' => [
                        'oojs-ui-core',
                        'oojs-ui.styles.icons-editing-core',
@@ -2090,7 +2087,7 @@ return [
                ],
        ],
        'mediawiki.special.changecredentials.js' => [
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.changecredentials.js',
+               'scripts' => 'resources/src/mediawiki.special.changecredentials.js',
                'dependencies' => [
                        'mediawiki.api',
                        'mediawiki.htmlform.ooui'
@@ -2098,39 +2095,33 @@ return [
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.special.changeslist' => [
-               'styles' => 'resources/src/mediawiki.special/mediawiki.special.changeslist.css',
+               'styles' => 'resources/src/mediawiki.special.changeslist.css',
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.special.changeslist.enhanced' => [
-               'styles' => 'resources/src/mediawiki.special/mediawiki.special.changeslist.enhanced.css',
+               'styles' => 'resources/src/mediawiki.special.changeslist.enhanced.css',
        ],
        'mediawiki.special.changeslist.legend' => [
-               'styles' => 'resources/src/mediawiki.special/mediawiki.special.changeslist.legend.css',
+               'styles' => 'resources/src/mediawiki.special.changeslist.legend.css',
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.special.changeslist.legend.js' => [
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.changeslist.legend.js',
+               'scripts' => 'resources/src/mediawiki.special.changeslist.legend.js',
                'dependencies' => [
                        'jquery.makeCollapsible',
                        'mediawiki.cookie',
                ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
-       'mediawiki.special.changeslist.visitedstatus' => [
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.changeslist.visitedstatus.js',
-       ],
-       'mediawiki.special.comparepages.styles' => [
-               'styles' => 'resources/src/mediawiki.special/mediawiki.special.comparepages.styles.less',
-       ],
        'mediawiki.special.contributions' => [
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.contributions.js',
+               'scripts' => 'resources/src/mediawiki.special.contributions.js',
                'dependencies' => [
                        'mediawiki.widgets.DateInputWidget',
                        'mediawiki.jqueryMsg',
                ]
        ],
        'mediawiki.special.edittags' => [
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.edittags.js',
+               'scripts' => 'resources/src/mediawiki.special.edittags.js',
                'dependencies' => [
                        'jquery.chosen',
                        'jquery.lengthLimit',
@@ -2140,39 +2131,30 @@ return [
                        'tags-edit-chosen-no-results',
                ],
        ],
-       'mediawiki.special.edittags.styles' => [
-               'styles' => 'resources/src/mediawiki.special/mediawiki.special.edittags.css',
-       ],
        'mediawiki.special.import' => [
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.import.js',
+               'scripts' => 'resources/src/mediawiki.special.import.js',
        ],
        'mediawiki.special.movePage' => [
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.movePage.js',
+               'scripts' => 'resources/src/mediawiki.special.movePage.js',
                'dependencies' => [
                        'mediawiki.widgets.visibleLengthLimit',
                        'mediawiki.widgets',
                ],
        ],
-       'mediawiki.special.movePage.styles' => [
-               'styles' => 'resources/src/mediawiki.special/mediawiki.special.movePage.css',
-       ],
        'mediawiki.special.pageLanguage' => [
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.pageLanguage.js',
+               'scripts' => 'resources/src/mediawiki.special.pageLanguage.js',
                'dependencies' => [
                        'oojs-ui-core',
                ],
        ],
-       'mediawiki.special.pagesWithProp' => [
-               'styles' => 'resources/src/mediawiki.special/mediawiki.special.pagesWithProp.css',
-       ],
        'mediawiki.special.preferences' => [
                'targets' => [ 'desktop', 'mobile' ],
                'scripts' => [
-                       'resources/src/mediawiki.special/mediawiki.special.preferences.confirmClose.js',
-                       'resources/src/mediawiki.special/mediawiki.special.preferences.convertmessagebox.js',
-                       'resources/src/mediawiki.special/mediawiki.special.preferences.tabs.legacy.js',
-                       'resources/src/mediawiki.special/mediawiki.special.preferences.timezone.js',
-                       'resources/src/mediawiki.special/mediawiki.special.preferences.personalEmail.js',
+                       'resources/src/mediawiki.special.preferences/confirmClose.js',
+                       'resources/src/mediawiki.special.preferences/convertmessagebox.js',
+                       'resources/src/mediawiki.special.preferences/tabs.legacy.js',
+                       'resources/src/mediawiki.special.preferences/timezone.js',
+                       'resources/src/mediawiki.special.preferences/personalEmail.js',
                ],
                'messages' => [
                        'prefs-tabs-navigation-hint',
@@ -2188,17 +2170,19 @@ return [
        ],
        'mediawiki.special.preferences.styles' => [
                'targets' => [ 'desktop', 'mobile' ],
-               'styles' => 'resources/src/mediawiki.special/mediawiki.special.preferences.styles.legacy.css',
+               // legacy
+               'styles' => 'resources/src/mediawiki.special.preferences.styles.css',
        ],
        'mediawiki.special.preferences.ooui' => [
                'targets' => [ 'desktop', 'mobile' ],
                'scripts' => [
-                       'resources/src/mediawiki.special/mediawiki.special.preferences.confirmClose.js',
-                       'resources/src/mediawiki.special/mediawiki.special.preferences.convertmessagebox.js',
-                       'resources/src/mediawiki.special/mediawiki.special.preferences.editfont.js',
-                       'resources/src/mediawiki.special/mediawiki.special.preferences.tabs.js',
-                       'resources/src/mediawiki.special/mediawiki.special.preferences.timezone.js',
-                       'resources/src/mediawiki.special/mediawiki.special.preferences.personalEmail.js',
+                       // FIXME: This uses files already belonging to another module
+                       'resources/src/mediawiki.special.preferences/confirmClose.js',
+                       'resources/src/mediawiki.special.preferences/convertmessagebox.js',
+                       'resources/src/mediawiki.special.preferences.ooui/editfont.js',
+                       'resources/src/mediawiki.special.preferences.ooui/tabs.js',
+                       'resources/src/mediawiki.special.preferences/timezone.js',
+                       'resources/src/mediawiki.special.preferences/personalEmail.js',
                ],
                'messages' => [
                        'prefs-tabs-navigation-hint',
@@ -2217,14 +2201,14 @@ return [
        ],
        'mediawiki.special.preferences.styles.ooui' => [
                'targets' => [ 'desktop', 'mobile' ],
-               'styles' => 'resources/src/mediawiki.special/mediawiki.special.preferences.styles.css',
+               'styles' => 'resources/src/mediawiki.special.preferences.styles.ooui.css',
        ],
        'mediawiki.special.recentchanges' => [
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.recentchanges.js',
+               'scripts' => 'resources/src/mediawiki.special.recentchanges.js',
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.special.revisionDelete' => [
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.revisionDelete.js',
+               'scripts' => 'resources/src/mediawiki.special.revisionDelete.js',
                'messages' => [
                        // @todo Load this message in content language
                        'colon-separator',
@@ -2235,8 +2219,8 @@ return [
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.special.search' => [
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.search.js',
-               'styles' => 'resources/src/mediawiki.special/mediawiki.special.search.css',
+               'scripts' => 'resources/src/mediawiki.special.search/search.js',
+               'styles' => 'resources/src/mediawiki.special.search/search.css',
                'dependencies' => 'mediawiki.widgets.SearchInputWidget',
                'messages' => [
                        'powersearch-togglelabel',
@@ -2245,7 +2229,7 @@ return [
                ],
        ],
        'mediawiki.special.search.commonsInterwikiWidget' => [
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.search.commonsInterwikiWidget.js',
+               'scripts' => 'resources/src/mediawiki.special.search.commonsInterwikiWidget.js',
                'dependencies' => [
                        'mediawiki.api',
                        'mediawiki.Uri',
@@ -2258,24 +2242,23 @@ return [
                ],
        ],
        'mediawiki.special.search.interwikiwidget.styles' => [
-               'styles' => 'resources/src/mediawiki.special/'
-                       . 'mediawiki.special.search.interwikiwidget.styles.less',
+               'styles' => 'resources/src/mediawiki.special.search.interwikiwidget.styles.less',
                'targets' => [ 'desktop', 'mobile' ]
        ],
        'mediawiki.special.search.styles' => [
-               'styles' => 'resources/src/mediawiki.special/mediawiki.special.search.styles.css',
+               'styles' => 'resources/src/mediawiki.special.search.styles.css',
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.special.undelete' => [
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.undelete.js',
+               'scripts' => 'resources/src/mediawiki.special.undelete.js',
                'dependencies' => [
                        'mediawiki.widgets.visibleLengthLimit',
                        'mediawiki.widgets',
                ],
        ],
        'mediawiki.special.unwatchedPages' => [
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.unwatchedPages.js',
-               'styles' => 'resources/src/mediawiki.special/mediawiki.special.unwatchedPages.css',
+               'scripts' => 'resources/src/mediawiki.special.unwatchedPages/unwatchedPages.js',
+               'styles' => 'resources/src/mediawiki.special.unwatchedPages/unwatchedPages.css',
                'messages' => [
                        'addedwatchtext-short',
                        'removedwatchtext-short',
@@ -2287,7 +2270,6 @@ return [
                ],
                'dependencies' => [
                        'mediawiki.api',
-                       'mediawiki.api.watch',
                        'mediawiki.notify',
                        'mediawiki.Title',
                        'mediawiki.util',
@@ -2295,9 +2277,9 @@ return [
        ],
        'mediawiki.special.upload' => [
                'templates' => [
-                       'thumbnail.html' => 'resources/src/mediawiki.special/templates/thumbnail.html',
+                       'thumbnail.html' => 'resources/src/mediawiki.special.upload/templates/thumbnail.html',
                ],
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.upload.js',
+               'scripts' => 'resources/src/mediawiki.special.upload/upload.js',
                'messages' => [
                        'widthheight',
                        'size-bytes',
@@ -2310,11 +2292,10 @@ return [
                        'prefs-editing',
                ],
                'dependencies' => [
-                       'mediawiki.special.upload.styles',
+                       'mediawiki.special',
                        'jquery.spinner',
                        'mediawiki.jqueryMsg',
                        'mediawiki.api',
-                       'mediawiki.api.parse',
                        'mediawiki.libs.jpegmeta',
                        'mediawiki.Title',
                        'mediawiki.util',
@@ -2322,22 +2303,19 @@ return [
                        'user.options',
                ],
        ],
-       'mediawiki.special.upload.styles' => [
-               'styles' => 'resources/src/mediawiki.special/mediawiki.special.upload.styles.css',
-       ],
        'mediawiki.special.userlogin.common.styles' => [
                'targets' => [ 'desktop', 'mobile' ],
                'skinStyles' => [
-                       'default' => 'resources/src/mediawiki.special/mediawiki.special.userlogin.common.css',
+                       'default' => 'resources/src/mediawiki.special.userlogin.common.styles/userlogin.css',
                ],
        ],
        'mediawiki.special.userlogin.login.styles' => [
                'styles' => [
-                       'resources/src/mediawiki.special/mediawiki.special.userlogin.login.css',
+                       'resources/src/mediawiki.special.userlogin.login.styles/login.css',
                ],
        ],
        'mediawiki.special.userlogin.signup.js' => [
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.userlogin.signup.js',
+               'scripts' => 'resources/src/mediawiki.special.userlogin.signup.js',
                'messages' => [
                        'createacct-emailrequired',
                        'noname',
@@ -2352,18 +2330,21 @@ return [
        ],
        'mediawiki.special.userlogin.signup.styles' => [
                'styles' => [
-                       'resources/src/mediawiki.special/mediawiki.special.userlogin.signup.css',
+                       'resources/src/mediawiki.special.userlogin.signup.styles/signup.css',
                ],
        ],
        'mediawiki.special.userrights' => [
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.userrights.js',
+               'scripts' => 'resources/src/mediawiki.special.userrights.js',
                'dependencies' => [
                        'mediawiki.notification.convertmessagebox',
                        'jquery.lengthLimit',
                ],
        ],
        'mediawiki.special.watchlist' => [
-               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.watchlist.js',
+               'scripts' => [
+                       'resources/src/mediawiki.special.watchlist/watchlist.js',
+                       'resources/src/mediawiki.special.watchlist/visitedstatus.js',
+               ],
                'messages' => [
                        'addedwatchtext',
                        'addedwatchtext-talk',
@@ -2375,7 +2356,7 @@ return [
                        'watchlist-unwatch-undo',
                ],
                'dependencies' => [
-                       'mediawiki.api.watch',
+                       'mediawiki.api',
                        'mediawiki.jqueryMsg',
                        'mediawiki.Title',
                        'mediawiki.util',
@@ -2383,11 +2364,8 @@ return [
                        'user.options',
                ],
        ],
-       'mediawiki.special.watchlist.styles' => [
-               'styles' => 'resources/src/mediawiki.special/mediawiki.special.watchlist.css',
-       ],
        'mediawiki.special.version' => [
-               'styles' => 'resources/src/mediawiki.special/mediawiki.special.version.css',
+               'styles' => 'resources/src/mediawiki.special.version.css',
        ],
 
        /* MediaWiki Installer */
@@ -2573,11 +2551,6 @@ return [
                ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
-       'mediawiki.widgets.visibleByteLimit' => [
-               'dependencies' => 'mediawiki.widgets.visibleLengthLimit',
-               'deprecated' => 'Use "mediawiki.widgets.visibleLengthLimit" instead.',
-               'targets' => [ 'desktop', 'mobile' ]
-       ],
        'mediawiki.widgets.visibleLengthLimit' => [
                'scripts' => [
                        'resources/src/mediawiki.widgets.visibleLengthLimit/mediawiki.widgets.visibleLengthLimit.js'
@@ -2797,12 +2770,6 @@ return [
                ],
        ],
 
-       /* es5-shim */
-       'es5-shim' => [
-               'deprecated' => 'Use of the "es5-shim" module is deprecated since MediaWiki 1.29.0',
-               'targets' => [ 'desktop', 'mobile' ],
-       ],
-
        /* dom-level2-shim */
        'dom-level2-shim' => [
                'deprecated' => 'Use of the "dom-level2-shim" module is deprecated since MediaWiki 1.29.0',
@@ -2902,9 +2869,9 @@ return [
        'oojs-ui-widgets' => [
                'class' => ResourceLoaderOOUIFileModule::class,
                'scripts' => 'resources/lib/oojs-ui/oojs-ui-widgets.js',
-               'themeStyles' => 'widgets',
                'dependencies' => [
                        'oojs-ui-core',
+                       'oojs-ui-widgets.styles',
                        'oojs-ui.styles.icons-interactions',
                        'oojs-ui.styles.icons-content',
                        'oojs-ui.styles.icons-editing-advanced',
@@ -2923,6 +2890,14 @@ return [
                ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
+       // You should never directly load this module. The CSS classes it defines are not a public API,
+       // they depend on the internal structure of OOUI widgets, which can change at any time. If you
+       // find that you need to load this module, you're probably doing something wrong or very hacky.
+       'oojs-ui-widgets.styles' => [
+               'class' => ResourceLoaderOOUIFileModule::class,
+               'themeStyles' => 'widgets',
+               'targets' => [ 'desktop', 'mobile' ],
+       ],
        // Toolbar and tools module.
        'oojs-ui-toolbars' => [
                'class' => ResourceLoaderOOUIFileModule::class,
diff --git a/resources/src/jquery.spinner/images/spinner-large.gif b/resources/src/jquery.spinner/images/spinner-large.gif
new file mode 100644 (file)
index 0000000..72203fd
Binary files /dev/null and b/resources/src/jquery.spinner/images/spinner-large.gif differ
diff --git a/resources/src/jquery.spinner/images/spinner.gif b/resources/src/jquery.spinner/images/spinner.gif
new file mode 100644 (file)
index 0000000..6146be4
Binary files /dev/null and b/resources/src/jquery.spinner/images/spinner.gif differ
diff --git a/resources/src/jquery.spinner/spinner.css b/resources/src/jquery.spinner/spinner.css
new file mode 100644 (file)
index 0000000..9c819a6
--- /dev/null
@@ -0,0 +1,36 @@
+.mw-spinner {
+       background-color: transparent;
+       background-position: center center;
+       background-repeat: no-repeat;
+}
+
+.mw-spinner-small {
+       /* @embed */
+       background-image: url( images/spinner.gif );
+       height: 20px;
+       width: 20px;
+       /* Avoid issues with .mw-spinner-block when floated without width. */
+       min-width: 20px;
+}
+
+.mw-spinner-large {
+       /* @embed */
+       background-image: url( images/spinner-large.gif );
+       height: 32px;
+       width: 32px;
+       /* Avoid issues with .mw-spinner-block when floated without width. */
+       min-width: 32px;
+}
+
+.mw-spinner-block {
+       display: block;
+       /* This overrides width from .mw-spinner-large / .mw-spinner-small,
+        * This is where the min-width kicks in.
+        */
+       width: 100%;
+}
+
+.mw-spinner-inline {
+       display: inline-block;
+       vertical-align: middle;
+}
diff --git a/resources/src/jquery.spinner/spinner.js b/resources/src/jquery.spinner/spinner.js
new file mode 100644 (file)
index 0000000..9079cc0
--- /dev/null
@@ -0,0 +1,114 @@
+/**
+ * jQuery Spinner
+ *
+ * Simple jQuery plugin to create, inject and remove spinners.
+ *
+ * @class jQuery.plugin.spinner
+ */
+( function ( $ ) {
+
+       // Default options for new spinners,
+       // stored outside the function to share between calls.
+       var defaults = {
+               id: undefined,
+               size: 'small',
+               type: 'inline'
+       };
+
+       $.extend( {
+               /**
+                * Create a spinner element
+                *
+                * The argument is an object with options used to construct the spinner (see below).
+                *
+                * It is a good practice to keep a reference to the created spinner to be able to remove it
+                * later. Alternatively, one can use the 'id' option and #removeSpinner (but make sure to choose
+                * an id that's unlikely to cause conflicts, e.g. with extensions, gadgets or user scripts).
+                *
+                * CSS classes used:
+                *
+                * - .mw-spinner for every spinner
+                * - .mw-spinner-small / .mw-spinner-large for size
+                * - .mw-spinner-block / .mw-spinner-inline for display types
+                *
+                * Example:
+                *
+                *     // Create a large spinner reserving all available horizontal space.
+                *     var $spinner = $.createSpinner( { size: 'large', type: 'block' } );
+                *     // Insert above page content.
+                *     $( '#mw-content-text' ).prepend( $spinner );
+                *
+                *     // Place a small inline spinner next to the "Save" button
+                *     var $spinner = $.createSpinner( { size: 'small', type: 'inline' } );
+                *     // Alternatively, just `$.createSpinner();` as these are the default options.
+                *     $( '#wpSave' ).after( $spinner );
+                *
+                *     // The following two are equivalent:
+                *     $.createSpinner( 'magic' );
+                *     $.createSpinner( { id: 'magic' } );
+                *
+                * @static
+                * @inheritable
+                * @param {Object|string} [opts] Options. If a string is given, it will be treated as the value
+                *   of the `id` option. If an object is given, the possible option keys are:
+                * @param {string} [opts.id] If given, spinner will be given an id of "mw-spinner-{id}".
+                * @param {string} [opts.size='small'] 'small' or 'large' for a 20-pixel or 32-pixel spinner.
+                * @param {string} [opts.type='inline'] 'inline' or 'block'. Inline creates an inline-block with
+                *   width and height equal to spinner size. Block is a block-level element with width 100%,
+                *   height equal to spinner size.
+                * @return {jQuery}
+                */
+               createSpinner: function ( opts ) {
+                       var $spinner;
+
+                       if ( opts !== undefined && $.type( opts ) !== 'object' ) {
+                               opts = {
+                                       id: opts
+                               };
+                       }
+
+                       opts = $.extend( {}, defaults, opts );
+
+                       $spinner = $( '<div>' ).addClass( 'mw-spinner' ).attr( 'title', '...' );
+                       if ( opts.id !== undefined ) {
+                               $spinner.attr( 'id', 'mw-spinner-' + opts.id );
+                       }
+
+                       $spinner.addClass( opts.size === 'large' ? 'mw-spinner-large' : 'mw-spinner-small' );
+                       $spinner.addClass( opts.type === 'block' ? 'mw-spinner-block' : 'mw-spinner-inline' );
+
+                       return $spinner;
+               },
+
+               /**
+                * Remove a spinner element
+                *
+                * @static
+                * @inheritable
+                * @param {string} id Id of the spinner, as passed to #createSpinner
+                * @return {jQuery} The (now detached) spinner element
+                */
+               removeSpinner: function ( id ) {
+                       return $( '#mw-spinner-' + id ).remove();
+               }
+       } );
+
+       /**
+        * Inject a spinner after each element in the collection
+        *
+        * Inserts spinner as siblings (not children) of the target elements.
+        * Collection contents remain unchanged.
+        *
+        * @param {Object|string} [opts] See #createSpinner
+        * @return {jQuery}
+        */
+       $.fn.injectSpinner = function ( opts ) {
+               return this.after( $.createSpinner( opts ) );
+       };
+
+       /**
+        * @class jQuery
+        * @mixins jQuery.plugin.spinner
+        */
+
+}( jQuery ) );
diff --git a/resources/src/jquery/images/marker.png b/resources/src/jquery/images/marker.png
deleted file mode 100644 (file)
index 915b347..0000000
Binary files a/resources/src/jquery/images/marker.png and /dev/null differ
diff --git a/resources/src/jquery/images/mask.png b/resources/src/jquery/images/mask.png
deleted file mode 100644 (file)
index c9606b0..0000000
Binary files a/resources/src/jquery/images/mask.png and /dev/null differ
diff --git a/resources/src/jquery/images/spinner-large.gif b/resources/src/jquery/images/spinner-large.gif
deleted file mode 100644 (file)
index 72203fd..0000000
Binary files a/resources/src/jquery/images/spinner-large.gif and /dev/null differ
diff --git a/resources/src/jquery/images/spinner.gif b/resources/src/jquery/images/spinner.gif
deleted file mode 100644 (file)
index 6146be4..0000000
Binary files a/resources/src/jquery/images/spinner.gif and /dev/null differ
diff --git a/resources/src/jquery/images/wheel.png b/resources/src/jquery/images/wheel.png
deleted file mode 100644 (file)
index d930224..0000000
Binary files a/resources/src/jquery/images/wheel.png and /dev/null differ
diff --git a/resources/src/jquery/jquery.farbtastic.css b/resources/src/jquery/jquery.farbtastic.css
deleted file mode 100644 (file)
index 0cba34f..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * Farbtastic Color Picker 1.2
- * © 2008 Steven Wittens
- *
- * 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
- */
-.farbtastic {
-       position: relative;
-}
-.farbtastic * {
-       position: absolute;
-       cursor: crosshair;
-}
-.farbtastic,
-.farbtastic .wheel {
-       width: 195px;
-       height: 195px;
-}
-.farbtastic .color,
-.farbtastic .overlay {
-       top: 47px;
-       left: 47px;
-       width: 101px;
-       height: 101px;
-}
-.farbtastic .wheel {
-       /* @embed */
-       background: url( images/wheel.png ) no-repeat;
-       width: 195px;
-       height: 195px;
-}
-.farbtastic .overlay {
-       /* @embed */
-       background: url( images/mask.png ) no-repeat;
-}
-.farbtastic .marker {
-       width: 17px;
-       height: 17px;
-       margin: -8px 0 0 -8px;
-       overflow: hidden;
-       /* @embed */
-       background: url( images/marker.png ) no-repeat;
-}
diff --git a/resources/src/jquery/jquery.farbtastic.js b/resources/src/jquery/jquery.farbtastic.js
deleted file mode 100644 (file)
index f70913f..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-/**
- * Farbtastic Color Picker 1.2
- * © 2008 Steven Wittens
- *
- * 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
- */
-
-//Adapted to uniform style with jQuery UI widgets and slightly change behavior
-//TODO:
-// - remove duplicated code by replacing it with jquery.colorUtils and modern jQuery
-// - uniform code style
-
-jQuery.fn.farbtastic = function (callback) {
-       $.farbtastic(this, callback);
-       return this;
-};
-
-jQuery.farbtastic = function (container, callback) {
-       var container = $(container).get(0);
-       return container.farbtastic || (container.farbtastic = new jQuery._farbtastic(container, callback));
-}
-
-jQuery._farbtastic = function (container, callback) {
-       // Store farbtastic object
-       var fb = this;
-
-       // Insert markup
-       $(container).html('<div class="farbtastic ui-widget-content"><div class="color"></div><div class="wheel"></div><div class="overlay"></div><div class="h-marker marker"></div><div class="sl-marker marker"></div></div>');
-       $(container).addClass('ui-widget');
-       var e = $('.farbtastic', container);
-       fb.wheel = $('.wheel', container).get(0);
-       // Dimensions
-       fb.radius = 84;
-       fb.square = 100;
-       fb.width = 194;
-
-       // Fix background PNGs in IE6
-       if (navigator.appVersion.match(/MSIE [0-6]\./)) {
-               $('*', e).each(function () {
-                       if (this.currentStyle.backgroundImage != 'none') {
-                               var image = this.currentStyle.backgroundImage;
-                               image = this.currentStyle.backgroundImage.slice(5, image.length - 2);
-                               $(this).css( {
-                                       backgroundImage: 'none',
-                                       filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
-                               } );
-                       }
-               });
-       }
-
-       /**
-        * Link to the given element(s) or callback.
-        */
-       fb.linkTo = function (callback) {
-               // Unbind previous nodes
-               if (typeof fb.callback == 'object') {
-                       $(fb.callback).unbind('keyup', fb.updateValue);
-               }
-
-               // Reset color
-               fb.color = null;
-
-               // Bind callback or elements
-               if (typeof callback == 'function') {
-                       fb.callback = callback;
-               }
-               else if (typeof callback == 'object' || typeof callback == 'string') {
-                       fb.callback = $(callback);
-                       fb.callback.bind('keyup', fb.updateValue);
-                       if (fb.callback.get(0).value) {
-                               fb.setColor(fb.callback.get(0).value);
-                       }
-               }
-               return this;
-       }
-       fb.updateValue = function (event) {
-               if (this.value != fb.color) {
-                       fb.setColor(this.value);
-               }
-       }
-
-       /**
-        * Change color with HTML syntax #123456
-        */
-       fb.setColor = function (color) {
-               var rgb = $.colorUtil.getRGB( color );
-               if (fb.color != color && rgb) {
-                       rgb = rgb.slice( 0 ); //make a clone
-                       //TODO: rewrite code so that this is not needed
-                       rgb[0] /= 255;
-                       rgb[1] /= 255;
-                       rgb[2] /= 255;
-                       fb.color = color;
-                       fb.rgb = rgb;
-                       fb.hsl = fb.RGBToHSL(fb.rgb);
-                       fb.updateDisplay();
-               }
-               return this;
-       }
-
-       /**
-        * Change color with HSL triplet [0..1, 0..1, 0..1]
-        */
-       fb.setHSL = function (hsl) {
-               fb.hsl = hsl;
-               fb.rgb = fb.HSLToRGB(hsl);
-               fb.color = fb.pack(fb.rgb);
-               fb.updateDisplay();
-               return this;
-       }
-
-       /////////////////////////////////////////////////////
-
-       /**
-        * Retrieve the coordinates of the given event relative to the center
-        * of the widget.
-        */
-       fb.widgetCoords = function (event) {
-               var ref = $( fb.wheel ).offset();
-               return {
-                       x: event.pageX - ref.left - fb.width / 2,
-                       y: event.pageY - ref.top - fb.width / 2
-               };
-       }
-
-       /**
-        * Mousedown handler
-        */
-       fb.mousedown = function (event) {
-               // Capture mouse
-               if (!document.dragging) {
-                       $(document).bind('mousemove', fb.mousemove).bind('mouseup', fb.mouseup);
-                       document.dragging = true;
-               }
-
-               // Check which area is being dragged
-               var pos = fb.widgetCoords(event);
-               fb.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > fb.square;
-
-               // Process
-               fb.mousemove(event);
-               return false;
-       }
-
-       /**
-        * Mousemove handler
-        */
-       fb.mousemove = function (event) {
-               // Get coordinates relative to color picker center
-               var pos = fb.widgetCoords(event);
-
-               // Set new HSL parameters
-               if (fb.circleDrag) {
-                       var hue = Math.atan2(pos.x, -pos.y) / 6.28;
-                       if (hue < 0) hue += 1;
-                       fb.setHSL([hue, fb.hsl[1], fb.hsl[2]]);
-               }
-               else {
-                       var sat = Math.max(0, Math.min(1, -(pos.x / fb.square) + .5));
-                       var lum = Math.max(0, Math.min(1, -(pos.y / fb.square) + .5));
-                       fb.setHSL([fb.hsl[0], sat, lum]);
-               }
-               return false;
-       }
-
-       /**
-        * Mouseup handler
-        */
-       fb.mouseup = function () {
-               // Uncapture mouse
-               $(document).unbind('mousemove', fb.mousemove);
-               $(document).unbind('mouseup', fb.mouseup);
-               document.dragging = false;
-       }
-
-       /**
-        * Update the markers and styles
-        */
-       fb.updateDisplay = function () {
-               // Markers
-               var angle = fb.hsl[0] * 6.28;
-               $('.h-marker', e).css({
-                       left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + 'px',
-                       top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + 'px'
-               });
-
-               $('.sl-marker', e).css({
-                       left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + 'px',
-                       top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + 'px'
-               });
-
-               // Saturation/Luminance gradient
-               $('.color', e).css('backgroundColor', fb.pack(fb.HSLToRGB([fb.hsl[0], 1, 0.5])));
-
-               // Linked elements or callback
-               if (typeof fb.callback == 'object') {
-                       // Set background/foreground color
-                       $(fb.callback).css({
-                               backgroundColor: fb.color,
-                               color: fb.hsl[2] > 0.5 ? '#000' : '#fff'
-                       });
-
-                       // Change linked value
-                       $(fb.callback).each(function() {
-                               if ( $( this ).val() != fb.color) {
-                                       $( this ).val( fb.color ).change();
-                               }
-                       });
-               }
-               else if (typeof fb.callback == 'function') {
-                       fb.callback.call(fb, fb.color);
-               }
-       }
-
-       /* Various color utility functions */
-       fb.pack = function (rgb) {
-               var r = Math.round(rgb[0] * 255);
-               var g = Math.round(rgb[1] * 255);
-               var b = Math.round(rgb[2] * 255);
-               return '#' + (r < 16 ? '0' : '') + r.toString(16) +
-                                        (g < 16 ? '0' : '') + g.toString(16) +
-                                        (b < 16 ? '0' : '') + b.toString(16);
-       }
-
-       fb.HSLToRGB = function (hsl) {
-               var m1, m2, r, g, b;
-               var h = hsl[0], s = hsl[1], l = hsl[2];
-               m2 = (l <= 0.5) ? l * (s + 1) : l + s - l*s;
-               m1 = l * 2 - m2;
-               return [this.hueToRGB(m1, m2, h+0.33333),
-                               this.hueToRGB(m1, m2, h),
-                               this.hueToRGB(m1, m2, h-0.33333)];
-       }
-
-       fb.hueToRGB = function (m1, m2, h) {
-               h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h);
-               if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
-               if (h * 2 < 1) return m2;
-               if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6;
-               return m1;
-       }
-
-       fb.RGBToHSL = function (rgb) {
-               var min, max, delta, h, s, l;
-               var r = rgb[0], g = rgb[1], b = rgb[2];
-               min = Math.min(r, Math.min(g, b));
-               max = Math.max(r, Math.max(g, b));
-               delta = max - min;
-               l = (min + max) / 2;
-               s = 0;
-               if (l > 0 && l < 1) {
-                       s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l));
-               }
-               h = 0;
-               if (delta > 0) {
-                       if (max == r && max != g) h += (g - b) / delta;
-                       if (max == g && max != b) h += (2 + (b - r) / delta);
-                       if (max == b && max != r) h += (4 + (r - g) / delta);
-                       h /= 6;
-               }
-               return [h, s, l];
-       }
-
-       // Install mousedown handler (the others are set on the document on-demand)
-       $('*', e).mousedown(fb.mousedown);
-
-               // Init color
-       fb.setColor('#000000');
-
-       // Set linked elements/callback
-       if (callback) {
-               fb.linkTo(callback);
-       }
-}
diff --git a/resources/src/jquery/jquery.footHovzer.css b/resources/src/jquery/jquery.footHovzer.css
deleted file mode 100644 (file)
index 77d9514..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#jquery-foot-hovzer {
-       position: fixed;
-       bottom: 0;
-       width: 100%;
-       z-index: 1000;
-}
diff --git a/resources/src/jquery/jquery.footHovzer.js b/resources/src/jquery/jquery.footHovzer.js
deleted file mode 100644 (file)
index e601ddb..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * @class jQuery.plugin.footHovzer
- */
-( function ( $ ) {
-       var $hovzer, footHovzer, $spacer;
-
-       function getHovzer() {
-               if ( $hovzer === undefined ) {
-                       $hovzer = $( '<div id="jquery-foot-hovzer"></div>' ).appendTo( 'body' );
-               }
-               return $hovzer;
-       }
-
-       /**
-        * Utility to stack stuff in an overlay fixed on the bottom of the page.
-        *
-        * Usage:
-        *
-        *     var hovzer = $.getFootHovzer();
-        *     hovzer.$.append( $myCollection );
-        *     hovzer.update();
-        *
-        * @static
-        * @inheritable
-        * @return {jQuery.footHovzer}
-        */
-       $.getFootHovzer = function () {
-               footHovzer.$ = getHovzer();
-               return footHovzer;
-       };
-
-       /**
-        * @private
-        * @class jQuery.footHovzer
-        */
-       footHovzer = {
-
-               /**
-                * @property {jQuery} $ The stack container
-                */
-
-               /**
-                * Update dimensions of stack to account for changes in the subtree.
-                */
-               update: function () {
-                       var $body;
-
-                       $body = $( 'body' );
-
-                       if ( $spacer === undefined ) {
-                               $spacer = $( '<div>' ).attr( 'id', 'jquery-foot-hovzer-spacer' );
-                               $spacer.appendTo( $body );
-                       }
-                       // Ensure CSS is applied by browser before using .outerHeight()
-                       setTimeout( function () {
-                               $spacer.css( 'height', getHovzer().outerHeight( /* includeMargin = */ true ) );
-                       }, 0 );
-               }
-       };
-
-       /**
-        * @class jQuery
-        * @mixins jQuery.plugin.footHovzer
-        */
-
-}( jQuery ) );
index c3d7dbf..eb42311 100644 (file)
@@ -47,7 +47,6 @@
                };
 
                // Handle different kinds of elements
-
                if ( !options.plainMode && $collapsible.is( 'table' ) ) {
                        // Tables
                        // If there is a caption, hide all rows; otherwise, only hide body rows
                                $containers = $containers.not( $defaultToggle.closest( 'tr' ) );
                        }
 
-                       if ( action === 'collapse' ) {
-                               // Hide all table rows of this table
-                               // Slide doesn't work with tables, but fade does as of jQuery 1.1.3
-                               // http://stackoverflow.com/questions/467336#920480
-                               if ( options.instantHide ) {
-                                       $containers.hide();
-                                       hookCallback();
-                               } else {
-                                       $containers.stop( true, true ).fadeOut().promise().done( hookCallback );
-                               }
-                       } else {
-                               $containers.stop( true, true ).fadeIn().promise().done( hookCallback );
-                       }
-
                } else if ( !options.plainMode && ( $collapsible.is( 'ul' ) || $collapsible.is( 'ol' ) ) ) {
                        // Lists
                        $containers = $collapsible.find( '> li' );
                                // Exclude list-item containing togglelink
                                $containers = $containers.not( $defaultToggle.parent() );
                        }
-
-                       if ( action === 'collapse' ) {
-                               if ( options.instantHide ) {
-                                       $containers.hide();
-                                       hookCallback();
-                               } else {
-                                       $containers.stop( true, true ).slideUp().promise().done( hookCallback );
-                               }
-                       } else {
-                               $containers.stop( true, true ).slideDown().promise().done( hookCallback );
-                       }
-
                } else {
                        // Everything else: <div>, <p> etc.
                        $collapsibleContent = $collapsible.find( '> .mw-collapsible-content' );
 
                        // If a collapsible-content is defined, act on it
                        if ( !options.plainMode && $collapsibleContent.length ) {
-                               if ( action === 'collapse' ) {
-                                       if ( options.instantHide ) {
-                                               $collapsibleContent.hide();
-                                               hookCallback();
-                                       } else {
-                                               $collapsibleContent.slideUp().promise().done( hookCallback );
-                                       }
-                               } else {
-                                       $collapsibleContent.slideDown().promise().done( hookCallback );
-                               }
+                               $containers = $collapsibleContent;
 
                        // Otherwise assume this is a customcollapse with a remote toggle
                        // .. and there is no collapsible-content because the entire element should be toggled
                        } else {
-                               if ( action === 'collapse' ) {
-                                       if ( options.instantHide ) {
-                                               $collapsible.hide();
-                                               hookCallback();
-                                       } else {
-                                               if ( $collapsible.is( 'tr' ) || $collapsible.is( 'td' ) || $collapsible.is( 'th' ) ) {
-                                                       $collapsible.fadeOut().promise().done( hookCallback );
-                                               } else {
-                                                       $collapsible.slideUp().promise().done( hookCallback );
-                                               }
-                                       }
-                               } else {
-                                       if ( $collapsible.is( 'tr' ) || $collapsible.is( 'td' ) || $collapsible.is( 'th' ) ) {
-                                               $collapsible.fadeIn().promise().done( hookCallback );
-                                       } else {
-                                               $collapsible.slideDown().promise().done( hookCallback );
-                                       }
-                               }
+                               $containers = $collapsible;
                        }
                }
+
+               $containers.toggle( action === 'expand' );
+               hookCallback();
        }
 
        /**
 
                        $( this ).data( 'mw-collapsible', {
                                collapse: function () {
-                                       actionHandler.call( $toggleLink.get( 0 ), null, { instantHide: true, wasCollapsed: false } );
+                                       actionHandler.call( $toggleLink.get( 0 ), null, { wasCollapsed: false } );
                                },
                                expand: function () {
-                                       actionHandler.call( $toggleLink.get( 0 ), null, { instantHide: true, wasCollapsed: true } );
+                                       actionHandler.call( $toggleLink.get( 0 ), null, { wasCollapsed: true } );
                                },
                                toggle: function () {
                                        actionHandler.call( $toggleLink.get( 0 ), null, null );
                        if ( options.collapsed || $collapsible.hasClass( 'mw-collapsed' ) ) {
                                // One toggler can hook to multiple elements, and one element can have
                                // multiple togglers. This is the sanest way to handle that.
-                               actionHandler.call( $toggleLink.get( 0 ), null, { instantHide: true, wasCollapsed: false } );
+                               actionHandler.call( $toggleLink.get( 0 ), null, { wasCollapsed: false } );
                        }
 
                } );
diff --git a/resources/src/jquery/jquery.spinner.css b/resources/src/jquery/jquery.spinner.css
deleted file mode 100644 (file)
index 6c7bd0e..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-.mw-spinner {
-       background-color: transparent;
-       background-position: center center;
-       background-repeat: no-repeat;
-}
-
-.mw-spinner-small {
-       /* @embed */
-       background-image: url( images/spinner.gif );
-       height: 20px;
-       width: 20px;
-       /* Avoid issues with .mw-spinner-block when floated without width. */
-       min-width: 20px;
-}
-
-.mw-spinner-large {
-       /* @embed */
-       background-image: url( images/spinner-large.gif );
-       height: 32px;
-       width: 32px;
-       /* Avoid issues with .mw-spinner-block when floated without width. */
-       min-width: 32px;
-}
-
-.mw-spinner-block {
-       display: block;
-       /* This overrides width from .mw-spinner-large / .mw-spinner-small,
-        * This is where the min-width kicks in.
-        */
-       width: 100%;
-}
-
-.mw-spinner-inline {
-       display: inline-block;
-       vertical-align: middle;
-
-       /* IE < 8 */
-       zoom: 1;
-       *display: inline; /* stylelint-disable-line declaration-block-no-duplicate-properties */
-}
diff --git a/resources/src/jquery/jquery.spinner.js b/resources/src/jquery/jquery.spinner.js
deleted file mode 100644 (file)
index 9079cc0..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * jQuery Spinner
- *
- * Simple jQuery plugin to create, inject and remove spinners.
- *
- * @class jQuery.plugin.spinner
- */
-( function ( $ ) {
-
-       // Default options for new spinners,
-       // stored outside the function to share between calls.
-       var defaults = {
-               id: undefined,
-               size: 'small',
-               type: 'inline'
-       };
-
-       $.extend( {
-               /**
-                * Create a spinner element
-                *
-                * The argument is an object with options used to construct the spinner (see below).
-                *
-                * It is a good practice to keep a reference to the created spinner to be able to remove it
-                * later. Alternatively, one can use the 'id' option and #removeSpinner (but make sure to choose
-                * an id that's unlikely to cause conflicts, e.g. with extensions, gadgets or user scripts).
-                *
-                * CSS classes used:
-                *
-                * - .mw-spinner for every spinner
-                * - .mw-spinner-small / .mw-spinner-large for size
-                * - .mw-spinner-block / .mw-spinner-inline for display types
-                *
-                * Example:
-                *
-                *     // Create a large spinner reserving all available horizontal space.
-                *     var $spinner = $.createSpinner( { size: 'large', type: 'block' } );
-                *     // Insert above page content.
-                *     $( '#mw-content-text' ).prepend( $spinner );
-                *
-                *     // Place a small inline spinner next to the "Save" button
-                *     var $spinner = $.createSpinner( { size: 'small', type: 'inline' } );
-                *     // Alternatively, just `$.createSpinner();` as these are the default options.
-                *     $( '#wpSave' ).after( $spinner );
-                *
-                *     // The following two are equivalent:
-                *     $.createSpinner( 'magic' );
-                *     $.createSpinner( { id: 'magic' } );
-                *
-                * @static
-                * @inheritable
-                * @param {Object|string} [opts] Options. If a string is given, it will be treated as the value
-                *   of the `id` option. If an object is given, the possible option keys are:
-                * @param {string} [opts.id] If given, spinner will be given an id of "mw-spinner-{id}".
-                * @param {string} [opts.size='small'] 'small' or 'large' for a 20-pixel or 32-pixel spinner.
-                * @param {string} [opts.type='inline'] 'inline' or 'block'. Inline creates an inline-block with
-                *   width and height equal to spinner size. Block is a block-level element with width 100%,
-                *   height equal to spinner size.
-                * @return {jQuery}
-                */
-               createSpinner: function ( opts ) {
-                       var $spinner;
-
-                       if ( opts !== undefined && $.type( opts ) !== 'object' ) {
-                               opts = {
-                                       id: opts
-                               };
-                       }
-
-                       opts = $.extend( {}, defaults, opts );
-
-                       $spinner = $( '<div>' ).addClass( 'mw-spinner' ).attr( 'title', '...' );
-                       if ( opts.id !== undefined ) {
-                               $spinner.attr( 'id', 'mw-spinner-' + opts.id );
-                       }
-
-                       $spinner.addClass( opts.size === 'large' ? 'mw-spinner-large' : 'mw-spinner-small' );
-                       $spinner.addClass( opts.type === 'block' ? 'mw-spinner-block' : 'mw-spinner-inline' );
-
-                       return $spinner;
-               },
-
-               /**
-                * Remove a spinner element
-                *
-                * @static
-                * @inheritable
-                * @param {string} id Id of the spinner, as passed to #createSpinner
-                * @return {jQuery} The (now detached) spinner element
-                */
-               removeSpinner: function ( id ) {
-                       return $( '#mw-spinner-' + id ).remove();
-               }
-       } );
-
-       /**
-        * Inject a spinner after each element in the collection
-        *
-        * Inserts spinner as siblings (not children) of the target elements.
-        * Collection contents remain unchanged.
-        *
-        * @param {Object|string} [opts] See #createSpinner
-        * @return {jQuery}
-        */
-       $.fn.injectSpinner = function ( opts ) {
-               return this.after( $.createSpinner( opts ) );
-       };
-
-       /**
-        * @class jQuery
-        * @mixins jQuery.plugin.spinner
-        */
-
-}( jQuery ) );
index bd6b5dd..eda939d 100644 (file)
@@ -1,6 +1,6 @@
 .client-js {
        // Reserve space for table sortable controls
-       table.sortable th {
+       table.sortable > thead > tr > th:not( .unsortable ) {
                padding-right: 21px;
        }
 }
index 2b76187..dcaae3e 100644 (file)
                rWhitespace = /[ _\u00A0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]+/g,
 
                // From MediaWikiTitleCodec::splitTitleString() in PHP
-               rUnicodeBidi = /[\u200E\u200F\u202A-\u202E]/g,
+               rStripCharacters = /[\u00AD\u061C\u200E\u200F\u202A-\u202E\u2066-\u2069]/g,
 
                /**
                 * Slightly modified from Flinfo. Credit goes to Lupo and Flominator.
                        namespace = defaultNamespace === undefined ? NS_MAIN : defaultNamespace;
 
                        title = title
-                               // Strip Unicode bidi override characters
-                               .replace( rUnicodeBidi, '' )
+                               // Strip soft hyphens and Unicode directional formatting characters
+                               .replace( rStripCharacters, '' )
                                // Normalise whitespace to underscores and remove duplicates
                                .replace( rWhitespace, '_' )
                                // Trim underscores
index 7f12835..7467d50 100644 (file)
@@ -50,8 +50,6 @@
  * @class mw.Uri
  */
 
-/* eslint-disable no-use-before-define */
-
 ( function ( mw, $ ) {
        var parser, properties;
 
                                        return uri;
                                }
                                href = hrefCur;
+                               // eslint-disable-next-line no-use-before-define
                                uri = new Uri( href );
                                return uri;
                        };
index 5ae91e8..1be0052 100644 (file)
@@ -1,7 +1,7 @@
 /*!
  * Scripts for pre-emptive edit preparing on action=edit
  */
-/* eslint-disable no-use-before-define */
+
 ( function ( mw, $ ) {
        if ( !mw.config.get( 'wgAjaxEditStash' ) ) {
                return;
                        return;
                }
 
+               // Whether the body text content changed since the last stashEdit()
+               function isTextChanged() {
+                       return lastText !== $text.textSelection( 'getContents' );
+               }
+
+               // Whether the edit summary has changed since the last stashEdit()
+               function isSummaryChanged() {
+                       return lastSummary !== $summary.textSelection( 'getContents' );
+               }
+
                // Send a request to stash the edit to the API.
                // If a request is in progress, abort it since its payload is stale and the API
                // may limit concurrent stash parses.
@@ -43,6 +53,7 @@
                        if ( stashReq ) {
                                if ( lastPriority > priority ) {
                                        // Stash request for summary change should wait on pending text change stash
+                                       // eslint-disable-next-line no-use-before-define
                                        stashReq.then( checkStash );
                                        return;
                                }
                        } );
                }
 
-               // Whether the body text content changed since the last stashEdit()
-               function isTextChanged() {
-                       return lastText !== $text.textSelection( 'getContents' );
-               }
-
-               // Whether the edit summary has changed since the last stashEdit()
-               function isSummaryChanged() {
-                       return lastSummary !== $summary.textSelection( 'getContents' );
-               }
-
                // Check whether text or summary have changed and call stashEdit()
                function checkStash() {
                        if ( !isTextChanged() && !isSummaryChanged() ) {
index db81ff2..1367426 100644 (file)
@@ -60,7 +60,6 @@
 
        // Use buttonElement to include ButtonInputWidget and ButtonWidget
        .editButtons .oo-ui-buttonElement,
-       .cancelLink,
        .editHelp {
                margin-top: 0.5em;
        }
diff --git a/resources/src/mediawiki.api.category.js b/resources/src/mediawiki.api.category.js
deleted file mode 100644 (file)
index 85df90e..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * @class mw.Api.plugin.category
- */
-( function ( mw, $ ) {
-
-       $.extend( mw.Api.prototype, {
-               /**
-                * Determine if a category exists.
-                *
-                * @param {mw.Title|string} title
-                * @return {jQuery.Promise}
-                * @return {Function} return.done
-                * @return {boolean} return.done.isCategory Whether the category exists.
-                */
-               isCategory: function ( title ) {
-                       var apiPromise = this.get( {
-                               formatversion: 2,
-                               prop: 'categoryinfo',
-                               titles: [ String( title ) ]
-                       } );
-
-                       return apiPromise
-                               .then( function ( data ) {
-                                       return !!(
-                                               data.query && // query is missing on title=""
-                                               data.query.pages && // query.pages is missing on title="#" or title="mw:"
-                                               data.query.pages[ 0 ].categoryinfo
-                                       );
-                               } )
-                               .promise( { abort: apiPromise.abort } );
-               },
-
-               /**
-                * Get a list of categories that match a certain prefix.
-                *
-                * E.g. given "Foo", return "Food", "Foolish people", "Foosball tables"...
-                *
-                * @param {string} prefix Prefix to match.
-                * @return {jQuery.Promise}
-                * @return {Function} return.done
-                * @return {string[]} return.done.categories Matched categories
-                */
-               getCategoriesByPrefix: function ( prefix ) {
-                       // Fetch with allpages to only get categories that have a corresponding description page.
-                       var apiPromise = this.get( {
-                               formatversion: 2,
-                               list: 'allpages',
-                               apprefix: prefix,
-                               apnamespace: mw.config.get( 'wgNamespaceIds' ).category
-                       } );
-
-                       return apiPromise
-                               .then( function ( data ) {
-                                       return data.query.allpages.map( function ( category ) {
-                                               return new mw.Title( category.title ).getMainText();
-                                       } );
-                               } )
-                               .promise( { abort: apiPromise.abort } );
-               },
-
-               /**
-                * Get the categories that a particular page on the wiki belongs to.
-                *
-                * @param {mw.Title|string} title
-                * @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 ) {
-                       var apiPromise = this.get( {
-                               formatversion: 2,
-                               prop: 'categories',
-                               titles: [ String( title ) ]
-                       } );
-
-                       return apiPromise
-                               .then( function ( data ) {
-                                       var page;
-
-                                       if ( !data.query || !data.query.pages ) {
-                                               return false;
-                                       }
-                                       page = data.query.pages[ 0 ];
-                                       if ( !page.categories ) {
-                                               return false;
-                                       }
-                                       return page.categories.map( function ( cat ) {
-                                               return new mw.Title( cat.title );
-                                       } );
-                               } )
-                               .promise( { abort: apiPromise.abort } );
-               }
-       } );
-
-       /**
-        * @class mw.Api
-        * @mixins mw.Api.plugin.category
-        */
-
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api.edit.js b/resources/src/mediawiki.api.edit.js
deleted file mode 100644 (file)
index 21c55c7..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-/**
- * @class mw.Api.plugin.edit
- */
-( function ( mw, $ ) {
-
-       $.extend( mw.Api.prototype, {
-
-               /**
-                * Post to API with csrf token. If we have no token, get one and try to post.
-                * If we have a cached token try using that, and if it fails, blank out the
-                * cached token and start over.
-                *
-                * @param {Object} params API parameters
-                * @param {Object} [ajaxOptions]
-                * @return {jQuery.Promise} See #post
-                */
-               postWithEditToken: function ( params, ajaxOptions ) {
-                       return this.postWithToken( 'csrf', params, ajaxOptions );
-               },
-
-               /**
-                * API helper to grab a csrf token.
-                *
-                * @return {jQuery.Promise} Received token.
-                */
-               getEditToken: function () {
-                       return this.getToken( 'csrf' );
-               },
-
-               /**
-                * Create a new page.
-                *
-                * Example:
-                *
-                *     new mw.Api().create( 'Sandbox',
-                *         { summary: 'Load sand particles.' },
-                *         'Sand.'
-                *     );
-                *
-                * @since 1.28
-                * @param {mw.Title|string} title Page title
-                * @param {Object} params Edit API parameters
-                * @param {string} params.summary Edit summary
-                * @param {string} content
-                * @return {jQuery.Promise} API response
-                */
-               create: function ( title, params, content ) {
-                       return this.postWithEditToken( $.extend( {
-                               action: 'edit',
-                               title: String( title ),
-                               text: content,
-                               formatversion: '2',
-
-                               // Protect against errors and conflicts
-                               assert: mw.user.isAnon() ? undefined : 'user',
-                               createonly: true
-                       }, params ) ).then( function ( data ) {
-                               return data.edit;
-                       } );
-               },
-
-               /**
-                * Edit an existing page.
-                *
-                * To create a new page, use #create() instead.
-                *
-                * Simple transformation:
-                *
-                *     new mw.Api()
-                *         .edit( 'Sandbox', function ( revision ) {
-                *             return revision.content.replace( 'foo', 'bar' );
-                *         } )
-                *         .then( function () {
-                *             console.log( 'Saved! ');
-                *         } );
-                *
-                * Set save parameters by returning an object instead of a string:
-                *
-                *     new mw.Api().edit(
-                *         'Sandbox',
-                *         function ( revision ) {
-                *             return {
-                *                 text: revision.content.replace( 'foo', 'bar' ),
-                *                 summary: 'Replace "foo" with "bar".',
-                *                 assert: 'bot',
-                *                 minor: true
-                *             };
-                *         }
-                *     )
-                *     .then( function () {
-                *         console.log( 'Saved! ');
-                *     } );
-                *
-                * Transform asynchronously by returning a promise.
-                *
-                *     new mw.Api()
-                *         .edit( 'Sandbox', function ( revision ) {
-                *             return Spelling
-                *                 .corrections( revision.content )
-                *                 .then( function ( report ) {
-                *                     return {
-                *                         text: report.output,
-                *                         summary: report.changelog
-                *                     };
-                *                 } );
-                *         } )
-                *         .then( function () {
-                *             console.log( 'Saved! ');
-                *         } );
-                *
-                * @since 1.28
-                * @param {mw.Title|string} title Page title
-                * @param {Function} transform Callback that prepares the edit
-                * @param {Object} transform.revision Current revision
-                * @param {string} transform.revision.content Current revision content
-                * @param {string|Object|jQuery.Promise} transform.return New content, object with edit
-                *  API parameters, or promise providing one of those.
-                * @return {jQuery.Promise} Edit API response
-                */
-               edit: function ( title, transform ) {
-                       var basetimestamp, curtimestamp,
-                               api = this;
-
-                       title = String( title );
-
-                       return api.get( {
-                               action: 'query',
-                               prop: 'revisions',
-                               rvprop: [ 'content', 'timestamp' ],
-                               titles: [ title ],
-                               formatversion: '2',
-                               curtimestamp: true
-                       } )
-                               .then( function ( data ) {
-                                       var page, revision;
-                                       if ( !data.query || !data.query.pages ) {
-                                               return $.Deferred().reject( 'unknown' );
-                                       }
-                                       page = data.query.pages[ 0 ];
-                                       if ( !page || page.invalid ) {
-                                               return $.Deferred().reject( 'invalidtitle' );
-                                       }
-                                       if ( page.missing ) {
-                                               return $.Deferred().reject( 'nocreate-missing' );
-                                       }
-                                       revision = page.revisions[ 0 ];
-                                       basetimestamp = revision.timestamp;
-                                       curtimestamp = data.curtimestamp;
-                                       return transform( {
-                                               timestamp: revision.timestamp,
-                                               content: revision.content
-                                       } );
-                               } )
-                               .then( function ( params ) {
-                                       var editParams = typeof params === 'object' ? params : { text: String( params ) };
-                                       return api.postWithEditToken( $.extend( {
-                                               action: 'edit',
-                                               title: title,
-                                               formatversion: '2',
-
-                                               // Protect against errors and conflicts
-                                               assert: mw.user.isAnon() ? undefined : 'user',
-                                               basetimestamp: basetimestamp,
-                                               starttimestamp: curtimestamp,
-                                               nocreate: true
-                                       }, editParams ) );
-                               } )
-                               .then( function ( data ) {
-                                       return data.edit;
-                               } );
-               },
-
-               /**
-                * Post a new section to the page.
-                *
-                * @see #postWithEditToken
-                * @param {mw.Title|string} title Target page
-                * @param {string} header
-                * @param {string} message wikitext message
-                * @param {Object} [additionalParams] Additional API parameters, e.g. `{ redirect: true }`
-                * @return {jQuery.Promise}
-                */
-               newSection: function ( title, header, message, additionalParams ) {
-                       return this.postWithEditToken( $.extend( {
-                               action: 'edit',
-                               section: 'new',
-                               title: String( title ),
-                               summary: header,
-                               text: message
-                       }, additionalParams ) );
-               }
-       } );
-
-       /**
-        * @class mw.Api
-        * @mixins mw.Api.plugin.edit
-        */
-
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api.js b/resources/src/mediawiki.api.js
deleted file mode 100644 (file)
index 0038ed8..0000000
+++ /dev/null
@@ -1,506 +0,0 @@
-( function ( mw, $ ) {
-
-       /**
-        * @class mw.Api
-        */
-
-       /**
-        * @property {Object} defaultOptions Default options for #ajax calls. Can be overridden by passing
-        *     `options` to mw.Api constructor.
-        * @property {Object} defaultOptions.parameters Default query parameters for API requests.
-        * @property {Object} defaultOptions.ajax Default options for jQuery#ajax.
-        * @property {boolean} defaultOptions.useUS Whether to use U+001F when joining multi-valued
-        *     parameters (since 1.28). Default is true if ajax.url is not set, false otherwise for
-        *     compatibility.
-        * @private
-        */
-       var defaultOptions = {
-                       parameters: {
-                               action: 'query',
-                               format: 'json'
-                       },
-                       ajax: {
-                               url: mw.util.wikiScript( 'api' ),
-                               timeout: 30 * 1000, // 30 seconds
-                               dataType: 'json'
-                       }
-               },
-
-               // Keyed by ajax url and symbolic name for the individual request
-               promises = {};
-
-       function mapLegacyToken( action ) {
-               // Legacy types for backward-compatibility with API action=tokens.
-               var csrfActions = [
-                       'edit',
-                       'delete',
-                       'protect',
-                       'move',
-                       'block',
-                       'unblock',
-                       'email',
-                       'import',
-                       'options'
-               ];
-               if ( csrfActions.indexOf( action ) !== -1 ) {
-                       mw.track( 'mw.deprecate', 'apitoken_' + action );
-                       mw.log.warn( 'Use of the "' + action + '" token is deprecated. Use "csrf" instead.' );
-                       return 'csrf';
-               }
-               return action;
-       }
-
-       // Pre-populate with fake ajax promises to save http requests for tokens
-       // we already have on the page via the user.tokens module (T36733).
-       promises[ defaultOptions.ajax.url ] = {};
-       $.each( mw.user.tokens.get(), function ( key, value ) {
-               // This requires #getToken to use the same key as user.tokens.
-               // Format: token-type + "Token" (eg. csrfToken, patrolToken, watchToken).
-               promises[ defaultOptions.ajax.url ][ key ] = $.Deferred()
-                       .resolve( value )
-                       .promise( { abort: function () {} } );
-       } );
-
-       /**
-        * 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.
-        *
-        *     var api = new mw.Api();
-        *     api.get( {
-        *         action: 'query',
-        *         meta: 'userinfo'
-        *     } ).done( function ( data ) {
-        *         console.log( data );
-        *     } );
-        *
-        * Since MW 1.25, multiple values for a parameter can be specified using an array:
-        *
-        *     var api = new mw.Api();
-        *     api.get( {
-        *         action: 'query',
-        *         meta: [ 'userinfo', 'siteinfo' ] // same effect as 'userinfo|siteinfo'
-        *     } ).done( function ( data ) {
-        *         console.log( data );
-        *     } );
-        *
-        * Since MW 1.26, boolean values for a parameter can be specified directly. If the value is
-        * `false` or `undefined`, the parameter will be omitted from the request, as required by the API.
-        *
-        * @constructor
-        * @param {Object} [options] See #defaultOptions documentation above. Can also be overridden for
-        *  each individual request by passing them to #get or #post (or directly #ajax) later on.
-        */
-       mw.Api = function ( options ) {
-               options = options || {};
-
-               // Force a string if we got a mw.Uri object
-               if ( options.ajax && options.ajax.url !== undefined ) {
-                       options.ajax.url = String( options.ajax.url );
-               }
-
-               options = $.extend( { useUS: !options.ajax || !options.ajax.url }, options );
-
-               options.parameters = $.extend( {}, defaultOptions.parameters, options.parameters );
-               options.ajax = $.extend( {}, defaultOptions.ajax, options.ajax );
-
-               this.defaults = options;
-               this.requests = [];
-       };
-
-       mw.Api.prototype = {
-               /**
-                * Abort all unfinished requests issued by this Api object.
-                *
-                * @method
-                */
-               abort: function () {
-                       this.requests.forEach( function ( request ) {
-                               if ( request ) {
-                                       request.abort();
-                               }
-                       } );
-               },
-
-               /**
-                * Perform API get request
-                *
-                * @param {Object} parameters
-                * @param {Object} [ajaxOptions]
-                * @return {jQuery.Promise}
-                */
-               get: function ( parameters, ajaxOptions ) {
-                       ajaxOptions = ajaxOptions || {};
-                       ajaxOptions.type = 'GET';
-                       return this.ajax( parameters, ajaxOptions );
-               },
-
-               /**
-                * Perform API post request
-                *
-                * @param {Object} parameters
-                * @param {Object} [ajaxOptions]
-                * @return {jQuery.Promise}
-                */
-               post: function ( parameters, ajaxOptions ) {
-                       ajaxOptions = ajaxOptions || {};
-                       ajaxOptions.type = 'POST';
-                       return this.ajax( parameters, ajaxOptions );
-               },
-
-               /**
-                * Massage parameters from the nice format we accept into a format suitable for the API.
-                *
-                * NOTE: A value of undefined/null in an array will be represented by Array#join()
-                * as the empty string. Should we filter silently? Warn? Leave as-is?
-                *
-                * @private
-                * @param {Object} parameters (modified in-place)
-                * @param {boolean} useUS Whether to use U+001F when joining multi-valued parameters.
-                */
-               preprocessParameters: function ( parameters, useUS ) {
-                       var key;
-                       // Handle common MediaWiki API idioms for passing parameters
-                       for ( key in parameters ) {
-                               // Multiple values are pipe-separated
-                               if ( Array.isArray( parameters[ key ] ) ) {
-                                       if ( !useUS || parameters[ key ].join( '' ).indexOf( '|' ) === -1 ) {
-                                               parameters[ key ] = parameters[ key ].join( '|' );
-                                       } else {
-                                               parameters[ key ] = '\x1f' + parameters[ key ].join( '\x1f' );
-                                       }
-                               } else if ( parameters[ key ] === false || parameters[ key ] === undefined ) {
-                                       // Boolean values are only false when not given at all
-                                       delete parameters[ key ];
-                               }
-                       }
-               },
-
-               /**
-                * Perform the API call.
-                *
-                * @param {Object} parameters
-                * @param {Object} [ajaxOptions]
-                * @return {jQuery.Promise} Done: API response data and the jqXHR object.
-                *  Fail: Error code
-                */
-               ajax: function ( parameters, ajaxOptions ) {
-                       var token, requestIndex,
-                               api = this,
-                               apiDeferred = $.Deferred(),
-                               xhr, key, formData;
-
-                       parameters = $.extend( {}, this.defaults.parameters, parameters );
-                       ajaxOptions = $.extend( {}, this.defaults.ajax, ajaxOptions );
-
-                       // Ensure that token parameter is last (per [[mw:API:Edit#Token]]).
-                       if ( parameters.token ) {
-                               token = parameters.token;
-                               delete parameters.token;
-                       }
-
-                       this.preprocessParameters( parameters, this.defaults.useUS );
-
-                       // If multipart/form-data has been requested and emulation is possible, emulate it
-                       if (
-                               ajaxOptions.type === 'POST' &&
-                               window.FormData &&
-                               ajaxOptions.contentType === 'multipart/form-data'
-                       ) {
-
-                               formData = new FormData();
-
-                               for ( key in parameters ) {
-                                       formData.append( key, parameters[ key ] );
-                               }
-                               // If we extracted a token parameter, add it back in.
-                               if ( token ) {
-                                       formData.append( 'token', token );
-                               }
-
-                               ajaxOptions.data = formData;
-
-                               // Prevent jQuery from mangling our FormData object
-                               ajaxOptions.processData = false;
-                               // Prevent jQuery from overriding the Content-Type header
-                               ajaxOptions.contentType = false;
-                       } else {
-                               // This works because jQuery accepts data as a query string or as an Object
-                               ajaxOptions.data = $.param( parameters );
-                               // If we extracted a token parameter, add it back in.
-                               if ( token ) {
-                                       ajaxOptions.data += '&token=' + encodeURIComponent( token );
-                               }
-
-                               // Depending on server configuration, MediaWiki may forbid periods in URLs, due to an IE 6
-                               // XSS bug. So let's escape them here. See WebRequest::checkUrlExtension() and T30235.
-                               ajaxOptions.data = ajaxOptions.data.replace( /\./g, '%2E' );
-
-                               if ( ajaxOptions.contentType === 'multipart/form-data' ) {
-                                       // We were asked to emulate but can't, so drop the Content-Type header, otherwise
-                                       // it'll be wrong and the server will fail to decode the POST body
-                                       delete ajaxOptions.contentType;
-                               }
-                       }
-
-                       // Make the AJAX request
-                       xhr = $.ajax( ajaxOptions )
-                               // If AJAX fails, reject API call with error code 'http'
-                               // and details in second argument.
-                               .fail( function ( xhr, textStatus, exception ) {
-                                       apiDeferred.reject( 'http', {
-                                               xhr: xhr,
-                                               textStatus: textStatus,
-                                               exception: exception
-                                       } );
-                               } )
-                               // AJAX success just means "200 OK" response, also check API error codes
-                               .done( function ( result, textStatus, jqXHR ) {
-                                       var code;
-                                       if ( result === undefined || result === null || result === '' ) {
-                                               apiDeferred.reject( 'ok-but-empty',
-                                                       'OK response but empty result (check HTTP headers?)',
-                                                       result,
-                                                       jqXHR
-                                               );
-                                       } else if ( result.error ) {
-                                               // errorformat=bc
-                                               code = result.error.code === undefined ? 'unknown' : result.error.code;
-                                               apiDeferred.reject( code, result, result, jqXHR );
-                                       } else if ( result.errors ) {
-                                               // errorformat!=bc
-                                               code = result.errors[ 0 ].code === undefined ? 'unknown' : result.errors[ 0 ].code;
-                                               apiDeferred.reject( code, result, result, jqXHR );
-                                       } else {
-                                               apiDeferred.resolve( result, jqXHR );
-                                       }
-                               } );
-
-                       requestIndex = this.requests.length;
-                       this.requests.push( xhr );
-                       xhr.always( function () {
-                               api.requests[ requestIndex ] = null;
-                       } );
-                       // Return the Promise
-                       return apiDeferred.promise( { abort: xhr.abort } ).fail( function ( code, details ) {
-                               if ( !( code === 'http' && details && details.textStatus === 'abort' ) ) {
-                                       mw.log( 'mw.Api error: ', code, details );
-                               }
-                       } );
-               },
-
-               /**
-                * Post to API with specified type of token. If we have no token, get one and try to post.
-                * If we have a cached token try using that, and if it fails, blank out the
-                * cached token and start over. For example to change an user option you could do:
-                *
-                *     new mw.Api().postWithToken( 'csrf', {
-                *         action: 'options',
-                *         optionname: 'gender',
-                *         optionvalue: 'female'
-                *     } );
-                *
-                * @param {string} tokenType The name of the token, like options or edit.
-                * @param {Object} params API parameters
-                * @param {Object} [ajaxOptions]
-                * @return {jQuery.Promise} See #post
-                * @since 1.22
-                */
-               postWithToken: function ( tokenType, params, ajaxOptions ) {
-                       var api = this,
-                               abortedPromise = $.Deferred().reject( 'http',
-                                       { textStatus: 'abort', exception: 'abort' } ).promise(),
-                               abortable,
-                               aborted;
-
-                       return api.getToken( tokenType, params.assert ).then( function ( token ) {
-                               params.token = token;
-                               // Request was aborted while token request was running, but we
-                               // don't want to unnecessarily abort token requests, so abort
-                               // a fake request instead
-                               if ( aborted ) {
-                                       return abortedPromise;
-                               }
-
-                               return ( abortable = api.post( params, ajaxOptions ) ).catch(
-                                       // Error handler
-                                       function ( code ) {
-                                               if ( code === 'badtoken' ) {
-                                                       api.badToken( tokenType );
-                                                       // Try again, once
-                                                       params.token = undefined;
-                                                       abortable = null;
-                                                       return api.getToken( tokenType, params.assert ).then( function ( token ) {
-                                                               params.token = token;
-                                                               if ( aborted ) {
-                                                                       return abortedPromise;
-                                                               }
-
-                                                               return ( abortable = api.post( params, ajaxOptions ) );
-                                                       } );
-                                               }
-
-                                               // Let caller handle the error code
-                                               return $.Deferred().rejectWith( this, arguments );
-                                       }
-                               );
-                       } ).promise( { abort: function () {
-                               if ( abortable ) {
-                                       abortable.abort();
-                               } else {
-                                       aborted = true;
-                               }
-                       } } );
-               },
-
-               /**
-                * Get a token for a certain action from the API.
-                *
-                * The assert parameter is only for internal use by #postWithToken.
-                *
-                * @since 1.22
-                * @param {string} type Token type
-                * @param {string} [assert]
-                * @return {jQuery.Promise} Received token.
-                */
-               getToken: function ( type, assert ) {
-                       var apiPromise, promiseGroup, d, reject;
-                       type = mapLegacyToken( type );
-                       promiseGroup = promises[ this.defaults.ajax.url ];
-                       d = promiseGroup && promiseGroup[ type + 'Token' ];
-
-                       if ( !promiseGroup ) {
-                               promiseGroup = promises[ this.defaults.ajax.url ] = {};
-                       }
-
-                       if ( !d ) {
-                               apiPromise = this.get( {
-                                       action: 'query',
-                                       meta: 'tokens',
-                                       type: type,
-                                       assert: assert
-                               } );
-                               reject = function () {
-                                       // Clear promise. Do not cache errors.
-                                       delete promiseGroup[ type + 'Token' ];
-
-                                       // Let caller handle the error code
-                                       return $.Deferred().rejectWith( this, arguments );
-                               };
-                               d = apiPromise
-                                       .then( function ( res ) {
-                                               if ( !res.query ) {
-                                                       return reject( 'query-missing', res );
-                                               }
-                                               // If token type is unknown, it is omitted from the response
-                                               if ( !res.query.tokens[ type + 'token' ] ) {
-                                                       return $.Deferred().reject( 'token-missing', res );
-                                               }
-                                               return res.query.tokens[ type + 'token' ];
-                                       }, reject )
-                                       // Attach abort handler
-                                       .promise( { abort: apiPromise.abort } );
-
-                               // Store deferred now so that we can use it again even if it isn't ready yet
-                               promiseGroup[ type + 'Token' ] = d;
-                       }
-
-                       return d;
-               },
-
-               /**
-                * Indicate that the cached token for a certain action of the API is bad.
-                *
-                * Call this if you get a 'badtoken' error when using the token returned by #getToken.
-                * You may also want to use #postWithToken instead, which invalidates bad cached tokens
-                * automatically.
-                *
-                * @param {string} type Token type
-                * @since 1.26
-                */
-               badToken: function ( type ) {
-                       var promiseGroup = promises[ this.defaults.ajax.url ];
-
-                       type = mapLegacyToken( type );
-                       if ( promiseGroup ) {
-                               delete promiseGroup[ type + 'Token' ];
-                       }
-               }
-       };
-
-       /**
-        * @static
-        * @property {Array}
-        * Very incomplete and outdated list of errors we might receive from the API. Do not use.
-        * @deprecated since 1.29
-        */
-       mw.Api.errors = [
-               // occurs when POST aborted
-               // jQuery 1.4 can't distinguish abort or lost connection from 200 OK + empty result
-               'ok-but-empty',
-
-               // timeout
-               'timeout',
-
-               // really a warning, but we treat it like an error
-               'duplicate',
-               'duplicate-archive',
-
-               // upload succeeded, but no image info.
-               // this is probably impossible, but might as well check for it
-               'noimageinfo',
-               // remote errors, defined in API
-               'uploaddisabled',
-               'nomodule',
-               'mustbeposted',
-               'badaccess-groups',
-               'missingresult',
-               'missingparam',
-               'invalid-file-key',
-               'copyuploaddisabled',
-               'mustbeloggedin',
-               'empty-file',
-               'file-too-large',
-               'filetype-missing',
-               'filetype-banned',
-               'filetype-banned-type',
-               'filename-tooshort',
-               'illegal-filename',
-               'verification-error',
-               'hookaborted',
-               'unknown-error',
-               'internal-error',
-               'overwrite',
-               'badtoken',
-               'fetchfileerror',
-               'fileexists-shared-forbidden',
-               'invalidtitle',
-               'notloggedin',
-               'autoblocked',
-               'blocked',
-
-               // Stash-specific errors - expanded
-               'stashfailed',
-               'stasherror',
-               'stashedfilenotfound',
-               'stashpathinvalid',
-               'stashfilestorage',
-               'stashzerolength',
-               'stashnotloggedin',
-               'stashwrongowner',
-               'stashnosuchfilekey'
-       ];
-       mw.log.deprecate( mw.Api, 'errors', mw.Api.errors, null, 'mw.Api.errors' );
-
-       /**
-        * @static
-        * @property {Array}
-        * Very incomplete and outdated list of warnings we might receive from the API. Do not use.
-        * @deprecated since 1.29
-        */
-       mw.Api.warnings = [
-               'duplicate',
-               'exists'
-       ];
-       mw.log.deprecate( mw.Api, 'warnings', mw.Api.warnings, null, 'mw.Api.warnings' );
-
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api.login.js b/resources/src/mediawiki.api.login.js
deleted file mode 100644 (file)
index 2b709aa..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * Make the two-step login easier.
- *
- * @author Niklas Laxström
- * @class mw.Api.plugin.login
- * @since 1.22
- */
-( function ( mw, $ ) {
-       'use strict';
-
-       $.extend( mw.Api.prototype, {
-               /**
-                * @param {string} username
-                * @param {string} password
-                * @return {jQuery.Promise} See mw.Api#post
-                */
-               login: function ( username, password ) {
-                       var params, apiPromise, innerPromise,
-                               api = this;
-
-                       params = {
-                               action: 'login',
-                               lgname: username,
-                               lgpassword: password
-                       };
-
-                       apiPromise = api.post( params );
-
-                       return apiPromise
-                               .then( function ( data ) {
-                                       params.lgtoken = data.login.token;
-                                       innerPromise = api.post( params )
-                                               .then( function ( data ) {
-                                                       var code;
-                                                       if ( data.login.result !== 'Success' ) {
-                                                               // Set proper error code whenever possible
-                                                               code = data.error && data.error.code || 'unknown';
-                                                               return $.Deferred().reject( code, data );
-                                                       }
-                                                       return data;
-                                               } );
-                                       return innerPromise;
-                               } )
-                               .promise( {
-                                       abort: function () {
-                                               apiPromise.abort();
-                                               if ( innerPromise ) {
-                                                       innerPromise.abort();
-                                               }
-                                       }
-                               } );
-               }
-       } );
-
-       /**
-        * @class mw.Api
-        * @mixins mw.Api.plugin.login
-        */
-
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api.messages.js b/resources/src/mediawiki.api.messages.js
deleted file mode 100644 (file)
index 688f0b2..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * Allows to retrieve a specific or a set of
- * messages to be added to mw.messages and returned
- * by the Api.
- *
- * @class mw.Api.plugin.messages
- * @since 1.27
- */
-( function ( mw, $ ) {
-       'use strict';
-
-       $.extend( mw.Api.prototype, {
-               /**
-                * Get a set of messages.
-                *
-                * @param {Array} messages Messages to retrieve
-                * @param {Object} [options] Additional parameters for the API call
-                * @return {jQuery.Promise}
-                */
-               getMessages: function ( messages, options ) {
-                       options = options || {};
-                       return this.get( $.extend( {
-                               action: 'query',
-                               meta: 'allmessages',
-                               ammessages: messages,
-                               amlang: mw.config.get( 'wgUserLanguage' ),
-                               formatversion: 2
-                       }, options ) ).then( function ( data ) {
-                               var result = {};
-
-                               data.query.allmessages.forEach( function ( obj ) {
-                                       if ( !obj.missing ) {
-                                               result[ obj.name ] = obj.content;
-                                       }
-                               } );
-
-                               return result;
-                       } );
-               },
-
-               /**
-                * Loads a set of messages and add them to mw.messages.
-                *
-                * @param {Array} messages Messages to retrieve
-                * @param {Object} [options] Additional parameters for the API call
-                * @return {jQuery.Promise}
-                */
-               loadMessages: function ( messages, options ) {
-                       return this.getMessages( messages, options ).then( $.proxy( mw.messages, 'set' ) );
-               },
-
-               /**
-                * Loads a set of messages and add them to mw.messages. Only messages that are not already known
-                * are loaded. If all messages are known, the returned promise is resolved immediately.
-                *
-                * @param {Array} messages Messages to retrieve
-                * @param {Object} [options] Additional parameters for the API call
-                * @return {jQuery.Promise}
-                */
-               loadMessagesIfMissing: function ( messages, options ) {
-                       var missing = messages.filter( function ( msg ) {
-                               return !mw.message( msg ).exists();
-                       } );
-
-                       if ( missing.length === 0 ) {
-                               return $.Deferred().resolve();
-                       }
-
-                       return this.getMessages( missing, options ).then( $.proxy( mw.messages, 'set' ) );
-               }
-       } );
-
-       /**
-        * @class mw.Api
-        * @mixins mw.Api.plugin.messages
-        */
-
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api.options.js b/resources/src/mediawiki.api.options.js
deleted file mode 100644 (file)
index 4930c4f..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * @class mw.Api.plugin.options
- */
-( function ( mw, $ ) {
-
-       $.extend( mw.Api.prototype, {
-
-               /**
-                * Asynchronously save the value of a single user option using the API. See #saveOptions.
-                *
-                * @param {string} name
-                * @param {string|null} value
-                * @return {jQuery.Promise}
-                */
-               saveOption: function ( name, value ) {
-                       var param = {};
-                       param[ name ] = value;
-                       return this.saveOptions( param );
-               },
-
-               /**
-                * Asynchronously save the values of user options using the API.
-                *
-                * If a value of `null` is provided, the given option will be reset to the default value.
-                *
-                * Any warnings returned by the API, including warnings about invalid option names or values,
-                * are ignored. However, do not rely on this behavior.
-                *
-                * If necessary, the options will be saved using several sequential API requests. Only one promise
-                * is always returned that will be resolved when all requests complete.
-                *
-                * @param {Object} options Options as a `{ name: value, … }` object
-                * @return {jQuery.Promise}
-                */
-               saveOptions: function ( options ) {
-                       var name, value, bundleable,
-                               grouped = [],
-                               promise = $.Deferred().resolve();
-
-                       for ( name in options ) {
-                               value = options[ name ] === null ? null : String( options[ name ] );
-
-                               // Can we bundle this option, or does it need a separate request?
-                               if ( this.defaults.useUS ) {
-                                       bundleable = name.indexOf( '=' ) === -1;
-                               } else {
-                                       bundleable =
-                                               ( value === null || value.indexOf( '|' ) === -1 ) &&
-                                               ( name.indexOf( '|' ) === -1 && name.indexOf( '=' ) === -1 );
-                               }
-
-                               if ( bundleable ) {
-                                       if ( value !== null ) {
-                                               grouped.push( name + '=' + value );
-                                       } else {
-                                               // Omitting value resets the option
-                                               grouped.push( name );
-                                       }
-                               } else {
-                                       if ( value !== null ) {
-                                               promise = promise.then( function ( name, value ) {
-                                                       return this.postWithToken( 'csrf', {
-                                                               formatversion: 2,
-                                                               action: 'options',
-                                                               optionname: name,
-                                                               optionvalue: value
-                                                       } );
-                                               }.bind( this, name, value ) );
-                                       } else {
-                                               // Omitting value resets the option
-                                               promise = promise.then( function ( name ) {
-                                                       return this.postWithToken( 'csrf', {
-                                                               formatversion: 2,
-                                                               action: 'options',
-                                                               optionname: name
-                                                       } );
-                                               }.bind( this, name ) );
-                                       }
-                               }
-                       }
-
-                       if ( grouped.length ) {
-                               promise = promise.then( function () {
-                                       return this.postWithToken( 'csrf', {
-                                               formatversion: 2,
-                                               action: 'options',
-                                               change: grouped
-                                       } );
-                               }.bind( this ) );
-                       }
-
-                       return promise;
-               }
-
-       } );
-
-       /**
-        * @class mw.Api
-        * @mixins mw.Api.plugin.options
-        */
-
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api.parse.js b/resources/src/mediawiki.api.parse.js
deleted file mode 100644 (file)
index f38e88b..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * @class mw.Api.plugin.parse
- */
-( function ( mw, $ ) {
-
-       $.extend( mw.Api.prototype, {
-               /**
-                * Convenience method for 'action=parse'.
-                *
-                * @param {string|mw.Title} content Content to parse, either as a wikitext string or
-                *   a mw.Title.
-                * @param {Object} additionalParams Parameters object to set custom settings, e.g.
-                *   redirects, sectionpreview.  prop should not be overridden.
-                * @return {jQuery.Promise}
-                * @return {Function} return.done
-                * @return {string} return.done.data Parsed HTML of `wikitext`.
-                */
-               parse: function ( content, additionalParams ) {
-                       var apiPromise,
-                               config = $.extend( {
-                                       formatversion: 2,
-                                       action: 'parse',
-                                       contentmodel: 'wikitext'
-                               }, additionalParams );
-
-                       if ( mw.Title && content instanceof mw.Title ) {
-                               // Parse existing page
-                               config.page = content.getPrefixedDb();
-                       } else {
-                               // Parse wikitext from input
-                               config.text = String( content );
-                       }
-
-                       apiPromise = this.get( config );
-
-                       return apiPromise
-                               .then( function ( data ) {
-                                       return data.parse.text;
-                               } )
-                               .promise( { abort: apiPromise.abort } );
-               }
-       } );
-
-       /**
-        * @class mw.Api
-        * @mixins mw.Api.plugin.parse
-        */
-
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api.rollback.js b/resources/src/mediawiki.api.rollback.js
deleted file mode 100644 (file)
index 322143d..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * @class mw.Api.plugin.rollback
- * @since 1.28
- */
-( function ( mw, $ ) {
-
-       $.extend( mw.Api.prototype, {
-               /**
-                * Convenience method for `action=rollback`.
-                *
-                * @param {string|mw.Title} page
-                * @param {string} user
-                * @param {Object} [params] Additional parameters
-                * @return {jQuery.Promise}
-                */
-               rollback: function ( page, user, params ) {
-                       return this.postWithToken( 'rollback', $.extend( {
-                               action: 'rollback',
-                               title: String( page ),
-                               user: user,
-                               uselang: mw.config.get( 'wgUserLanguage' )
-                       }, params ) ).then( function ( data ) {
-                               return data.rollback;
-                       } );
-               }
-       } );
-
-       /**
-        * @class mw.Api
-        * @mixins mw.Api.plugin.rollback
-        */
-
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api.upload.js b/resources/src/mediawiki.api.upload.js
deleted file mode 100644 (file)
index 29bd59a..0000000
+++ /dev/null
@@ -1,668 +0,0 @@
-/**
- * Provides an interface for uploading files to MediaWiki.
- *
- * @class mw.Api.plugin.upload
- * @singleton
- */
-( function ( mw, $ ) {
-       var nonce = 0,
-               fieldsAllowed = {
-                       stash: true,
-                       filekey: true,
-                       filename: true,
-                       comment: true,
-                       text: true,
-                       watchlist: true,
-                       ignorewarnings: true,
-                       chunk: true,
-                       offset: true,
-                       filesize: true,
-                       async: true
-               };
-
-       /**
-        * Get nonce for iframe IDs on the page.
-        *
-        * @private
-        * @return {number}
-        */
-       function getNonce() {
-               return nonce++;
-       }
-
-       /**
-        * Given a non-empty object, return one of its keys.
-        *
-        * @private
-        * @param {Object} obj
-        * @return {string}
-        */
-       function getFirstKey( obj ) {
-               var key;
-               for ( key in obj ) {
-                       if ( obj.hasOwnProperty( key ) ) {
-                               return key;
-                       }
-               }
-       }
-
-       /**
-        * Get new iframe object for an upload.
-        *
-        * @private
-        * @param {string} id
-        * @return {HTMLIframeElement}
-        */
-       function getNewIframe( id ) {
-               var frame = document.createElement( 'iframe' );
-               frame.id = id;
-               frame.name = id;
-               return frame;
-       }
-
-       /**
-        * Shortcut for getting hidden inputs
-        *
-        * @private
-        * @param {string} name
-        * @param {string} val
-        * @return {jQuery}
-        */
-       function getHiddenInput( name, val ) {
-               return $( '<input>' ).attr( 'type', 'hidden' )
-                       .attr( 'name', name )
-                       .val( val );
-       }
-
-       /**
-        * Process the result of the form submission, returned to an iframe.
-        * This is the iframe's onload event.
-        *
-        * @param {HTMLIframeElement} iframe Iframe to extract result from
-        * @return {Object} Response from the server. The return value may or may
-        *   not be an XMLDocument, this code was copied from elsewhere, so if you
-        *   see an unexpected return type, please file a bug.
-        */
-       function processIframeResult( iframe ) {
-               var json,
-                       doc = iframe.contentDocument || frames[ iframe.id ].document;
-
-               if ( doc.XMLDocument ) {
-                       // The response is a document property in IE
-                       return doc.XMLDocument;
-               }
-
-               if ( doc.body ) {
-                       // Get the json string
-                       // We're actually searching through an HTML doc here --
-                       // according to mdale we need to do this
-                       // because IE does not load JSON properly in an iframe
-                       json = $( doc.body ).find( 'pre' ).text();
-
-                       return JSON.parse( json );
-               }
-
-               // Response is a xml document
-               return doc;
-       }
-
-       function formDataAvailable() {
-               return window.FormData !== undefined &&
-                       window.File !== undefined &&
-                       window.File.prototype.slice !== undefined;
-       }
-
-       $.extend( mw.Api.prototype, {
-               /**
-                * Upload a file to MediaWiki.
-                *
-                * The file will be uploaded using AJAX and FormData, if the browser supports it, or via an
-                * iframe if it doesn't.
-                *
-                * Caveats of iframe upload:
-                * - The returned jQuery.Promise will not receive `progress` notifications during the upload
-                * - It is incompatible with uploads to a foreign wiki using mw.ForeignApi
-                * - You must pass a HTMLInputElement and not a File for it to be possible
-                *
-                * @param {HTMLInputElement|File|Blob} file HTML input type=file element with a file already inside
-                *  of it, or a File object.
-                * @param {Object} data Other upload options, see action=upload API docs for more
-                * @return {jQuery.Promise}
-                */
-               upload: function ( file, data ) {
-                       var isFileInput, canUseFormData;
-
-                       isFileInput = file && file.nodeType === Node.ELEMENT_NODE;
-
-                       if ( formDataAvailable() && isFileInput && file.files ) {
-                               file = file.files[ 0 ];
-                       }
-
-                       if ( !file ) {
-                               throw new Error( 'No file' );
-                       }
-
-                       // Blobs are allowed in formdata uploads, it turns out
-                       canUseFormData = formDataAvailable() && ( file instanceof window.File || file instanceof window.Blob );
-
-                       if ( !isFileInput && !canUseFormData ) {
-                               throw new Error( 'Unsupported argument type passed to mw.Api.upload' );
-                       }
-
-                       if ( canUseFormData ) {
-                               return this.uploadWithFormData( file, data );
-                       }
-
-                       return this.uploadWithIframe( file, data );
-               },
-
-               /**
-                * Upload a file to MediaWiki with an iframe and a form.
-                *
-                * This method is necessary for browsers without the File/FormData
-                * APIs, and continues to work in browsers with those APIs.
-                *
-                * The rough sketch of how this method works is as follows:
-                * 1. An iframe is loaded with no content.
-                * 2. A form is submitted with the passed-in file input and some extras.
-                * 3. The MediaWiki API receives that form data, and sends back a response.
-                * 4. The response is sent to the iframe, because we set target=(iframe id)
-                * 5. The response is parsed out of the iframe's document, and passed back
-                *    through the promise.
-                *
-                * @private
-                * @param {HTMLInputElement} file The file input with a file in it.
-                * @param {Object} data Other upload options, see action=upload API docs for more
-                * @return {jQuery.Promise}
-                */
-               uploadWithIframe: function ( file, data ) {
-                       var key,
-                               tokenPromise = $.Deferred(),
-                               api = this,
-                               deferred = $.Deferred(),
-                               nonce = getNonce(),
-                               id = 'uploadframe-' + nonce,
-                               $form = $( '<form>' ),
-                               iframe = getNewIframe( id ),
-                               $iframe = $( iframe );
-
-                       for ( key in data ) {
-                               if ( !fieldsAllowed[ key ] ) {
-                                       delete data[ key ];
-                               }
-                       }
-
-                       data = $.extend( {}, this.defaults.parameters, { action: 'upload' }, data );
-                       $form.addClass( 'mw-api-upload-form' );
-
-                       $form.css( 'display', 'none' )
-                               .attr( {
-                                       action: this.defaults.ajax.url,
-                                       method: 'POST',
-                                       target: id,
-                                       enctype: 'multipart/form-data'
-                               } );
-
-                       $iframe.one( 'load', function () {
-                               $iframe.one( 'load', function () {
-                                       var result = processIframeResult( iframe );
-                                       deferred.notify( 1 );
-
-                                       if ( !result ) {
-                                               deferred.reject( 'ok-but-empty', 'No response from API on upload attempt.' );
-                                       } else if ( result.error ) {
-                                               if ( result.error.code === 'badtoken' ) {
-                                                       api.badToken( 'csrf' );
-                                               }
-
-                                               deferred.reject( result.error.code, result );
-                                       } else if ( result.upload && result.upload.warnings ) {
-                                               deferred.reject( getFirstKey( result.upload.warnings ), result );
-                                       } else {
-                                               deferred.resolve( result );
-                                       }
-                               } );
-                               tokenPromise.done( function () {
-                                       $form.submit();
-                               } );
-                       } );
-
-                       $iframe.on( 'error', function ( error ) {
-                               deferred.reject( 'http', error );
-                       } );
-
-                       $iframe.prop( 'src', 'about:blank' ).hide();
-
-                       file.name = 'file';
-
-                       $.each( data, function ( key, val ) {
-                               $form.append( getHiddenInput( key, val ) );
-                       } );
-
-                       if ( !data.filename && !data.stash ) {
-                               throw new Error( 'Filename not included in file data.' );
-                       }
-
-                       if ( this.needToken() ) {
-                               this.getEditToken().then( function ( token ) {
-                                       $form.append( getHiddenInput( 'token', token ) );
-                                       tokenPromise.resolve();
-                               }, tokenPromise.reject );
-                       } else {
-                               tokenPromise.resolve();
-                       }
-
-                       $( 'body' ).append( $form, $iframe );
-
-                       deferred.always( function () {
-                               $form.remove();
-                               $iframe.remove();
-                       } );
-
-                       return deferred.promise();
-               },
-
-               /**
-                * Uploads a file using the FormData API.
-                *
-                * @private
-                * @param {File} file
-                * @param {Object} data Other upload options, see action=upload API docs for more
-                * @return {jQuery.Promise}
-                */
-               uploadWithFormData: function ( file, data ) {
-                       var key, request,
-                               deferred = $.Deferred();
-
-                       for ( key in data ) {
-                               if ( !fieldsAllowed[ key ] ) {
-                                       delete data[ key ];
-                               }
-                       }
-
-                       data = $.extend( {}, this.defaults.parameters, { action: 'upload' }, data );
-                       if ( !data.chunk ) {
-                               data.file = file;
-                       }
-
-                       if ( !data.filename && !data.stash ) {
-                               throw new Error( 'Filename not included in file data.' );
-                       }
-
-                       // Use this.postWithEditToken() or this.post()
-                       request = this[ this.needToken() ? 'postWithEditToken' : 'post' ]( data, {
-                               // Use FormData (if we got here, we know that it's available)
-                               contentType: 'multipart/form-data',
-                               // No timeout (default from mw.Api is 30 seconds)
-                               timeout: 0,
-                               // Provide upload progress notifications
-                               xhr: function () {
-                                       var xhr = $.ajaxSettings.xhr();
-                                       if ( xhr.upload ) {
-                                               // need to bind this event before we open the connection (see note at
-                                               // https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest#Monitoring_progress)
-                                               xhr.upload.addEventListener( 'progress', function ( ev ) {
-                                                       if ( ev.lengthComputable ) {
-                                                               deferred.notify( ev.loaded / ev.total );
-                                                       }
-                                               } );
-                                       }
-                                       return xhr;
-                               }
-                       } )
-                               .done( function ( result ) {
-                                       deferred.notify( 1 );
-                                       if ( result.upload && result.upload.warnings ) {
-                                               deferred.reject( getFirstKey( result.upload.warnings ), result );
-                                       } else {
-                                               deferred.resolve( result );
-                                       }
-                               } )
-                               .fail( function ( errorCode, result ) {
-                                       deferred.notify( 1 );
-                                       deferred.reject( errorCode, result );
-                               } );
-
-                       return deferred.promise( { abort: request.abort } );
-               },
-
-               /**
-                * Upload a file in several chunks.
-                *
-                * @param {File} file
-                * @param {Object} data Other upload options, see action=upload API docs for more
-                * @param {number} [chunkSize] Size (in bytes) per chunk (default: 5MB)
-                * @param {number} [chunkRetries] Amount of times to retry a failed chunk (default: 1)
-                * @return {jQuery.Promise}
-                */
-               chunkedUpload: function ( file, data, chunkSize, chunkRetries ) {
-                       var start, end, promise, next, active,
-                               deferred = $.Deferred();
-
-                       chunkSize = chunkSize === undefined ? 5 * 1024 * 1024 : chunkSize;
-                       chunkRetries = chunkRetries === undefined ? 1 : chunkRetries;
-
-                       if ( !data.filename ) {
-                               throw new Error( 'Filename not included in file data.' );
-                       }
-
-                       // Submit first chunk to get the filekey
-                       active = promise = this.uploadChunk( file, data, 0, chunkSize, '', chunkRetries )
-                               .done( chunkSize >= file.size ? deferred.resolve : null )
-                               .fail( deferred.reject )
-                               .progress( deferred.notify );
-
-                       // Now iteratively submit the rest of the chunks
-                       for ( start = chunkSize; start < file.size; start += chunkSize ) {
-                               end = Math.min( start + chunkSize, file.size );
-                               next = $.Deferred();
-
-                               // We could simply chain one this.uploadChunk after another with
-                               // .then(), but then we'd hit an `Uncaught RangeError: Maximum
-                               // call stack size exceeded` at as low as 1024 calls in Firefox
-                               // 47. This'll work around it, but comes with the drawback of
-                               // having to properly relay the results to the returned promise.
-                               // eslint-disable-next-line no-loop-func
-                               promise.done( function ( start, end, next, result ) {
-                                       var filekey = result.upload.filekey;
-                                       active = this.uploadChunk( file, data, start, end, filekey, chunkRetries )
-                                               .done( end === file.size ? deferred.resolve : next.resolve )
-                                               .fail( deferred.reject )
-                                               .progress( deferred.notify );
-                               // start, end & next must be bound to closure, or they'd have
-                               // changed by the time the promises are resolved
-                               }.bind( this, start, end, next ) );
-
-                               promise = next;
-                       }
-
-                       return deferred.promise( { abort: active.abort } );
-               },
-
-               /**
-                * Uploads 1 chunk.
-                *
-                * @private
-                * @param {File} file
-                * @param {Object} data Other upload options, see action=upload API docs for more
-                * @param {number} start Chunk start position
-                * @param {number} end Chunk end position
-                * @param {string} [filekey] File key, for follow-up chunks
-                * @param {number} [retries] Amount of times to retry request
-                * @return {jQuery.Promise}
-                */
-               uploadChunk: function ( file, data, start, end, filekey, retries ) {
-                       var upload,
-                               api = this,
-                               chunk = this.slice( file, start, end );
-
-                       // When uploading in chunks, we're going to be issuing a lot more
-                       // requests and there's always a chance of 1 getting dropped.
-                       // In such case, it could be useful to try again: a network hickup
-                       // doesn't necessarily have to result in upload failure...
-                       retries = retries === undefined ? 1 : retries;
-
-                       data.filesize = file.size;
-                       data.chunk = chunk;
-                       data.offset = start;
-
-                       // filekey must only be added when uploading follow-up chunks; the
-                       // first chunk should never have a filekey (it'll be generated)
-                       if ( filekey && start !== 0 ) {
-                               data.filekey = filekey;
-                       }
-
-                       upload = this.uploadWithFormData( file, data );
-                       return upload.then(
-                               null,
-                               function ( code, result ) {
-                                       var retry;
-
-                                       // uploadWithFormData will reject uploads with warnings, but
-                                       // these warnings could be "harmless" or recovered from
-                                       // (e.g. exists-normalized, when it'll be renamed later)
-                                       // In the case of (only) a warning, we still want to
-                                       // continue the chunked upload until it completes: then
-                                       // reject it - at least it's been fully uploaded by then and
-                                       // failure handlers have a complete result object (including
-                                       // possibly more warnings, e.g. duplicate)
-                                       // This matches .upload, which also completes the upload.
-                                       if ( result.upload && result.upload.warnings && code in result.upload.warnings ) {
-                                               if ( end === file.size ) {
-                                                       // uploaded last chunk = reject with result data
-                                                       return $.Deferred().reject( code, result );
-                                               } else {
-                                                       // still uploading chunks = resolve to keep going
-                                                       return $.Deferred().resolve( result );
-                                               }
-                                       }
-
-                                       if ( retries === 0 ) {
-                                               return $.Deferred().reject( code, result );
-                                       }
-
-                                       // If the call flat out failed, we may want to try again...
-                                       retry = api.uploadChunk.bind( this, file, data, start, end, filekey, retries - 1 );
-                                       return api.retry( code, result, retry );
-                               },
-                               function ( fraction ) {
-                                       // Since we're only uploading small parts of a file, we
-                                       // need to adjust the reported progress to reflect where
-                                       // we actually are in the combined upload
-                                       return ( start + fraction * ( end - start ) ) / file.size;
-                               }
-                       ).promise( { abort: upload.abort } );
-               },
-
-               /**
-                * Launch the upload anew if it failed because of network issues.
-                *
-                * @private
-                * @param {string} code Error code
-                * @param {Object} result API result
-                * @param {Function} callable
-                * @return {jQuery.Promise}
-                */
-               retry: function ( code, result, callable ) {
-                       var uploadPromise,
-                               retryTimer,
-                               deferred = $.Deferred(),
-                               // Wrap around the callable, so that once it completes, it'll
-                               // resolve/reject the promise we'll return
-                               retry = function () {
-                                       uploadPromise = callable();
-                                       uploadPromise.then( deferred.resolve, deferred.reject );
-                               };
-
-                       // Don't retry if the request failed because we aborted it (or if
-                       // it's another kind of request failure)
-                       if ( code !== 'http' || result.textStatus === 'abort' ) {
-                               return deferred.reject( code, result );
-                       }
-
-                       retryTimer = setTimeout( retry, 1000 );
-                       return deferred.promise( { abort: function () {
-                               // Clear the scheduled upload, or abort if already in flight
-                               if ( retryTimer ) {
-                                       clearTimeout( retryTimer );
-                               }
-                               if ( uploadPromise.abort ) {
-                                       uploadPromise.abort();
-                               }
-                       } } );
-               },
-
-               /**
-                * Slice a chunk out of a File object.
-                *
-                * @private
-                * @param {File} file
-                * @param {number} start
-                * @param {number} stop
-                * @return {Blob}
-                */
-               slice: function ( file, start, stop ) {
-                       if ( file.mozSlice ) {
-                               // FF <= 12
-                               return file.mozSlice( start, stop, file.type );
-                       } else if ( file.webkitSlice ) {
-                               // Chrome <= 20
-                               return file.webkitSlice( start, stop, file.type );
-                       } else {
-                               // On really old browser versions (before slice was prefixed),
-                               // slice() would take (start, length) instead of (start, end)
-                               // We'll ignore that here...
-                               return file.slice( start, stop, file.type );
-                       }
-               },
-
-               /**
-                * This function will handle how uploads to stash (via uploadToStash or
-                * chunkedUploadToStash) are resolved/rejected.
-                *
-                * After a successful stash, it'll resolve with a callback which, when
-                * called, will finalize the upload in stash (with the given data, or
-                * with additional/conflicting data)
-                *
-                * A failed stash can still be recovered from as long as 'filekey' is
-                * present. In that case, it'll also resolve with the callback to
-                * finalize the upload (all warnings are then ignored.)
-                * Otherwise, it'll just reject as you'd expect, with code & result.
-                *
-                * @private
-                * @param {jQuery.Promise} uploadPromise
-                * @param {Object} data
-                * @return {jQuery.Promise}
-                * @return {Function} return.finishUpload Call this function to finish the upload.
-                * @return {Object} return.finishUpload.data Additional data for the upload.
-                * @return {jQuery.Promise} return.finishUpload.return API promise for the final upload
-                * @return {Object} return.finishUpload.return.data API return value for the final upload
-                */
-               finishUploadToStash: function ( uploadPromise, data ) {
-                       var filekey,
-                               api = this;
-
-                       function finishUpload( moreData ) {
-                               return api.uploadFromStash( filekey, $.extend( data, moreData ) );
-                       }
-
-                       return uploadPromise.then(
-                               function ( result ) {
-                                       filekey = result.upload.filekey;
-                                       return finishUpload;
-                               },
-                               function ( errorCode, result ) {
-                                       if ( result && result.upload && result.upload.filekey ) {
-                                               // Ignore any warnings if 'filekey' was returned, that's all we care about
-                                               filekey = result.upload.filekey;
-                                               return $.Deferred().resolve( finishUpload );
-                                       }
-                                       return $.Deferred().reject( errorCode, result );
-                               }
-                       );
-               },
-
-               /**
-                * Upload a file to the stash.
-                *
-                * This function will return a promise, which when resolved, will pass back a function
-                * to finish the stash upload. You can call that function with an argument containing
-                * more, or conflicting, data to pass to the server. For example:
-                *
-                *     // upload a file to the stash with a placeholder filename
-                *     api.uploadToStash( file, { filename: 'testing.png' } ).done( function ( finish ) {
-                *         // finish is now the function we can use to finalize the upload
-                *         // pass it a new filename from user input to override the initial value
-                *         finish( { filename: getFilenameFromUser() } ).done( function ( data ) {
-                *             // the upload is complete, data holds the API response
-                *         } );
-                *     } );
-                *
-                * @param {File|HTMLInputElement} file
-                * @param {Object} [data]
-                * @return {jQuery.Promise}
-                * @return {Function} return.finishUpload Call this function to finish the upload.
-                * @return {Object} return.finishUpload.data Additional data for the upload.
-                * @return {jQuery.Promise} return.finishUpload.return API promise for the final upload
-                * @return {Object} return.finishUpload.return.data API return value for the final upload
-                */
-               uploadToStash: function ( file, data ) {
-                       var promise;
-
-                       if ( !data.filename ) {
-                               throw new Error( 'Filename not included in file data.' );
-                       }
-
-                       promise = this.upload( file, { stash: true, filename: data.filename } );
-
-                       return this.finishUploadToStash( promise, data );
-               },
-
-               /**
-                * Upload a file to the stash, in chunks.
-                *
-                * This function will return a promise, which when resolved, will pass back a function
-                * to finish the stash upload.
-                *
-                * @see #method-uploadToStash
-                * @param {File|HTMLInputElement} file
-                * @param {Object} [data]
-                * @param {number} [chunkSize] Size (in bytes) per chunk (default: 5MB)
-                * @param {number} [chunkRetries] Amount of times to retry a failed chunk (default: 1)
-                * @return {jQuery.Promise}
-                * @return {Function} return.finishUpload Call this function to finish the upload.
-                * @return {Object} return.finishUpload.data Additional data for the upload.
-                * @return {jQuery.Promise} return.finishUpload.return API promise for the final upload
-                * @return {Object} return.finishUpload.return.data API return value for the final upload
-                */
-               chunkedUploadToStash: function ( file, data, chunkSize, chunkRetries ) {
-                       var promise;
-
-                       if ( !data.filename ) {
-                               throw new Error( 'Filename not included in file data.' );
-                       }
-
-                       promise = this.chunkedUpload(
-                               file,
-                               { stash: true, filename: data.filename },
-                               chunkSize,
-                               chunkRetries
-                       );
-
-                       return this.finishUploadToStash( promise, data );
-               },
-
-               /**
-                * Finish an upload in the stash.
-                *
-                * @param {string} filekey
-                * @param {Object} data
-                * @return {jQuery.Promise}
-                */
-               uploadFromStash: function ( filekey, data ) {
-                       data.filekey = filekey;
-                       data.action = 'upload';
-                       data.format = 'json';
-
-                       if ( !data.filename ) {
-                               throw new Error( 'Filename not included in file data.' );
-                       }
-
-                       return this.postWithEditToken( data ).then( function ( result ) {
-                               if ( result.upload && result.upload.warnings ) {
-                                       return $.Deferred().reject( getFirstKey( result.upload.warnings ), result ).promise();
-                               }
-                               return result;
-                       } );
-               },
-
-               needToken: function () {
-                       return true;
-               }
-       } );
-
-       /**
-        * @class mw.Api
-        * @mixins mw.Api.plugin.upload
-        */
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api.user.js b/resources/src/mediawiki.api.user.js
deleted file mode 100644 (file)
index e7b4b6d..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * @class mw.Api.plugin.user
- * @since 1.27
- */
-( function ( mw, $ ) {
-
-       $.extend( mw.Api.prototype, {
-
-               /**
-                * Get the current user's groups and rights.
-                *
-                * @return {jQuery.Promise}
-                * @return {Function} return.done
-                * @return {Object} return.done.userInfo
-                * @return {string[]} return.done.userInfo.groups User groups that the current user belongs to
-                * @return {string[]} return.done.userInfo.rights Current user's rights
-                */
-               getUserInfo: function () {
-                       return this.get( {
-                               action: 'query',
-                               meta: 'userinfo',
-                               uiprop: [ 'groups', 'rights' ]
-                       } ).then( function ( data ) {
-                               if ( data.query && data.query.userinfo ) {
-                                       return data.query.userinfo;
-                               }
-                               return $.Deferred().reject().promise();
-                       } );
-               }
-       } );
-
-       /**
-        * @class mw.Api
-        * @mixins mw.Api.plugin.user
-        */
-
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api.watch.js b/resources/src/mediawiki.api.watch.js
deleted file mode 100644 (file)
index 025c111..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * @class mw.Api.plugin.watch
- * @since 1.19
- */
-( function ( mw, $ ) {
-
-       /**
-        * @private
-        * @static
-        * @context mw.Api
-        *
-        * @param {string|mw.Title|string[]|mw.Title[]} pages Full page name or instance of mw.Title, or an
-        *  array thereof. If an array is passed, the return value passed to the promise will also be an
-        *  array of appropriate objects.
-        * @param {Object} [addParams]
-        * @return {jQuery.Promise}
-        * @return {Function} return.done
-        * @return {Object|Object[]} return.done.watch Object or list of objects (depends on the `pages`
-        *  parameter)
-        * @return {string} return.done.watch.title Full pagename
-        * @return {boolean} return.done.watch.watched Whether the page is now watched or unwatched
-        */
-       function doWatchInternal( pages, addParams ) {
-               // XXX: Parameter addParams is undocumented because we inherit this
-               // documentation in the public method...
-               var apiPromise = this.postWithToken( 'watch',
-                       $.extend(
-                               {
-                                       formatversion: 2,
-                                       action: 'watch',
-                                       titles: Array.isArray( pages ) ? pages : String( pages )
-                               },
-                               addParams
-                       )
-               );
-
-               return apiPromise
-                       .then( function ( data ) {
-                               // If a single page was given (not an array) respond with a single item as well.
-                               return Array.isArray( pages ) ? data.watch : data.watch[ 0 ];
-                       } )
-                       .promise( { abort: apiPromise.abort } );
-       }
-
-       $.extend( mw.Api.prototype, {
-               /**
-                * Convenience method for `action=watch`.
-                *
-                * @inheritdoc #doWatchInternal
-                */
-               watch: function ( pages ) {
-                       return doWatchInternal.call( this, pages );
-               },
-
-               /**
-                * Convenience method for `action=watch&unwatch=1`.
-                *
-                * @inheritdoc #doWatchInternal
-                */
-               unwatch: function ( pages ) {
-                       return doWatchInternal.call( this, pages, { unwatch: 1 } );
-               }
-       } );
-
-       /**
-        * @class mw.Api
-        * @mixins mw.Api.plugin.watch
-        */
-
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api/category.js b/resources/src/mediawiki.api/category.js
new file mode 100644 (file)
index 0000000..85df90e
--- /dev/null
@@ -0,0 +1,101 @@
+/**
+ * @class mw.Api.plugin.category
+ */
+( function ( mw, $ ) {
+
+       $.extend( mw.Api.prototype, {
+               /**
+                * Determine if a category exists.
+                *
+                * @param {mw.Title|string} title
+                * @return {jQuery.Promise}
+                * @return {Function} return.done
+                * @return {boolean} return.done.isCategory Whether the category exists.
+                */
+               isCategory: function ( title ) {
+                       var apiPromise = this.get( {
+                               formatversion: 2,
+                               prop: 'categoryinfo',
+                               titles: [ String( title ) ]
+                       } );
+
+                       return apiPromise
+                               .then( function ( data ) {
+                                       return !!(
+                                               data.query && // query is missing on title=""
+                                               data.query.pages && // query.pages is missing on title="#" or title="mw:"
+                                               data.query.pages[ 0 ].categoryinfo
+                                       );
+                               } )
+                               .promise( { abort: apiPromise.abort } );
+               },
+
+               /**
+                * Get a list of categories that match a certain prefix.
+                *
+                * E.g. given "Foo", return "Food", "Foolish people", "Foosball tables"...
+                *
+                * @param {string} prefix Prefix to match.
+                * @return {jQuery.Promise}
+                * @return {Function} return.done
+                * @return {string[]} return.done.categories Matched categories
+                */
+               getCategoriesByPrefix: function ( prefix ) {
+                       // Fetch with allpages to only get categories that have a corresponding description page.
+                       var apiPromise = this.get( {
+                               formatversion: 2,
+                               list: 'allpages',
+                               apprefix: prefix,
+                               apnamespace: mw.config.get( 'wgNamespaceIds' ).category
+                       } );
+
+                       return apiPromise
+                               .then( function ( data ) {
+                                       return data.query.allpages.map( function ( category ) {
+                                               return new mw.Title( category.title ).getMainText();
+                                       } );
+                               } )
+                               .promise( { abort: apiPromise.abort } );
+               },
+
+               /**
+                * Get the categories that a particular page on the wiki belongs to.
+                *
+                * @param {mw.Title|string} title
+                * @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 ) {
+                       var apiPromise = this.get( {
+                               formatversion: 2,
+                               prop: 'categories',
+                               titles: [ String( title ) ]
+                       } );
+
+                       return apiPromise
+                               .then( function ( data ) {
+                                       var page;
+
+                                       if ( !data.query || !data.query.pages ) {
+                                               return false;
+                                       }
+                                       page = data.query.pages[ 0 ];
+                                       if ( !page.categories ) {
+                                               return false;
+                                       }
+                                       return page.categories.map( function ( cat ) {
+                                               return new mw.Title( cat.title );
+                                       } );
+                               } )
+                               .promise( { abort: apiPromise.abort } );
+               }
+       } );
+
+       /**
+        * @class mw.Api
+        * @mixins mw.Api.plugin.category
+        */
+
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api/edit.js b/resources/src/mediawiki.api/edit.js
new file mode 100644 (file)
index 0000000..e6f5668
--- /dev/null
@@ -0,0 +1,199 @@
+/**
+ * @class mw.Api.plugin.edit
+ */
+( function ( mw, $ ) {
+
+       $.extend( mw.Api.prototype, {
+
+               /**
+                * Post to API with csrf token. If we have no token, get one and try to post.
+                * If we have a cached token try using that, and if it fails, blank out the
+                * cached token and start over.
+                *
+                * @param {Object} params API parameters
+                * @param {Object} [ajaxOptions]
+                * @return {jQuery.Promise} See #post
+                */
+               postWithEditToken: function ( params, ajaxOptions ) {
+                       return this.postWithToken( 'csrf', params, ajaxOptions );
+               },
+
+               /**
+                * API helper to grab a csrf token.
+                *
+                * @return {jQuery.Promise} Received token.
+                */
+               getEditToken: function () {
+                       return this.getToken( 'csrf' );
+               },
+
+               /**
+                * Create a new page.
+                *
+                * Example:
+                *
+                *     new mw.Api().create( 'Sandbox',
+                *         { summary: 'Load sand particles.' },
+                *         'Sand.'
+                *     );
+                *
+                * @since 1.28
+                * @param {mw.Title|string} title Page title
+                * @param {Object} params Edit API parameters
+                * @param {string} params.summary Edit summary
+                * @param {string} content
+                * @return {jQuery.Promise} API response
+                */
+               create: function ( title, params, content ) {
+                       return this.postWithEditToken( $.extend( {
+                               action: 'edit',
+                               title: String( title ),
+                               text: content,
+                               formatversion: '2',
+
+                               // Protect against errors and conflicts
+                               assert: mw.config.get( 'wgUserName' ) ? 'user' : undefined,
+                               createonly: true
+                       }, params ) ).then( function ( data ) {
+                               return data.edit;
+                       } );
+               },
+
+               /**
+                * Edit an existing page.
+                *
+                * To create a new page, use #create() instead.
+                *
+                * Simple transformation:
+                *
+                *     new mw.Api()
+                *         .edit( 'Sandbox', function ( revision ) {
+                *             return revision.content.replace( 'foo', 'bar' );
+                *         } )
+                *         .then( function () {
+                *             console.log( 'Saved! ');
+                *         } );
+                *
+                * Set save parameters by returning an object instead of a string:
+                *
+                *     new mw.Api().edit(
+                *         'Sandbox',
+                *         function ( revision ) {
+                *             return {
+                *                 text: revision.content.replace( 'foo', 'bar' ),
+                *                 summary: 'Replace "foo" with "bar".',
+                *                 assert: 'bot',
+                *                 minor: true
+                *             };
+                *         }
+                *     )
+                *     .then( function () {
+                *         console.log( 'Saved! ');
+                *     } );
+                *
+                * Transform asynchronously by returning a promise.
+                *
+                *     new mw.Api()
+                *         .edit( 'Sandbox', function ( revision ) {
+                *             return Spelling
+                *                 .corrections( revision.content )
+                *                 .then( function ( report ) {
+                *                     return {
+                *                         text: report.output,
+                *                         summary: report.changelog
+                *                     };
+                *                 } );
+                *         } )
+                *         .then( function () {
+                *             console.log( 'Saved! ');
+                *         } );
+                *
+                * @since 1.28
+                * @param {mw.Title|string} title Page title
+                * @param {Function} transform Callback that prepares the edit
+                * @param {Object} transform.revision Current revision
+                * @param {string} transform.revision.content Current revision content
+                * @param {string|Object|jQuery.Promise} transform.return New content, object with edit
+                *  API parameters, or promise providing one of those.
+                * @return {jQuery.Promise} Edit API response
+                */
+               edit: function ( title, transform ) {
+                       var basetimestamp, curtimestamp,
+                               api = this;
+
+                       title = String( title );
+
+                       return api.get( {
+                               action: 'query',
+                               prop: 'revisions',
+                               rvprop: [ 'content', 'timestamp' ],
+                               titles: [ title ],
+                               formatversion: '2',
+                               curtimestamp: true
+                       } )
+                               .then( function ( data ) {
+                                       var page, revision;
+                                       if ( !data.query || !data.query.pages ) {
+                                               return $.Deferred().reject( 'unknown' );
+                                       }
+                                       page = data.query.pages[ 0 ];
+                                       if ( !page || page.invalid ) {
+                                               return $.Deferred().reject( 'invalidtitle' );
+                                       }
+                                       if ( page.missing ) {
+                                               return $.Deferred().reject( 'nocreate-missing' );
+                                       }
+                                       revision = page.revisions[ 0 ];
+                                       basetimestamp = revision.timestamp;
+                                       curtimestamp = data.curtimestamp;
+                                       return transform( {
+                                               timestamp: revision.timestamp,
+                                               content: revision.content
+                                       } );
+                               } )
+                               .then( function ( params ) {
+                                       var editParams = typeof params === 'object' ? params : { text: String( params ) };
+                                       return api.postWithEditToken( $.extend( {
+                                               action: 'edit',
+                                               title: title,
+                                               formatversion: '2',
+
+                                               // Protect against errors and conflicts
+                                               assert: mw.config.get( 'wgUserName' ) ? 'user' : undefined,
+                                               basetimestamp: basetimestamp,
+                                               starttimestamp: curtimestamp,
+                                               nocreate: true
+                                       }, editParams ) );
+                               } )
+                               .then( function ( data ) {
+                                       return data.edit;
+                               } );
+               },
+
+               /**
+                * Post a new section to the page.
+                *
+                * @see #postWithEditToken
+                * @param {mw.Title|string} title Target page
+                * @param {string} header
+                * @param {string} message wikitext message
+                * @param {Object} [additionalParams] Additional API parameters, e.g. `{ redirect: true }`
+                * @return {jQuery.Promise}
+                */
+               newSection: function ( title, header, message, additionalParams ) {
+                       return this.postWithEditToken( $.extend( {
+                               action: 'edit',
+                               section: 'new',
+                               title: String( title ),
+                               summary: header,
+                               text: message
+                       }, additionalParams ) );
+               }
+       } );
+
+       /**
+        * @class mw.Api
+        * @mixins mw.Api.plugin.edit
+        */
+
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api/index.js b/resources/src/mediawiki.api/index.js
new file mode 100644 (file)
index 0000000..0038ed8
--- /dev/null
@@ -0,0 +1,506 @@
+( function ( mw, $ ) {
+
+       /**
+        * @class mw.Api
+        */
+
+       /**
+        * @property {Object} defaultOptions Default options for #ajax calls. Can be overridden by passing
+        *     `options` to mw.Api constructor.
+        * @property {Object} defaultOptions.parameters Default query parameters for API requests.
+        * @property {Object} defaultOptions.ajax Default options for jQuery#ajax.
+        * @property {boolean} defaultOptions.useUS Whether to use U+001F when joining multi-valued
+        *     parameters (since 1.28). Default is true if ajax.url is not set, false otherwise for
+        *     compatibility.
+        * @private
+        */
+       var defaultOptions = {
+                       parameters: {
+                               action: 'query',
+                               format: 'json'
+                       },
+                       ajax: {
+                               url: mw.util.wikiScript( 'api' ),
+                               timeout: 30 * 1000, // 30 seconds
+                               dataType: 'json'
+                       }
+               },
+
+               // Keyed by ajax url and symbolic name for the individual request
+               promises = {};
+
+       function mapLegacyToken( action ) {
+               // Legacy types for backward-compatibility with API action=tokens.
+               var csrfActions = [
+                       'edit',
+                       'delete',
+                       'protect',
+                       'move',
+                       'block',
+                       'unblock',
+                       'email',
+                       'import',
+                       'options'
+               ];
+               if ( csrfActions.indexOf( action ) !== -1 ) {
+                       mw.track( 'mw.deprecate', 'apitoken_' + action );
+                       mw.log.warn( 'Use of the "' + action + '" token is deprecated. Use "csrf" instead.' );
+                       return 'csrf';
+               }
+               return action;
+       }
+
+       // Pre-populate with fake ajax promises to save http requests for tokens
+       // we already have on the page via the user.tokens module (T36733).
+       promises[ defaultOptions.ajax.url ] = {};
+       $.each( mw.user.tokens.get(), function ( key, value ) {
+               // This requires #getToken to use the same key as user.tokens.
+               // Format: token-type + "Token" (eg. csrfToken, patrolToken, watchToken).
+               promises[ defaultOptions.ajax.url ][ key ] = $.Deferred()
+                       .resolve( value )
+                       .promise( { abort: function () {} } );
+       } );
+
+       /**
+        * 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.
+        *
+        *     var api = new mw.Api();
+        *     api.get( {
+        *         action: 'query',
+        *         meta: 'userinfo'
+        *     } ).done( function ( data ) {
+        *         console.log( data );
+        *     } );
+        *
+        * Since MW 1.25, multiple values for a parameter can be specified using an array:
+        *
+        *     var api = new mw.Api();
+        *     api.get( {
+        *         action: 'query',
+        *         meta: [ 'userinfo', 'siteinfo' ] // same effect as 'userinfo|siteinfo'
+        *     } ).done( function ( data ) {
+        *         console.log( data );
+        *     } );
+        *
+        * Since MW 1.26, boolean values for a parameter can be specified directly. If the value is
+        * `false` or `undefined`, the parameter will be omitted from the request, as required by the API.
+        *
+        * @constructor
+        * @param {Object} [options] See #defaultOptions documentation above. Can also be overridden for
+        *  each individual request by passing them to #get or #post (or directly #ajax) later on.
+        */
+       mw.Api = function ( options ) {
+               options = options || {};
+
+               // Force a string if we got a mw.Uri object
+               if ( options.ajax && options.ajax.url !== undefined ) {
+                       options.ajax.url = String( options.ajax.url );
+               }
+
+               options = $.extend( { useUS: !options.ajax || !options.ajax.url }, options );
+
+               options.parameters = $.extend( {}, defaultOptions.parameters, options.parameters );
+               options.ajax = $.extend( {}, defaultOptions.ajax, options.ajax );
+
+               this.defaults = options;
+               this.requests = [];
+       };
+
+       mw.Api.prototype = {
+               /**
+                * Abort all unfinished requests issued by this Api object.
+                *
+                * @method
+                */
+               abort: function () {
+                       this.requests.forEach( function ( request ) {
+                               if ( request ) {
+                                       request.abort();
+                               }
+                       } );
+               },
+
+               /**
+                * Perform API get request
+                *
+                * @param {Object} parameters
+                * @param {Object} [ajaxOptions]
+                * @return {jQuery.Promise}
+                */
+               get: function ( parameters, ajaxOptions ) {
+                       ajaxOptions = ajaxOptions || {};
+                       ajaxOptions.type = 'GET';
+                       return this.ajax( parameters, ajaxOptions );
+               },
+
+               /**
+                * Perform API post request
+                *
+                * @param {Object} parameters
+                * @param {Object} [ajaxOptions]
+                * @return {jQuery.Promise}
+                */
+               post: function ( parameters, ajaxOptions ) {
+                       ajaxOptions = ajaxOptions || {};
+                       ajaxOptions.type = 'POST';
+                       return this.ajax( parameters, ajaxOptions );
+               },
+
+               /**
+                * Massage parameters from the nice format we accept into a format suitable for the API.
+                *
+                * NOTE: A value of undefined/null in an array will be represented by Array#join()
+                * as the empty string. Should we filter silently? Warn? Leave as-is?
+                *
+                * @private
+                * @param {Object} parameters (modified in-place)
+                * @param {boolean} useUS Whether to use U+001F when joining multi-valued parameters.
+                */
+               preprocessParameters: function ( parameters, useUS ) {
+                       var key;
+                       // Handle common MediaWiki API idioms for passing parameters
+                       for ( key in parameters ) {
+                               // Multiple values are pipe-separated
+                               if ( Array.isArray( parameters[ key ] ) ) {
+                                       if ( !useUS || parameters[ key ].join( '' ).indexOf( '|' ) === -1 ) {
+                                               parameters[ key ] = parameters[ key ].join( '|' );
+                                       } else {
+                                               parameters[ key ] = '\x1f' + parameters[ key ].join( '\x1f' );
+                                       }
+                               } else if ( parameters[ key ] === false || parameters[ key ] === undefined ) {
+                                       // Boolean values are only false when not given at all
+                                       delete parameters[ key ];
+                               }
+                       }
+               },
+
+               /**
+                * Perform the API call.
+                *
+                * @param {Object} parameters
+                * @param {Object} [ajaxOptions]
+                * @return {jQuery.Promise} Done: API response data and the jqXHR object.
+                *  Fail: Error code
+                */
+               ajax: function ( parameters, ajaxOptions ) {
+                       var token, requestIndex,
+                               api = this,
+                               apiDeferred = $.Deferred(),
+                               xhr, key, formData;
+
+                       parameters = $.extend( {}, this.defaults.parameters, parameters );
+                       ajaxOptions = $.extend( {}, this.defaults.ajax, ajaxOptions );
+
+                       // Ensure that token parameter is last (per [[mw:API:Edit#Token]]).
+                       if ( parameters.token ) {
+                               token = parameters.token;
+                               delete parameters.token;
+                       }
+
+                       this.preprocessParameters( parameters, this.defaults.useUS );
+
+                       // If multipart/form-data has been requested and emulation is possible, emulate it
+                       if (
+                               ajaxOptions.type === 'POST' &&
+                               window.FormData &&
+                               ajaxOptions.contentType === 'multipart/form-data'
+                       ) {
+
+                               formData = new FormData();
+
+                               for ( key in parameters ) {
+                                       formData.append( key, parameters[ key ] );
+                               }
+                               // If we extracted a token parameter, add it back in.
+                               if ( token ) {
+                                       formData.append( 'token', token );
+                               }
+
+                               ajaxOptions.data = formData;
+
+                               // Prevent jQuery from mangling our FormData object
+                               ajaxOptions.processData = false;
+                               // Prevent jQuery from overriding the Content-Type header
+                               ajaxOptions.contentType = false;
+                       } else {
+                               // This works because jQuery accepts data as a query string or as an Object
+                               ajaxOptions.data = $.param( parameters );
+                               // If we extracted a token parameter, add it back in.
+                               if ( token ) {
+                                       ajaxOptions.data += '&token=' + encodeURIComponent( token );
+                               }
+
+                               // Depending on server configuration, MediaWiki may forbid periods in URLs, due to an IE 6
+                               // XSS bug. So let's escape them here. See WebRequest::checkUrlExtension() and T30235.
+                               ajaxOptions.data = ajaxOptions.data.replace( /\./g, '%2E' );
+
+                               if ( ajaxOptions.contentType === 'multipart/form-data' ) {
+                                       // We were asked to emulate but can't, so drop the Content-Type header, otherwise
+                                       // it'll be wrong and the server will fail to decode the POST body
+                                       delete ajaxOptions.contentType;
+                               }
+                       }
+
+                       // Make the AJAX request
+                       xhr = $.ajax( ajaxOptions )
+                               // If AJAX fails, reject API call with error code 'http'
+                               // and details in second argument.
+                               .fail( function ( xhr, textStatus, exception ) {
+                                       apiDeferred.reject( 'http', {
+                                               xhr: xhr,
+                                               textStatus: textStatus,
+                                               exception: exception
+                                       } );
+                               } )
+                               // AJAX success just means "200 OK" response, also check API error codes
+                               .done( function ( result, textStatus, jqXHR ) {
+                                       var code;
+                                       if ( result === undefined || result === null || result === '' ) {
+                                               apiDeferred.reject( 'ok-but-empty',
+                                                       'OK response but empty result (check HTTP headers?)',
+                                                       result,
+                                                       jqXHR
+                                               );
+                                       } else if ( result.error ) {
+                                               // errorformat=bc
+                                               code = result.error.code === undefined ? 'unknown' : result.error.code;
+                                               apiDeferred.reject( code, result, result, jqXHR );
+                                       } else if ( result.errors ) {
+                                               // errorformat!=bc
+                                               code = result.errors[ 0 ].code === undefined ? 'unknown' : result.errors[ 0 ].code;
+                                               apiDeferred.reject( code, result, result, jqXHR );
+                                       } else {
+                                               apiDeferred.resolve( result, jqXHR );
+                                       }
+                               } );
+
+                       requestIndex = this.requests.length;
+                       this.requests.push( xhr );
+                       xhr.always( function () {
+                               api.requests[ requestIndex ] = null;
+                       } );
+                       // Return the Promise
+                       return apiDeferred.promise( { abort: xhr.abort } ).fail( function ( code, details ) {
+                               if ( !( code === 'http' && details && details.textStatus === 'abort' ) ) {
+                                       mw.log( 'mw.Api error: ', code, details );
+                               }
+                       } );
+               },
+
+               /**
+                * Post to API with specified type of token. If we have no token, get one and try to post.
+                * If we have a cached token try using that, and if it fails, blank out the
+                * cached token and start over. For example to change an user option you could do:
+                *
+                *     new mw.Api().postWithToken( 'csrf', {
+                *         action: 'options',
+                *         optionname: 'gender',
+                *         optionvalue: 'female'
+                *     } );
+                *
+                * @param {string} tokenType The name of the token, like options or edit.
+                * @param {Object} params API parameters
+                * @param {Object} [ajaxOptions]
+                * @return {jQuery.Promise} See #post
+                * @since 1.22
+                */
+               postWithToken: function ( tokenType, params, ajaxOptions ) {
+                       var api = this,
+                               abortedPromise = $.Deferred().reject( 'http',
+                                       { textStatus: 'abort', exception: 'abort' } ).promise(),
+                               abortable,
+                               aborted;
+
+                       return api.getToken( tokenType, params.assert ).then( function ( token ) {
+                               params.token = token;
+                               // Request was aborted while token request was running, but we
+                               // don't want to unnecessarily abort token requests, so abort
+                               // a fake request instead
+                               if ( aborted ) {
+                                       return abortedPromise;
+                               }
+
+                               return ( abortable = api.post( params, ajaxOptions ) ).catch(
+                                       // Error handler
+                                       function ( code ) {
+                                               if ( code === 'badtoken' ) {
+                                                       api.badToken( tokenType );
+                                                       // Try again, once
+                                                       params.token = undefined;
+                                                       abortable = null;
+                                                       return api.getToken( tokenType, params.assert ).then( function ( token ) {
+                                                               params.token = token;
+                                                               if ( aborted ) {
+                                                                       return abortedPromise;
+                                                               }
+
+                                                               return ( abortable = api.post( params, ajaxOptions ) );
+                                                       } );
+                                               }
+
+                                               // Let caller handle the error code
+                                               return $.Deferred().rejectWith( this, arguments );
+                                       }
+                               );
+                       } ).promise( { abort: function () {
+                               if ( abortable ) {
+                                       abortable.abort();
+                               } else {
+                                       aborted = true;
+                               }
+                       } } );
+               },
+
+               /**
+                * Get a token for a certain action from the API.
+                *
+                * The assert parameter is only for internal use by #postWithToken.
+                *
+                * @since 1.22
+                * @param {string} type Token type
+                * @param {string} [assert]
+                * @return {jQuery.Promise} Received token.
+                */
+               getToken: function ( type, assert ) {
+                       var apiPromise, promiseGroup, d, reject;
+                       type = mapLegacyToken( type );
+                       promiseGroup = promises[ this.defaults.ajax.url ];
+                       d = promiseGroup && promiseGroup[ type + 'Token' ];
+
+                       if ( !promiseGroup ) {
+                               promiseGroup = promises[ this.defaults.ajax.url ] = {};
+                       }
+
+                       if ( !d ) {
+                               apiPromise = this.get( {
+                                       action: 'query',
+                                       meta: 'tokens',
+                                       type: type,
+                                       assert: assert
+                               } );
+                               reject = function () {
+                                       // Clear promise. Do not cache errors.
+                                       delete promiseGroup[ type + 'Token' ];
+
+                                       // Let caller handle the error code
+                                       return $.Deferred().rejectWith( this, arguments );
+                               };
+                               d = apiPromise
+                                       .then( function ( res ) {
+                                               if ( !res.query ) {
+                                                       return reject( 'query-missing', res );
+                                               }
+                                               // If token type is unknown, it is omitted from the response
+                                               if ( !res.query.tokens[ type + 'token' ] ) {
+                                                       return $.Deferred().reject( 'token-missing', res );
+                                               }
+                                               return res.query.tokens[ type + 'token' ];
+                                       }, reject )
+                                       // Attach abort handler
+                                       .promise( { abort: apiPromise.abort } );
+
+                               // Store deferred now so that we can use it again even if it isn't ready yet
+                               promiseGroup[ type + 'Token' ] = d;
+                       }
+
+                       return d;
+               },
+
+               /**
+                * Indicate that the cached token for a certain action of the API is bad.
+                *
+                * Call this if you get a 'badtoken' error when using the token returned by #getToken.
+                * You may also want to use #postWithToken instead, which invalidates bad cached tokens
+                * automatically.
+                *
+                * @param {string} type Token type
+                * @since 1.26
+                */
+               badToken: function ( type ) {
+                       var promiseGroup = promises[ this.defaults.ajax.url ];
+
+                       type = mapLegacyToken( type );
+                       if ( promiseGroup ) {
+                               delete promiseGroup[ type + 'Token' ];
+                       }
+               }
+       };
+
+       /**
+        * @static
+        * @property {Array}
+        * Very incomplete and outdated list of errors we might receive from the API. Do not use.
+        * @deprecated since 1.29
+        */
+       mw.Api.errors = [
+               // occurs when POST aborted
+               // jQuery 1.4 can't distinguish abort or lost connection from 200 OK + empty result
+               'ok-but-empty',
+
+               // timeout
+               'timeout',
+
+               // really a warning, but we treat it like an error
+               'duplicate',
+               'duplicate-archive',
+
+               // upload succeeded, but no image info.
+               // this is probably impossible, but might as well check for it
+               'noimageinfo',
+               // remote errors, defined in API
+               'uploaddisabled',
+               'nomodule',
+               'mustbeposted',
+               'badaccess-groups',
+               'missingresult',
+               'missingparam',
+               'invalid-file-key',
+               'copyuploaddisabled',
+               'mustbeloggedin',
+               'empty-file',
+               'file-too-large',
+               'filetype-missing',
+               'filetype-banned',
+               'filetype-banned-type',
+               'filename-tooshort',
+               'illegal-filename',
+               'verification-error',
+               'hookaborted',
+               'unknown-error',
+               'internal-error',
+               'overwrite',
+               'badtoken',
+               'fetchfileerror',
+               'fileexists-shared-forbidden',
+               'invalidtitle',
+               'notloggedin',
+               'autoblocked',
+               'blocked',
+
+               // Stash-specific errors - expanded
+               'stashfailed',
+               'stasherror',
+               'stashedfilenotfound',
+               'stashpathinvalid',
+               'stashfilestorage',
+               'stashzerolength',
+               'stashnotloggedin',
+               'stashwrongowner',
+               'stashnosuchfilekey'
+       ];
+       mw.log.deprecate( mw.Api, 'errors', mw.Api.errors, null, 'mw.Api.errors' );
+
+       /**
+        * @static
+        * @property {Array}
+        * Very incomplete and outdated list of warnings we might receive from the API. Do not use.
+        * @deprecated since 1.29
+        */
+       mw.Api.warnings = [
+               'duplicate',
+               'exists'
+       ];
+       mw.log.deprecate( mw.Api, 'warnings', mw.Api.warnings, null, 'mw.Api.warnings' );
+
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api/login.js b/resources/src/mediawiki.api/login.js
new file mode 100644 (file)
index 0000000..2b709aa
--- /dev/null
@@ -0,0 +1,60 @@
+/**
+ * Make the two-step login easier.
+ *
+ * @author Niklas Laxström
+ * @class mw.Api.plugin.login
+ * @since 1.22
+ */
+( function ( mw, $ ) {
+       'use strict';
+
+       $.extend( mw.Api.prototype, {
+               /**
+                * @param {string} username
+                * @param {string} password
+                * @return {jQuery.Promise} See mw.Api#post
+                */
+               login: function ( username, password ) {
+                       var params, apiPromise, innerPromise,
+                               api = this;
+
+                       params = {
+                               action: 'login',
+                               lgname: username,
+                               lgpassword: password
+                       };
+
+                       apiPromise = api.post( params );
+
+                       return apiPromise
+                               .then( function ( data ) {
+                                       params.lgtoken = data.login.token;
+                                       innerPromise = api.post( params )
+                                               .then( function ( data ) {
+                                                       var code;
+                                                       if ( data.login.result !== 'Success' ) {
+                                                               // Set proper error code whenever possible
+                                                               code = data.error && data.error.code || 'unknown';
+                                                               return $.Deferred().reject( code, data );
+                                                       }
+                                                       return data;
+                                               } );
+                                       return innerPromise;
+                               } )
+                               .promise( {
+                                       abort: function () {
+                                               apiPromise.abort();
+                                               if ( innerPromise ) {
+                                                       innerPromise.abort();
+                                               }
+                                       }
+                               } );
+               }
+       } );
+
+       /**
+        * @class mw.Api
+        * @mixins mw.Api.plugin.login
+        */
+
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api/messages.js b/resources/src/mediawiki.api/messages.js
new file mode 100644 (file)
index 0000000..688f0b2
--- /dev/null
@@ -0,0 +1,78 @@
+/**
+ * Allows to retrieve a specific or a set of
+ * messages to be added to mw.messages and returned
+ * by the Api.
+ *
+ * @class mw.Api.plugin.messages
+ * @since 1.27
+ */
+( function ( mw, $ ) {
+       'use strict';
+
+       $.extend( mw.Api.prototype, {
+               /**
+                * Get a set of messages.
+                *
+                * @param {Array} messages Messages to retrieve
+                * @param {Object} [options] Additional parameters for the API call
+                * @return {jQuery.Promise}
+                */
+               getMessages: function ( messages, options ) {
+                       options = options || {};
+                       return this.get( $.extend( {
+                               action: 'query',
+                               meta: 'allmessages',
+                               ammessages: messages,
+                               amlang: mw.config.get( 'wgUserLanguage' ),
+                               formatversion: 2
+                       }, options ) ).then( function ( data ) {
+                               var result = {};
+
+                               data.query.allmessages.forEach( function ( obj ) {
+                                       if ( !obj.missing ) {
+                                               result[ obj.name ] = obj.content;
+                                       }
+                               } );
+
+                               return result;
+                       } );
+               },
+
+               /**
+                * Loads a set of messages and add them to mw.messages.
+                *
+                * @param {Array} messages Messages to retrieve
+                * @param {Object} [options] Additional parameters for the API call
+                * @return {jQuery.Promise}
+                */
+               loadMessages: function ( messages, options ) {
+                       return this.getMessages( messages, options ).then( $.proxy( mw.messages, 'set' ) );
+               },
+
+               /**
+                * Loads a set of messages and add them to mw.messages. Only messages that are not already known
+                * are loaded. If all messages are known, the returned promise is resolved immediately.
+                *
+                * @param {Array} messages Messages to retrieve
+                * @param {Object} [options] Additional parameters for the API call
+                * @return {jQuery.Promise}
+                */
+               loadMessagesIfMissing: function ( messages, options ) {
+                       var missing = messages.filter( function ( msg ) {
+                               return !mw.message( msg ).exists();
+                       } );
+
+                       if ( missing.length === 0 ) {
+                               return $.Deferred().resolve();
+                       }
+
+                       return this.getMessages( missing, options ).then( $.proxy( mw.messages, 'set' ) );
+               }
+       } );
+
+       /**
+        * @class mw.Api
+        * @mixins mw.Api.plugin.messages
+        */
+
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api/options.js b/resources/src/mediawiki.api/options.js
new file mode 100644 (file)
index 0000000..4930c4f
--- /dev/null
@@ -0,0 +1,102 @@
+/**
+ * @class mw.Api.plugin.options
+ */
+( function ( mw, $ ) {
+
+       $.extend( mw.Api.prototype, {
+
+               /**
+                * Asynchronously save the value of a single user option using the API. See #saveOptions.
+                *
+                * @param {string} name
+                * @param {string|null} value
+                * @return {jQuery.Promise}
+                */
+               saveOption: function ( name, value ) {
+                       var param = {};
+                       param[ name ] = value;
+                       return this.saveOptions( param );
+               },
+
+               /**
+                * Asynchronously save the values of user options using the API.
+                *
+                * If a value of `null` is provided, the given option will be reset to the default value.
+                *
+                * Any warnings returned by the API, including warnings about invalid option names or values,
+                * are ignored. However, do not rely on this behavior.
+                *
+                * If necessary, the options will be saved using several sequential API requests. Only one promise
+                * is always returned that will be resolved when all requests complete.
+                *
+                * @param {Object} options Options as a `{ name: value, … }` object
+                * @return {jQuery.Promise}
+                */
+               saveOptions: function ( options ) {
+                       var name, value, bundleable,
+                               grouped = [],
+                               promise = $.Deferred().resolve();
+
+                       for ( name in options ) {
+                               value = options[ name ] === null ? null : String( options[ name ] );
+
+                               // Can we bundle this option, or does it need a separate request?
+                               if ( this.defaults.useUS ) {
+                                       bundleable = name.indexOf( '=' ) === -1;
+                               } else {
+                                       bundleable =
+                                               ( value === null || value.indexOf( '|' ) === -1 ) &&
+                                               ( name.indexOf( '|' ) === -1 && name.indexOf( '=' ) === -1 );
+                               }
+
+                               if ( bundleable ) {
+                                       if ( value !== null ) {
+                                               grouped.push( name + '=' + value );
+                                       } else {
+                                               // Omitting value resets the option
+                                               grouped.push( name );
+                                       }
+                               } else {
+                                       if ( value !== null ) {
+                                               promise = promise.then( function ( name, value ) {
+                                                       return this.postWithToken( 'csrf', {
+                                                               formatversion: 2,
+                                                               action: 'options',
+                                                               optionname: name,
+                                                               optionvalue: value
+                                                       } );
+                                               }.bind( this, name, value ) );
+                                       } else {
+                                               // Omitting value resets the option
+                                               promise = promise.then( function ( name ) {
+                                                       return this.postWithToken( 'csrf', {
+                                                               formatversion: 2,
+                                                               action: 'options',
+                                                               optionname: name
+                                                       } );
+                                               }.bind( this, name ) );
+                                       }
+                               }
+                       }
+
+                       if ( grouped.length ) {
+                               promise = promise.then( function () {
+                                       return this.postWithToken( 'csrf', {
+                                               formatversion: 2,
+                                               action: 'options',
+                                               change: grouped
+                                       } );
+                               }.bind( this ) );
+                       }
+
+                       return promise;
+               }
+
+       } );
+
+       /**
+        * @class mw.Api
+        * @mixins mw.Api.plugin.options
+        */
+
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api/parse.js b/resources/src/mediawiki.api/parse.js
new file mode 100644 (file)
index 0000000..f38e88b
--- /dev/null
@@ -0,0 +1,49 @@
+/**
+ * @class mw.Api.plugin.parse
+ */
+( function ( mw, $ ) {
+
+       $.extend( mw.Api.prototype, {
+               /**
+                * Convenience method for 'action=parse'.
+                *
+                * @param {string|mw.Title} content Content to parse, either as a wikitext string or
+                *   a mw.Title.
+                * @param {Object} additionalParams Parameters object to set custom settings, e.g.
+                *   redirects, sectionpreview.  prop should not be overridden.
+                * @return {jQuery.Promise}
+                * @return {Function} return.done
+                * @return {string} return.done.data Parsed HTML of `wikitext`.
+                */
+               parse: function ( content, additionalParams ) {
+                       var apiPromise,
+                               config = $.extend( {
+                                       formatversion: 2,
+                                       action: 'parse',
+                                       contentmodel: 'wikitext'
+                               }, additionalParams );
+
+                       if ( mw.Title && content instanceof mw.Title ) {
+                               // Parse existing page
+                               config.page = content.getPrefixedDb();
+                       } else {
+                               // Parse wikitext from input
+                               config.text = String( content );
+                       }
+
+                       apiPromise = this.get( config );
+
+                       return apiPromise
+                               .then( function ( data ) {
+                                       return data.parse.text;
+                               } )
+                               .promise( { abort: apiPromise.abort } );
+               }
+       } );
+
+       /**
+        * @class mw.Api
+        * @mixins mw.Api.plugin.parse
+        */
+
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api/rollback.js b/resources/src/mediawiki.api/rollback.js
new file mode 100644 (file)
index 0000000..322143d
--- /dev/null
@@ -0,0 +1,33 @@
+/**
+ * @class mw.Api.plugin.rollback
+ * @since 1.28
+ */
+( function ( mw, $ ) {
+
+       $.extend( mw.Api.prototype, {
+               /**
+                * Convenience method for `action=rollback`.
+                *
+                * @param {string|mw.Title} page
+                * @param {string} user
+                * @param {Object} [params] Additional parameters
+                * @return {jQuery.Promise}
+                */
+               rollback: function ( page, user, params ) {
+                       return this.postWithToken( 'rollback', $.extend( {
+                               action: 'rollback',
+                               title: String( page ),
+                               user: user,
+                               uselang: mw.config.get( 'wgUserLanguage' )
+                       }, params ) ).then( function ( data ) {
+                               return data.rollback;
+                       } );
+               }
+       } );
+
+       /**
+        * @class mw.Api
+        * @mixins mw.Api.plugin.rollback
+        */
+
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api/upload.js b/resources/src/mediawiki.api/upload.js
new file mode 100644 (file)
index 0000000..29bd59a
--- /dev/null
@@ -0,0 +1,668 @@
+/**
+ * Provides an interface for uploading files to MediaWiki.
+ *
+ * @class mw.Api.plugin.upload
+ * @singleton
+ */
+( function ( mw, $ ) {
+       var nonce = 0,
+               fieldsAllowed = {
+                       stash: true,
+                       filekey: true,
+                       filename: true,
+                       comment: true,
+                       text: true,
+                       watchlist: true,
+                       ignorewarnings: true,
+                       chunk: true,
+                       offset: true,
+                       filesize: true,
+                       async: true
+               };
+
+       /**
+        * Get nonce for iframe IDs on the page.
+        *
+        * @private
+        * @return {number}
+        */
+       function getNonce() {
+               return nonce++;
+       }
+
+       /**
+        * Given a non-empty object, return one of its keys.
+        *
+        * @private
+        * @param {Object} obj
+        * @return {string}
+        */
+       function getFirstKey( obj ) {
+               var key;
+               for ( key in obj ) {
+                       if ( obj.hasOwnProperty( key ) ) {
+                               return key;
+                       }
+               }
+       }
+
+       /**
+        * Get new iframe object for an upload.
+        *
+        * @private
+        * @param {string} id
+        * @return {HTMLIframeElement}
+        */
+       function getNewIframe( id ) {
+               var frame = document.createElement( 'iframe' );
+               frame.id = id;
+               frame.name = id;
+               return frame;
+       }
+
+       /**
+        * Shortcut for getting hidden inputs
+        *
+        * @private
+        * @param {string} name
+        * @param {string} val
+        * @return {jQuery}
+        */
+       function getHiddenInput( name, val ) {
+               return $( '<input>' ).attr( 'type', 'hidden' )
+                       .attr( 'name', name )
+                       .val( val );
+       }
+
+       /**
+        * Process the result of the form submission, returned to an iframe.
+        * This is the iframe's onload event.
+        *
+        * @param {HTMLIframeElement} iframe Iframe to extract result from
+        * @return {Object} Response from the server. The return value may or may
+        *   not be an XMLDocument, this code was copied from elsewhere, so if you
+        *   see an unexpected return type, please file a bug.
+        */
+       function processIframeResult( iframe ) {
+               var json,
+                       doc = iframe.contentDocument || frames[ iframe.id ].document;
+
+               if ( doc.XMLDocument ) {
+                       // The response is a document property in IE
+                       return doc.XMLDocument;
+               }
+
+               if ( doc.body ) {
+                       // Get the json string
+                       // We're actually searching through an HTML doc here --
+                       // according to mdale we need to do this
+                       // because IE does not load JSON properly in an iframe
+                       json = $( doc.body ).find( 'pre' ).text();
+
+                       return JSON.parse( json );
+               }
+
+               // Response is a xml document
+               return doc;
+       }
+
+       function formDataAvailable() {
+               return window.FormData !== undefined &&
+                       window.File !== undefined &&
+                       window.File.prototype.slice !== undefined;
+       }
+
+       $.extend( mw.Api.prototype, {
+               /**
+                * Upload a file to MediaWiki.
+                *
+                * The file will be uploaded using AJAX and FormData, if the browser supports it, or via an
+                * iframe if it doesn't.
+                *
+                * Caveats of iframe upload:
+                * - The returned jQuery.Promise will not receive `progress` notifications during the upload
+                * - It is incompatible with uploads to a foreign wiki using mw.ForeignApi
+                * - You must pass a HTMLInputElement and not a File for it to be possible
+                *
+                * @param {HTMLInputElement|File|Blob} file HTML input type=file element with a file already inside
+                *  of it, or a File object.
+                * @param {Object} data Other upload options, see action=upload API docs for more
+                * @return {jQuery.Promise}
+                */
+               upload: function ( file, data ) {
+                       var isFileInput, canUseFormData;
+
+                       isFileInput = file && file.nodeType === Node.ELEMENT_NODE;
+
+                       if ( formDataAvailable() && isFileInput && file.files ) {
+                               file = file.files[ 0 ];
+                       }
+
+                       if ( !file ) {
+                               throw new Error( 'No file' );
+                       }
+
+                       // Blobs are allowed in formdata uploads, it turns out
+                       canUseFormData = formDataAvailable() && ( file instanceof window.File || file instanceof window.Blob );
+
+                       if ( !isFileInput && !canUseFormData ) {
+                               throw new Error( 'Unsupported argument type passed to mw.Api.upload' );
+                       }
+
+                       if ( canUseFormData ) {
+                               return this.uploadWithFormData( file, data );
+                       }
+
+                       return this.uploadWithIframe( file, data );
+               },
+
+               /**
+                * Upload a file to MediaWiki with an iframe and a form.
+                *
+                * This method is necessary for browsers without the File/FormData
+                * APIs, and continues to work in browsers with those APIs.
+                *
+                * The rough sketch of how this method works is as follows:
+                * 1. An iframe is loaded with no content.
+                * 2. A form is submitted with the passed-in file input and some extras.
+                * 3. The MediaWiki API receives that form data, and sends back a response.
+                * 4. The response is sent to the iframe, because we set target=(iframe id)
+                * 5. The response is parsed out of the iframe's document, and passed back
+                *    through the promise.
+                *
+                * @private
+                * @param {HTMLInputElement} file The file input with a file in it.
+                * @param {Object} data Other upload options, see action=upload API docs for more
+                * @return {jQuery.Promise}
+                */
+               uploadWithIframe: function ( file, data ) {
+                       var key,
+                               tokenPromise = $.Deferred(),
+                               api = this,
+                               deferred = $.Deferred(),
+                               nonce = getNonce(),
+                               id = 'uploadframe-' + nonce,
+                               $form = $( '<form>' ),
+                               iframe = getNewIframe( id ),
+                               $iframe = $( iframe );
+
+                       for ( key in data ) {
+                               if ( !fieldsAllowed[ key ] ) {
+                                       delete data[ key ];
+                               }
+                       }
+
+                       data = $.extend( {}, this.defaults.parameters, { action: 'upload' }, data );
+                       $form.addClass( 'mw-api-upload-form' );
+
+                       $form.css( 'display', 'none' )
+                               .attr( {
+                                       action: this.defaults.ajax.url,
+                                       method: 'POST',
+                                       target: id,
+                                       enctype: 'multipart/form-data'
+                               } );
+
+                       $iframe.one( 'load', function () {
+                               $iframe.one( 'load', function () {
+                                       var result = processIframeResult( iframe );
+                                       deferred.notify( 1 );
+
+                                       if ( !result ) {
+                                               deferred.reject( 'ok-but-empty', 'No response from API on upload attempt.' );
+                                       } else if ( result.error ) {
+                                               if ( result.error.code === 'badtoken' ) {
+                                                       api.badToken( 'csrf' );
+                                               }
+
+                                               deferred.reject( result.error.code, result );
+                                       } else if ( result.upload && result.upload.warnings ) {
+                                               deferred.reject( getFirstKey( result.upload.warnings ), result );
+                                       } else {
+                                               deferred.resolve( result );
+                                       }
+                               } );
+                               tokenPromise.done( function () {
+                                       $form.submit();
+                               } );
+                       } );
+
+                       $iframe.on( 'error', function ( error ) {
+                               deferred.reject( 'http', error );
+                       } );
+
+                       $iframe.prop( 'src', 'about:blank' ).hide();
+
+                       file.name = 'file';
+
+                       $.each( data, function ( key, val ) {
+                               $form.append( getHiddenInput( key, val ) );
+                       } );
+
+                       if ( !data.filename && !data.stash ) {
+                               throw new Error( 'Filename not included in file data.' );
+                       }
+
+                       if ( this.needToken() ) {
+                               this.getEditToken().then( function ( token ) {
+                                       $form.append( getHiddenInput( 'token', token ) );
+                                       tokenPromise.resolve();
+                               }, tokenPromise.reject );
+                       } else {
+                               tokenPromise.resolve();
+                       }
+
+                       $( 'body' ).append( $form, $iframe );
+
+                       deferred.always( function () {
+                               $form.remove();
+                               $iframe.remove();
+                       } );
+
+                       return deferred.promise();
+               },
+
+               /**
+                * Uploads a file using the FormData API.
+                *
+                * @private
+                * @param {File} file
+                * @param {Object} data Other upload options, see action=upload API docs for more
+                * @return {jQuery.Promise}
+                */
+               uploadWithFormData: function ( file, data ) {
+                       var key, request,
+                               deferred = $.Deferred();
+
+                       for ( key in data ) {
+                               if ( !fieldsAllowed[ key ] ) {
+                                       delete data[ key ];
+                               }
+                       }
+
+                       data = $.extend( {}, this.defaults.parameters, { action: 'upload' }, data );
+                       if ( !data.chunk ) {
+                               data.file = file;
+                       }
+
+                       if ( !data.filename && !data.stash ) {
+                               throw new Error( 'Filename not included in file data.' );
+                       }
+
+                       // Use this.postWithEditToken() or this.post()
+                       request = this[ this.needToken() ? 'postWithEditToken' : 'post' ]( data, {
+                               // Use FormData (if we got here, we know that it's available)
+                               contentType: 'multipart/form-data',
+                               // No timeout (default from mw.Api is 30 seconds)
+                               timeout: 0,
+                               // Provide upload progress notifications
+                               xhr: function () {
+                                       var xhr = $.ajaxSettings.xhr();
+                                       if ( xhr.upload ) {
+                                               // need to bind this event before we open the connection (see note at
+                                               // https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest#Monitoring_progress)
+                                               xhr.upload.addEventListener( 'progress', function ( ev ) {
+                                                       if ( ev.lengthComputable ) {
+                                                               deferred.notify( ev.loaded / ev.total );
+                                                       }
+                                               } );
+                                       }
+                                       return xhr;
+                               }
+                       } )
+                               .done( function ( result ) {
+                                       deferred.notify( 1 );
+                                       if ( result.upload && result.upload.warnings ) {
+                                               deferred.reject( getFirstKey( result.upload.warnings ), result );
+                                       } else {
+                                               deferred.resolve( result );
+                                       }
+                               } )
+                               .fail( function ( errorCode, result ) {
+                                       deferred.notify( 1 );
+                                       deferred.reject( errorCode, result );
+                               } );
+
+                       return deferred.promise( { abort: request.abort } );
+               },
+
+               /**
+                * Upload a file in several chunks.
+                *
+                * @param {File} file
+                * @param {Object} data Other upload options, see action=upload API docs for more
+                * @param {number} [chunkSize] Size (in bytes) per chunk (default: 5MB)
+                * @param {number} [chunkRetries] Amount of times to retry a failed chunk (default: 1)
+                * @return {jQuery.Promise}
+                */
+               chunkedUpload: function ( file, data, chunkSize, chunkRetries ) {
+                       var start, end, promise, next, active,
+                               deferred = $.Deferred();
+
+                       chunkSize = chunkSize === undefined ? 5 * 1024 * 1024 : chunkSize;
+                       chunkRetries = chunkRetries === undefined ? 1 : chunkRetries;
+
+                       if ( !data.filename ) {
+                               throw new Error( 'Filename not included in file data.' );
+                       }
+
+                       // Submit first chunk to get the filekey
+                       active = promise = this.uploadChunk( file, data, 0, chunkSize, '', chunkRetries )
+                               .done( chunkSize >= file.size ? deferred.resolve : null )
+                               .fail( deferred.reject )
+                               .progress( deferred.notify );
+
+                       // Now iteratively submit the rest of the chunks
+                       for ( start = chunkSize; start < file.size; start += chunkSize ) {
+                               end = Math.min( start + chunkSize, file.size );
+                               next = $.Deferred();
+
+                               // We could simply chain one this.uploadChunk after another with
+                               // .then(), but then we'd hit an `Uncaught RangeError: Maximum
+                               // call stack size exceeded` at as low as 1024 calls in Firefox
+                               // 47. This'll work around it, but comes with the drawback of
+                               // having to properly relay the results to the returned promise.
+                               // eslint-disable-next-line no-loop-func
+                               promise.done( function ( start, end, next, result ) {
+                                       var filekey = result.upload.filekey;
+                                       active = this.uploadChunk( file, data, start, end, filekey, chunkRetries )
+                                               .done( end === file.size ? deferred.resolve : next.resolve )
+                                               .fail( deferred.reject )
+                                               .progress( deferred.notify );
+                               // start, end & next must be bound to closure, or they'd have
+                               // changed by the time the promises are resolved
+                               }.bind( this, start, end, next ) );
+
+                               promise = next;
+                       }
+
+                       return deferred.promise( { abort: active.abort } );
+               },
+
+               /**
+                * Uploads 1 chunk.
+                *
+                * @private
+                * @param {File} file
+                * @param {Object} data Other upload options, see action=upload API docs for more
+                * @param {number} start Chunk start position
+                * @param {number} end Chunk end position
+                * @param {string} [filekey] File key, for follow-up chunks
+                * @param {number} [retries] Amount of times to retry request
+                * @return {jQuery.Promise}
+                */
+               uploadChunk: function ( file, data, start, end, filekey, retries ) {
+                       var upload,
+                               api = this,
+                               chunk = this.slice( file, start, end );
+
+                       // When uploading in chunks, we're going to be issuing a lot more
+                       // requests and there's always a chance of 1 getting dropped.
+                       // In such case, it could be useful to try again: a network hickup
+                       // doesn't necessarily have to result in upload failure...
+                       retries = retries === undefined ? 1 : retries;
+
+                       data.filesize = file.size;
+                       data.chunk = chunk;
+                       data.offset = start;
+
+                       // filekey must only be added when uploading follow-up chunks; the
+                       // first chunk should never have a filekey (it'll be generated)
+                       if ( filekey && start !== 0 ) {
+                               data.filekey = filekey;
+                       }
+
+                       upload = this.uploadWithFormData( file, data );
+                       return upload.then(
+                               null,
+                               function ( code, result ) {
+                                       var retry;
+
+                                       // uploadWithFormData will reject uploads with warnings, but
+                                       // these warnings could be "harmless" or recovered from
+                                       // (e.g. exists-normalized, when it'll be renamed later)
+                                       // In the case of (only) a warning, we still want to
+                                       // continue the chunked upload until it completes: then
+                                       // reject it - at least it's been fully uploaded by then and
+                                       // failure handlers have a complete result object (including
+                                       // possibly more warnings, e.g. duplicate)
+                                       // This matches .upload, which also completes the upload.
+                                       if ( result.upload && result.upload.warnings && code in result.upload.warnings ) {
+                                               if ( end === file.size ) {
+                                                       // uploaded last chunk = reject with result data
+                                                       return $.Deferred().reject( code, result );
+                                               } else {
+                                                       // still uploading chunks = resolve to keep going
+                                                       return $.Deferred().resolve( result );
+                                               }
+                                       }
+
+                                       if ( retries === 0 ) {
+                                               return $.Deferred().reject( code, result );
+                                       }
+
+                                       // If the call flat out failed, we may want to try again...
+                                       retry = api.uploadChunk.bind( this, file, data, start, end, filekey, retries - 1 );
+                                       return api.retry( code, result, retry );
+                               },
+                               function ( fraction ) {
+                                       // Since we're only uploading small parts of a file, we
+                                       // need to adjust the reported progress to reflect where
+                                       // we actually are in the combined upload
+                                       return ( start + fraction * ( end - start ) ) / file.size;
+                               }
+                       ).promise( { abort: upload.abort } );
+               },
+
+               /**
+                * Launch the upload anew if it failed because of network issues.
+                *
+                * @private
+                * @param {string} code Error code
+                * @param {Object} result API result
+                * @param {Function} callable
+                * @return {jQuery.Promise}
+                */
+               retry: function ( code, result, callable ) {
+                       var uploadPromise,
+                               retryTimer,
+                               deferred = $.Deferred(),
+                               // Wrap around the callable, so that once it completes, it'll
+                               // resolve/reject the promise we'll return
+                               retry = function () {
+                                       uploadPromise = callable();
+                                       uploadPromise.then( deferred.resolve, deferred.reject );
+                               };
+
+                       // Don't retry if the request failed because we aborted it (or if
+                       // it's another kind of request failure)
+                       if ( code !== 'http' || result.textStatus === 'abort' ) {
+                               return deferred.reject( code, result );
+                       }
+
+                       retryTimer = setTimeout( retry, 1000 );
+                       return deferred.promise( { abort: function () {
+                               // Clear the scheduled upload, or abort if already in flight
+                               if ( retryTimer ) {
+                                       clearTimeout( retryTimer );
+                               }
+                               if ( uploadPromise.abort ) {
+                                       uploadPromise.abort();
+                               }
+                       } } );
+               },
+
+               /**
+                * Slice a chunk out of a File object.
+                *
+                * @private
+                * @param {File} file
+                * @param {number} start
+                * @param {number} stop
+                * @return {Blob}
+                */
+               slice: function ( file, start, stop ) {
+                       if ( file.mozSlice ) {
+                               // FF <= 12
+                               return file.mozSlice( start, stop, file.type );
+                       } else if ( file.webkitSlice ) {
+                               // Chrome <= 20
+                               return file.webkitSlice( start, stop, file.type );
+                       } else {
+                               // On really old browser versions (before slice was prefixed),
+                               // slice() would take (start, length) instead of (start, end)
+                               // We'll ignore that here...
+                               return file.slice( start, stop, file.type );
+                       }
+               },
+
+               /**
+                * This function will handle how uploads to stash (via uploadToStash or
+                * chunkedUploadToStash) are resolved/rejected.
+                *
+                * After a successful stash, it'll resolve with a callback which, when
+                * called, will finalize the upload in stash (with the given data, or
+                * with additional/conflicting data)
+                *
+                * A failed stash can still be recovered from as long as 'filekey' is
+                * present. In that case, it'll also resolve with the callback to
+                * finalize the upload (all warnings are then ignored.)
+                * Otherwise, it'll just reject as you'd expect, with code & result.
+                *
+                * @private
+                * @param {jQuery.Promise} uploadPromise
+                * @param {Object} data
+                * @return {jQuery.Promise}
+                * @return {Function} return.finishUpload Call this function to finish the upload.
+                * @return {Object} return.finishUpload.data Additional data for the upload.
+                * @return {jQuery.Promise} return.finishUpload.return API promise for the final upload
+                * @return {Object} return.finishUpload.return.data API return value for the final upload
+                */
+               finishUploadToStash: function ( uploadPromise, data ) {
+                       var filekey,
+                               api = this;
+
+                       function finishUpload( moreData ) {
+                               return api.uploadFromStash( filekey, $.extend( data, moreData ) );
+                       }
+
+                       return uploadPromise.then(
+                               function ( result ) {
+                                       filekey = result.upload.filekey;
+                                       return finishUpload;
+                               },
+                               function ( errorCode, result ) {
+                                       if ( result && result.upload && result.upload.filekey ) {
+                                               // Ignore any warnings if 'filekey' was returned, that's all we care about
+                                               filekey = result.upload.filekey;
+                                               return $.Deferred().resolve( finishUpload );
+                                       }
+                                       return $.Deferred().reject( errorCode, result );
+                               }
+                       );
+               },
+
+               /**
+                * Upload a file to the stash.
+                *
+                * This function will return a promise, which when resolved, will pass back a function
+                * to finish the stash upload. You can call that function with an argument containing
+                * more, or conflicting, data to pass to the server. For example:
+                *
+                *     // upload a file to the stash with a placeholder filename
+                *     api.uploadToStash( file, { filename: 'testing.png' } ).done( function ( finish ) {
+                *         // finish is now the function we can use to finalize the upload
+                *         // pass it a new filename from user input to override the initial value
+                *         finish( { filename: getFilenameFromUser() } ).done( function ( data ) {
+                *             // the upload is complete, data holds the API response
+                *         } );
+                *     } );
+                *
+                * @param {File|HTMLInputElement} file
+                * @param {Object} [data]
+                * @return {jQuery.Promise}
+                * @return {Function} return.finishUpload Call this function to finish the upload.
+                * @return {Object} return.finishUpload.data Additional data for the upload.
+                * @return {jQuery.Promise} return.finishUpload.return API promise for the final upload
+                * @return {Object} return.finishUpload.return.data API return value for the final upload
+                */
+               uploadToStash: function ( file, data ) {
+                       var promise;
+
+                       if ( !data.filename ) {
+                               throw new Error( 'Filename not included in file data.' );
+                       }
+
+                       promise = this.upload( file, { stash: true, filename: data.filename } );
+
+                       return this.finishUploadToStash( promise, data );
+               },
+
+               /**
+                * Upload a file to the stash, in chunks.
+                *
+                * This function will return a promise, which when resolved, will pass back a function
+                * to finish the stash upload.
+                *
+                * @see #method-uploadToStash
+                * @param {File|HTMLInputElement} file
+                * @param {Object} [data]
+                * @param {number} [chunkSize] Size (in bytes) per chunk (default: 5MB)
+                * @param {number} [chunkRetries] Amount of times to retry a failed chunk (default: 1)
+                * @return {jQuery.Promise}
+                * @return {Function} return.finishUpload Call this function to finish the upload.
+                * @return {Object} return.finishUpload.data Additional data for the upload.
+                * @return {jQuery.Promise} return.finishUpload.return API promise for the final upload
+                * @return {Object} return.finishUpload.return.data API return value for the final upload
+                */
+               chunkedUploadToStash: function ( file, data, chunkSize, chunkRetries ) {
+                       var promise;
+
+                       if ( !data.filename ) {
+                               throw new Error( 'Filename not included in file data.' );
+                       }
+
+                       promise = this.chunkedUpload(
+                               file,
+                               { stash: true, filename: data.filename },
+                               chunkSize,
+                               chunkRetries
+                       );
+
+                       return this.finishUploadToStash( promise, data );
+               },
+
+               /**
+                * Finish an upload in the stash.
+                *
+                * @param {string} filekey
+                * @param {Object} data
+                * @return {jQuery.Promise}
+                */
+               uploadFromStash: function ( filekey, data ) {
+                       data.filekey = filekey;
+                       data.action = 'upload';
+                       data.format = 'json';
+
+                       if ( !data.filename ) {
+                               throw new Error( 'Filename not included in file data.' );
+                       }
+
+                       return this.postWithEditToken( data ).then( function ( result ) {
+                               if ( result.upload && result.upload.warnings ) {
+                                       return $.Deferred().reject( getFirstKey( result.upload.warnings ), result ).promise();
+                               }
+                               return result;
+                       } );
+               },
+
+               needToken: function () {
+                       return true;
+               }
+       } );
+
+       /**
+        * @class mw.Api
+        * @mixins mw.Api.plugin.upload
+        */
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api/user.js b/resources/src/mediawiki.api/user.js
new file mode 100644 (file)
index 0000000..e7b4b6d
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * @class mw.Api.plugin.user
+ * @since 1.27
+ */
+( function ( mw, $ ) {
+
+       $.extend( mw.Api.prototype, {
+
+               /**
+                * Get the current user's groups and rights.
+                *
+                * @return {jQuery.Promise}
+                * @return {Function} return.done
+                * @return {Object} return.done.userInfo
+                * @return {string[]} return.done.userInfo.groups User groups that the current user belongs to
+                * @return {string[]} return.done.userInfo.rights Current user's rights
+                */
+               getUserInfo: function () {
+                       return this.get( {
+                               action: 'query',
+                               meta: 'userinfo',
+                               uiprop: [ 'groups', 'rights' ]
+                       } ).then( function ( data ) {
+                               if ( data.query && data.query.userinfo ) {
+                                       return data.query.userinfo;
+                               }
+                               return $.Deferred().reject().promise();
+                       } );
+               }
+       } );
+
+       /**
+        * @class mw.Api
+        * @mixins mw.Api.plugin.user
+        */
+
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.api/watch.js b/resources/src/mediawiki.api/watch.js
new file mode 100644 (file)
index 0000000..025c111
--- /dev/null
@@ -0,0 +1,70 @@
+/**
+ * @class mw.Api.plugin.watch
+ * @since 1.19
+ */
+( function ( mw, $ ) {
+
+       /**
+        * @private
+        * @static
+        * @context mw.Api
+        *
+        * @param {string|mw.Title|string[]|mw.Title[]} pages Full page name or instance of mw.Title, or an
+        *  array thereof. If an array is passed, the return value passed to the promise will also be an
+        *  array of appropriate objects.
+        * @param {Object} [addParams]
+        * @return {jQuery.Promise}
+        * @return {Function} return.done
+        * @return {Object|Object[]} return.done.watch Object or list of objects (depends on the `pages`
+        *  parameter)
+        * @return {string} return.done.watch.title Full pagename
+        * @return {boolean} return.done.watch.watched Whether the page is now watched or unwatched
+        */
+       function doWatchInternal( pages, addParams ) {
+               // XXX: Parameter addParams is undocumented because we inherit this
+               // documentation in the public method...
+               var apiPromise = this.postWithToken( 'watch',
+                       $.extend(
+                               {
+                                       formatversion: 2,
+                                       action: 'watch',
+                                       titles: Array.isArray( pages ) ? pages : String( pages )
+                               },
+                               addParams
+                       )
+               );
+
+               return apiPromise
+                       .then( function ( data ) {
+                               // If a single page was given (not an array) respond with a single item as well.
+                               return Array.isArray( pages ) ? data.watch : data.watch[ 0 ];
+                       } )
+                       .promise( { abort: apiPromise.abort } );
+       }
+
+       $.extend( mw.Api.prototype, {
+               /**
+                * Convenience method for `action=watch`.
+                *
+                * @inheritdoc #doWatchInternal
+                */
+               watch: function ( pages ) {
+                       return doWatchInternal.call( this, pages );
+               },
+
+               /**
+                * Convenience method for `action=watch&unwatch=1`.
+                *
+                * @inheritdoc #doWatchInternal
+                */
+               unwatch: function ( pages ) {
+                       return doWatchInternal.call( this, pages, { unwatch: 1 } );
+               }
+       } );
+
+       /**
+        * @class mw.Api
+        * @mixins mw.Api.plugin.watch
+        */
+
+}( mediaWiki, jQuery ) );
index 830ff33..3f5a5db 100644 (file)
 
                        bitDiv( 'phpversion' )
                                .append( $( this.data.phpEngine === 'HHVM' ?
-                                       '<a href="http://hhvm.com/">HHVM</a>' :
+                                       '<a href="https://hhvm.com/">HHVM</a>' :
                                        '<a href="https://php.net/">PHP</a>'
                                ) )
                                .append( ': ' + this.data.phpVersion );
diff --git a/resources/src/mediawiki.debug/jquery.footHovzer.css b/resources/src/mediawiki.debug/jquery.footHovzer.css
new file mode 100644 (file)
index 0000000..77d9514
--- /dev/null
@@ -0,0 +1,6 @@
+#jquery-foot-hovzer {
+       position: fixed;
+       bottom: 0;
+       width: 100%;
+       z-index: 1000;
+}
diff --git a/resources/src/mediawiki.debug/jquery.footHovzer.js b/resources/src/mediawiki.debug/jquery.footHovzer.js
new file mode 100644 (file)
index 0000000..091aa25
--- /dev/null
@@ -0,0 +1,67 @@
+/**
+ * @private
+ * @class jQuery.plugin.footHovzer
+ */
+( function ( $ ) {
+       var $hovzer, footHovzer, $spacer;
+
+       function getHovzer() {
+               if ( $hovzer === undefined ) {
+                       $hovzer = $( '<div id="jquery-foot-hovzer"></div>' ).appendTo( 'body' );
+               }
+               return $hovzer;
+       }
+
+       /**
+        * Utility to stack stuff in an overlay fixed on the bottom of the page.
+        *
+        * Usage:
+        *
+        *     var hovzer = $.getFootHovzer();
+        *     hovzer.$.append( $myCollection );
+        *     hovzer.update();
+        *
+        * @static
+        * @inheritable
+        * @return {jQuery.footHovzer}
+        */
+       $.getFootHovzer = function () {
+               footHovzer.$ = getHovzer();
+               return footHovzer;
+       };
+
+       /**
+        * @private
+        * @class jQuery.footHovzer
+        */
+       footHovzer = {
+
+               /**
+                * @property {jQuery} $ The stack container
+                */
+
+               /**
+                * Update dimensions of stack to account for changes in the subtree.
+                */
+               update: function () {
+                       var $body;
+
+                       $body = $( 'body' );
+
+                       if ( $spacer === undefined ) {
+                               $spacer = $( '<div>' ).attr( 'id', 'jquery-foot-hovzer-spacer' );
+                               $spacer.appendTo( $body );
+                       }
+                       // Ensure CSS is applied by browser before using .outerHeight()
+                       setTimeout( function () {
+                               $spacer.css( 'height', getHovzer().outerHeight( /* includeMargin = */ true ) );
+                       }, 0 );
+               }
+       };
+
+       /**
+        * @class jQuery
+        * @mixins jQuery.plugin.footHovzer
+        */
+
+}( jQuery ) );
index 61a1c9c..0b56df1 100644 (file)
@@ -6,6 +6,8 @@
 
 @ooui-spacing-medium: 12 / @ooui-font-size-browser / @ooui-font-size-base; // equals `0.8571429em`≈`12px`
 @ooui-spacing-large: 16 / @ooui-font-size-browser / @ooui-font-size-base; // equals `1.1428571em`≈`16px`
+@ooui-padding-horizontal: 12 / @ooui-font-size-browser / @ooui-font-size-base;
+@ooui-padding-vertical: 4 / @ooui-font-size-browser / @ooui-font-size-base; // equals `0.285714em`≈`4px`
 
 .mw-htmlform-ooui-wrapper.oo-ui-panelLayout-padded {
        padding: @ooui-spacing-medium @ooui-spacing-large @ooui-spacing-large;
        }
 
        .mw-htmlform-matrix {
-               border-spacing: 0;
+               border-spacing: 0 2px;
 
                td {
-                       padding: 0.35em 0.7em;
+                       padding: @ooui-padding-vertical @ooui-padding-horizontal;
+                       text-align: center;
                        .transition( background-color 250ms );
+
+                       &:first-child {
+                               text-align: left;
+                       }
                }
 
                tbody tr:nth-child( even ) td {
@@ -40,6 +47,7 @@
 
                tbody tr:first-child td {
                        background-color: #fff;
+                       padding-bottom: 0;
                }
 
                td.first {
index e5cf26e..077473b 100644 (file)
                        if ( !( langData[ langCode ] instanceof mw.Map ) ) {
                                langData[ langCode ] = new mw.Map();
                        }
-                       langData[ langCode ].set( dataKey, value );
+                       if ( arguments.length > 2 ) {
+                               langData[ langCode ].set( dataKey, value );
+                       } else {
+                               langData[ langCode ].set( dataKey );
+                       }
                }
        };
 
index 2392089..267210c 100644 (file)
                /**
                 * Apply pattern to format value as a string.
                 *
-                * Using patterns from [Unicode TR35](http://www.unicode.org/reports/tr35/#Number_Format_Patterns).
+                * Using patterns from [Unicode TR35](https://www.unicode.org/reports/tr35/#Number_Format_Patterns).
                 *
                 * @param {number} value
                 * @param {string} pattern Pattern string as described by Unicode TR35
index b95a436..ac65ac7 100644 (file)
@@ -215,7 +215,7 @@ table.toc td {
 }
 
 /* preference page with js-genrated toc */
-/* TODO: Delete #preftoc when Special:Preference's non-OOUI mode is disabled */
+/* TODO: Delete #preftoc when Special:Preferences's non-OOUI mode is disabled */
 #preftoc {
        float: left;
        margin: 1em 1em 1em 1em;
index 53dccc2..55be237 100644 (file)
@@ -1,6 +1,6 @@
 // Common Less mixin library for MediaWiki
 //
-// By default the folder containing this file is included in $wgResourceLoaderLESSImportPaths,
+// By default the folder containing this file is included in the LESS import paths,
 // which makes this file importable by all less files via `@import 'mediawiki.mixins';`.
 //
 // The mixins included below are considered a public interface for MediaWiki extensions.
index 79937e5..892f044 100644 (file)
@@ -1,10 +1,14 @@
 /*!
- * Show gallery captions when focused. Copied directly from jquery.mw-jump.js.
- * Also Dynamically resize images to justify them.
+ * Enhance MediaWiki galleries (from the `<gallery>` parser tag).
+ *
+ * - Toggle gallery captions when focused.
+ * - Dynamically resize images to fill horizontal space.
  */
 ( function ( mw, $ ) {
        var $galleries,
                bound = false,
+               lastWidth = window.innerWidth,
+               justifyNeeded = false,
                // Is there a better way to detect a touchscreen? Current check taken from stack overflow.
                isTouchScreen = !!( window.ontouchstart !== undefined ||
                        window.DocumentTouch !== undefined && document instanceof window.DocumentTouch
        }
 
        function handleResizeStart() {
+               // Only do anything if window width changed. We don't care about the height.
+               if ( lastWidth === window.innerWidth ) {
+                       return;
+               }
+
+               justifyNeeded = true;
+               // Temporarily set min-height, so that content following the gallery is not reflowed twice
+               $galleries.css( 'min-height', function () {
+                       return $( this ).height();
+               } );
                $galleries.children( 'li.gallerybox' ).each( function () {
                        var imgWidth = $( this ).data( 'imgWidth' ),
                                imgHeight = $( this ).data( 'imgHeight' ),
        }
 
        function handleResizeEnd() {
-               $galleries.each( justify );
+               // If window width never changed during the resize, don't do anything.
+               if ( justifyNeeded ) {
+                       justifyNeeded = false;
+                       lastWidth = window.innerWidth;
+                       $galleries
+                               // Remove temporary min-height
+                               .css( 'min-height', '' )
+                               // Recalculate layout
+                               .each( justify );
+               }
        }
 
        mw.hook( 'wikipage.content' ).add( function ( $content ) {
                                .addClass( 'mw-gallery-packed-overlay' )
                                .removeClass( 'mw-gallery-packed-hover' );
                } else {
-                       // Note use of just "a", not a.image, since we want this to trigger if a link in
-                       // the caption receives focus
+                       // Note use of just `a`, not `a.image`, since we also want this to trigger if a link
+                       // within the caption text receives focus.
                        $content.find( 'ul.mw-gallery-packed-hover li.gallerybox' ).on( 'focus blur', 'a', function ( e ) {
                                // Confusingly jQuery leaves e.type as focusout for delegated blur events
                                var gettingFocus = e.type !== 'blur' && e.type !== 'focusout';
index 06c34a5..1823ef0 100644 (file)
@@ -2,8 +2,6 @@
  * Implement AJAX navigation for multi-page images so the user may browse without a full page reload.
  */
 
-/* eslint-disable no-use-before-define */
-
 ( function ( mw, $ ) {
        var jqXhr, $multipageimage, $spinner,
                cache = {},
@@ -86,6 +84,7 @@
                        // Replace table contents
                        $multipageimage.empty().append( $contents.clone() );
 
+                       // eslint-disable-next-line no-use-before-define
                        bindPageNavigation( $multipageimage );
 
                        // Fire hook because the page's content has changed
diff --git a/resources/src/mediawiki.skinning/content.externallinks.css b/resources/src/mediawiki.skinning/content.externallinks.css
deleted file mode 100644 (file)
index d82ffe0..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*!
- * Icons and colors for external links.
- */
-
-/* T68091 is blocking is from converting this file to LESS
- * and using the .background-image-svg mixin. */
-
-/* SVG support using a transparent gradient to guarantee cross-browser
- * compatibility ( browsers able to understand gradient syntax support also SVG ).
- * http://pauginer.tumblr.com/post/36614680636/invisible-gradient-technique */
-
-.mw-parser-output a.external,
-.link-https {
-       background: url( images/external-ltr.png ) center right no-repeat;
-       /* @embed */
-       background-image: -webkit-linear-gradient( transparent, transparent ), url( images/external-ltr.svg );
-       /* @embed */
-       background-image: linear-gradient( transparent, transparent ), url( images/external-ltr.svg );
-       padding-right: 15px;
-}
-
-.mw-parser-output a.external[ href^='mailto:' ],
-.link-mailto {
-       background: url( images/mail.png ) center right no-repeat;
-       /* @embed */
-       background-image: linear-gradient( transparent, transparent ), url( images/mail.svg );
-       padding-right: 15px;
-}
-
-.mw-parser-output a.external[ href^='ftp://' ],
-.link-ftp {
-       background: url( images/ftp-ltr.png ) center right no-repeat;
-       /* @embed */
-       background-image: linear-gradient( transparent, transparent ), url( images/ftp-ltr.svg );
-       padding-right: 15px;
-}
-
-.mw-parser-output a.external[ href^='irc://' ],
-.mw-parser-output a.external[ href^='ircs://' ],
-.link-irc {
-       background: url( images/chat-ltr.png ) center right no-repeat;
-       /* @embed */
-       background-image: linear-gradient( transparent, transparent ), url( images/chat-ltr.svg );
-       padding-right: 15px;
-}
-
-.mw-parser-output a.external[ href$='.ogg' ],
-.mw-parser-output a.external[ href$='.OGG' ],
-.mw-parser-output a.external[ href$='.mid' ],
-.mw-parser-output a.external[ href$='.MID' ],
-.mw-parser-output a.external[ href$='.midi' ],
-.mw-parser-output a.external[ href$='.MIDI' ],
-.mw-parser-output a.external[ href$='.mp3' ],
-.mw-parser-output a.external[ href$='.MP3' ],
-.mw-parser-output a.external[ href$='.wav' ],
-.mw-parser-output a.external[ href$='.WAV' ],
-.mw-parser-output a.external[ href$='.wma' ],
-.mw-parser-output a.external[ href$='.WMA' ],
-.link-audio {
-       background: url( images/audio-ltr.png ) center right no-repeat;
-       /* @embed */
-       background-image: linear-gradient( transparent, transparent ), url( images/audio-ltr.svg );
-       padding-right: 15px;
-}
-
-.mw-parser-output a.external[ href$='.ogm' ],
-.mw-parser-output a.external[ href$='.OGM' ],
-.mw-parser-output a.external[ href$='.avi' ],
-.mw-parser-output a.external[ href$='.AVI' ],
-.mw-parser-output a.external[ href$='.mpeg' ],
-.mw-parser-output a.external[ href$='.MPEG' ],
-.mw-parser-output a.external[ href$='.mpg' ],
-.mw-parser-output a.external[ href$='.MPG' ],
-.link-video {
-       background: url( images/video.png ) center right no-repeat;
-       /* @embed */
-       background-image: linear-gradient( transparent, transparent ), url( images/video.svg );
-       padding-right: 15px;
-}
-
-.mw-parser-output a.external[ href$='.pdf' ],
-.mw-parser-output a.external[ href$='.PDF' ],
-.mw-parser-output a.external[ href*='.pdf#' ],
-.mw-parser-output a.external[ href*='.PDF#' ],
-.mw-parser-output a.external[ href*='.pdf?' ],
-.mw-parser-output a.external[ href*='.PDF?' ],
-.link-document {
-       background: url( images/document-ltr.png ) center right no-repeat;
-       /* @embed */
-       background-image: linear-gradient( transparent, transparent ), url( images/document-ltr.svg );
-       padding-right: 15px;
-}
-
-/* Interwiki styling */
-.mw-parser-output a.extiw,
-.mw-parser-output a.extiw:active {
-       color: #36b;
-}
-
-/* External link color */
-.mw-parser-output a.external {
-       color: #36b;
-}
diff --git a/resources/src/mediawiki.skinning/content.externallinks.less b/resources/src/mediawiki.skinning/content.externallinks.less
new file mode 100644 (file)
index 0000000..c6390c0
--- /dev/null
@@ -0,0 +1,96 @@
+/*!
+ * Icons and colors for external links.
+ */
+
+@import 'mediawiki.mixins';
+
+.mw-parser-output a.external,
+.link-https {
+       background-position: center right;
+       background-repeat: no-repeat;
+       .background-image-svg( 'images/external-ltr.svg', 'images/external-ltr.png' );
+       padding-right: 13px;
+}
+
+.mw-parser-output a.external[ href^='mailto:' ],
+.link-mailto {
+       background-position: center right;
+       background-repeat: no-repeat;
+       .background-image-svg( 'images/mail.svg', 'images/mail.png' );
+       padding-right: 13px;
+}
+
+.mw-parser-output a.external[ href^='ftp://' ],
+.link-ftp {
+       background-position: center right;
+       background-repeat: no-repeat;
+       .background-image-svg( 'images/ftp-ltr.svg', 'images/ftp-ltr.png' );
+       padding-right: 13px;
+}
+
+.mw-parser-output a.external[ href^='irc://' ],
+.mw-parser-output a.external[ href^='ircs://' ],
+.link-irc {
+       background-position: center right;
+       background-repeat: no-repeat;
+       .background-image-svg( 'images/chat-ltr.svg', 'images/chat-ltr.png' );
+       padding-right: 13px;
+}
+
+.mw-parser-output a.external[ href$='.ogg' ],
+.mw-parser-output a.external[ href$='.OGG' ],
+.mw-parser-output a.external[ href$='.mid' ],
+.mw-parser-output a.external[ href$='.MID' ],
+.mw-parser-output a.external[ href$='.midi' ],
+.mw-parser-output a.external[ href$='.MIDI' ],
+.mw-parser-output a.external[ href$='.mp3' ],
+.mw-parser-output a.external[ href$='.MP3' ],
+.mw-parser-output a.external[ href$='.wav' ],
+.mw-parser-output a.external[ href$='.WAV' ],
+.mw-parser-output a.external[ href$='.wma' ],
+.mw-parser-output a.external[ href$='.WMA' ],
+.link-audio {
+       background-position: center right;
+       background-repeat: no-repeat;
+       .background-image-svg( 'images/audio-ltr.svg', 'images/audio-ltr.png' );
+       padding-right: 13px;
+}
+
+.mw-parser-output a.external[ href$='.ogm' ],
+.mw-parser-output a.external[ href$='.OGM' ],
+.mw-parser-output a.external[ href$='.avi' ],
+.mw-parser-output a.external[ href$='.AVI' ],
+.mw-parser-output a.external[ href$='.mpeg' ],
+.mw-parser-output a.external[ href$='.MPEG' ],
+.mw-parser-output a.external[ href$='.mpg' ],
+.mw-parser-output a.external[ href$='.MPG' ],
+.link-video {
+       background-position: center right;
+       background-repeat: no-repeat;
+       .background-image-svg( 'images/video.svg', 'images/video.png' );
+       padding-right: 13px;
+}
+
+.mw-parser-output a.external[ href$='.pdf' ],
+.mw-parser-output a.external[ href$='.PDF' ],
+.mw-parser-output a.external[ href*='.pdf#' ],
+.mw-parser-output a.external[ href*='.PDF#' ],
+.mw-parser-output a.external[ href*='.pdf?' ],
+.mw-parser-output a.external[ href*='.PDF?' ],
+.link-document {
+       background-position: center right;
+       background-repeat: no-repeat;
+       .background-image-svg( 'images/document-ltr.svg', 'images/document-ltr.png' );
+       padding-right: 13px;
+}
+
+/* Interwiki styling */
+.mw-parser-output a.extiw,
+.mw-parser-output a.extiw:active {
+       color: #36b;
+}
+
+/* External link color */
+.mw-parser-output a.external {
+       color: #36b;
+}
index 27ecb1a..d880e8b 100644 (file)
@@ -55,7 +55,7 @@ figure[ typeof*='mw:Audio' ] {
 
        &.mw-halign-right {
                /* @noflip */
-               margin: 0.5em 0 1.3em 1.4em;
+               margin: 0 0 0.5em 0.5em;
                /* @noflip */
                clear: right;
                /* @noflip */
@@ -64,7 +64,7 @@ figure[ typeof*='mw:Audio' ] {
 
        &.mw-halign-left {
                /* @noflip */
-               margin: 0.5em 1.4em 1.3em 0;
+               margin: 0 0.5em 0.5em 0;
                /* @noflip */
                clear: left;
                /* @noflip */
@@ -116,6 +116,15 @@ figure[ typeof~='mw:Audio/Frame' ] {
        clear: right;
        float: right;
 
+       &.mw-halign-left {
+               /* @noflip */
+               margin: 0.5em 1.4em 1.3em 0;
+       }
+       &.mw-halign-right {
+               /* @noflip */
+               margin: 0.5em 0 1.3em 1.4em;
+       }
+
        > *:first-child {
                > img,
                > video {
diff --git a/resources/src/mediawiki.special.apisandbox/apisandbox.css b/resources/src/mediawiki.special.apisandbox/apisandbox.css
new file mode 100644 (file)
index 0000000..fe5ac41
--- /dev/null
@@ -0,0 +1,110 @@
+.mw-apisandbox-toolbar {
+       background: #fff;
+       -webkit-position: sticky;
+       position: sticky;
+       top: 0;
+       margin-bottom: -1px;
+       padding: 0.5em 0;
+       border-bottom: 1px solid #a2a9b1;
+       text-align: right;
+       z-index: 1;
+}
+
+#mw-apisandbox-ui .mw-apisandbox-link {
+       display: none;
+}
+
+.mw-apisandbox-popup .oo-ui-popupWidget-body > .oo-ui-widget {
+       vertical-align: middle;
+}
+
+/* So DateTimeInputWidget's calendar popup works... */
+.mw-apisandbox-popup .oo-ui-popupWidget-popup,
+.mw-apisandbox-popup .oo-ui-popupWidget-body {
+       overflow: visible;
+}
+
+/* Display contents of the popup on a single line */
+.mw-apisandbox-popup > .oo-ui-popupWidget-popup > .oo-ui-popupWidget-body {
+       display: table;
+}
+
+.mw-apisandbox-popup > .oo-ui-popupWidget-popup > .oo-ui-popupWidget-body > * {
+       display: table-cell;
+}
+
+.mw-apisandbox-popup > .oo-ui-popupWidget-popup > .oo-ui-popupWidget-body > .oo-ui-buttonWidget {
+       padding-left: 0.5em;
+       width: 1%;
+}
+
+.mw-apisandbox-spacer {
+       display: inline-block;
+       height: 1px;
+       width: 5em;
+}
+
+.mw-apisandbox-help-field {
+       border-bottom: 1px solid rgba( 0, 0, 0, 0.1 );
+}
+
+.mw-apisandbox-help-field:last-child {
+       border-bottom: 0;
+}
+
+.mw-apisandbox-optionalWidget {
+       width: 100%;
+}
+
+.mw-apisandbox-optionalWidget.oo-ui-widget-disabled {
+       position: relative;
+       z-index: 0; /* New stacking context to prevent the cover from leaking out */
+}
+
+.mw-apisandbox-optionalWidget-cover {
+       position: absolute;
+       left: 0;
+       right: 0;
+       top: 0;
+       bottom: 0;
+       z-index: 2;
+       cursor: pointer;
+}
+
+.mw-apisandbox-optionalWidget-fields {
+       display: table;
+       width: 100%;
+}
+
+.mw-apisandbox-optionalWidget-widget,
+.mw-apisandbox-optionalWidget-checkbox {
+       display: table-cell;
+       vertical-align: middle;
+}
+
+.mw-apisandbox-optionalWidget-checkbox {
+       width: 1%; /* Will be expanded by content */
+       white-space: nowrap;
+       padding-left: 0.5em;
+}
+
+.mw-apisandbox-textInputCode .oo-ui-inputWidget-input {
+       font-family: monospace, monospace;
+       font-size: 0.8125em;
+       -moz-tab-size: 4;
+       tab-size: 4;
+}
+
+.mw-apisandbox-widget-field .oo-ui-textInputWidget {
+       /* Leave at least enough space for icon, indicator, and a sliver of text */
+       min-width: 6em;
+}
+
+.apihelp-deprecated {
+       font-weight: bold;
+       color: #d33;
+}
+
+.apihelp-deprecated-value .oo-ui-labelElement-label {
+       text-decoration: line-through;
+}
diff --git a/resources/src/mediawiki.special.apisandbox/apisandbox.js b/resources/src/mediawiki.special.apisandbox/apisandbox.js
new file mode 100644 (file)
index 0000000..f936658
--- /dev/null
@@ -0,0 +1,2073 @@
+( function ( $, mw, OO ) {
+       'use strict';
+       var ApiSandbox, Util, WidgetMethods, Validators,
+               $content, panel, booklet, oldhash, windowManager,
+               formatDropdown,
+               api = new mw.Api(),
+               bookletPages = [],
+               availableFormats = {},
+               resultPage = null,
+               suppressErrors = true,
+               updatingBooklet = false,
+               pages = {},
+               moduleInfoCache = {},
+               baseRequestParams;
+
+       /**
+        * A wrapper for a widget that provides an enable/disable button
+        *
+        * @class
+        * @private
+        * @constructor
+        * @param {OO.ui.Widget} widget
+        * @param {Object} [config] Configuration options
+        */
+       function OptionalWidget( widget, config ) {
+               var k;
+
+               config = config || {};
+
+               this.widget = widget;
+               this.$cover = config.$cover ||
+                       $( '<div>' ).addClass( 'mw-apisandbox-optionalWidget-cover' );
+               this.checkbox = new OO.ui.CheckboxInputWidget( config.checkbox )
+                       .on( 'change', this.onCheckboxChange, [], this );
+
+               OptionalWidget[ 'super' ].call( this, config );
+
+               // Forward most methods for convenience
+               for ( k in this.widget ) {
+                       if ( $.isFunction( this.widget[ k ] ) && !this[ k ] ) {
+                               this[ k ] = this.widget[ k ].bind( this.widget );
+                       }
+               }
+
+               widget.connect( this, {
+                       change: [ this.emit, 'change' ]
+               } );
+
+               this.$cover.on( 'click', this.onOverlayClick.bind( this ) );
+
+               this.$element
+                       .addClass( 'mw-apisandbox-optionalWidget' )
+                       .append(
+                               this.$cover,
+                               $( '<div>' ).addClass( 'mw-apisandbox-optionalWidget-fields' ).append(
+                                       $( '<div>' ).addClass( 'mw-apisandbox-optionalWidget-widget' ).append(
+                                               widget.$element
+                                       ),
+                                       $( '<div>' ).addClass( 'mw-apisandbox-optionalWidget-checkbox' ).append(
+                                               this.checkbox.$element
+                                       )
+                               )
+                       );
+
+               this.setDisabled( widget.isDisabled() );
+       }
+       OO.inheritClass( OptionalWidget, OO.ui.Widget );
+       OptionalWidget.prototype.onCheckboxChange = function ( checked ) {
+               this.setDisabled( !checked );
+       };
+       OptionalWidget.prototype.onOverlayClick = function () {
+               this.setDisabled( false );
+               if ( $.isFunction( this.widget.focus ) ) {
+                       this.widget.focus();
+               }
+       };
+       OptionalWidget.prototype.setDisabled = function ( disabled ) {
+               OptionalWidget[ 'super' ].prototype.setDisabled.call( this, disabled );
+               this.widget.setDisabled( this.isDisabled() );
+               this.checkbox.setSelected( !this.isDisabled() );
+               this.$cover.toggle( this.isDisabled() );
+               this.emit( 'change' );
+               return this;
+       };
+
+       WidgetMethods = {
+               textInputWidget: {
+                       getApiValue: function () {
+                               return this.getValue();
+                       },
+                       setApiValue: function ( v ) {
+                               if ( v === undefined ) {
+                                       v = this.paramInfo[ 'default' ];
+                               }
+                               this.setValue( v );
+                       },
+                       apiCheckValid: function () {
+                               var that = this;
+                               return this.getValidity().then( function () {
+                                       return $.Deferred().resolve( true ).promise();
+                               }, function () {
+                                       return $.Deferred().resolve( false ).promise();
+                               } ).done( function ( ok ) {
+                                       ok = ok || suppressErrors;
+                                       that.setIcon( ok ? null : 'alert' );
+                                       that.setIconTitle( ok ? '' : mw.message( 'apisandbox-alert-field' ).plain() );
+                               } );
+                       }
+               },
+
+               dateTimeInputWidget: {
+                       getValidity: function () {
+                               if ( !Util.apiBool( this.paramInfo.required ) || this.getApiValue() !== '' ) {
+                                       return $.Deferred().resolve().promise();
+                               } else {
+                                       return $.Deferred().reject().promise();
+                               }
+                       }
+               },
+
+               tokenWidget: {
+                       alertTokenError: function ( code, error ) {
+                               windowManager.openWindow( 'errorAlert', {
+                                       title: Util.parseMsg( 'apisandbox-results-fixtoken-fail', this.paramInfo.tokentype ),
+                                       message: error,
+                                       actions: [
+                                               {
+                                                       action: 'accept',
+                                                       label: OO.ui.msg( 'ooui-dialog-process-dismiss' ),
+                                                       flags: 'primary'
+                                               }
+                                       ]
+                               } );
+                       },
+                       fetchToken: function () {
+                               this.pushPending();
+                               return api.getToken( this.paramInfo.tokentype )
+                                       .done( this.setApiValue.bind( this ) )
+                                       .fail( this.alertTokenError.bind( this ) )
+                                       .always( this.popPending.bind( this ) );
+                       },
+                       setApiValue: function ( v ) {
+                               WidgetMethods.textInputWidget.setApiValue.call( this, v );
+                               if ( v === '123ABC' ) {
+                                       this.fetchToken();
+                               }
+                       }
+               },
+
+               passwordWidget: {
+                       getApiValueForDisplay: function () {
+                               return '';
+                       }
+               },
+
+               toggleSwitchWidget: {
+                       getApiValue: function () {
+                               return this.getValue() ? 1 : undefined;
+                       },
+                       setApiValue: function ( v ) {
+                               this.setValue( Util.apiBool( v ) );
+                       },
+                       apiCheckValid: function () {
+                               return $.Deferred().resolve( true ).promise();
+                       }
+               },
+
+               dropdownWidget: {
+                       getApiValue: function () {
+                               var item = this.getMenu().findSelectedItem();
+                               return item === null ? undefined : item.getData();
+                       },
+                       setApiValue: function ( v ) {
+                               var menu = this.getMenu();
+
+                               if ( v === undefined ) {
+                                       v = this.paramInfo[ 'default' ];
+                               }
+                               if ( v === undefined ) {
+                                       menu.selectItem();
+                               } else {
+                                       menu.selectItemByData( String( v ) );
+                               }
+                       },
+                       apiCheckValid: function () {
+                               var ok = this.getApiValue() !== undefined || suppressErrors;
+                               this.setIcon( ok ? null : 'alert' );
+                               this.setIconTitle( ok ? '' : mw.message( 'apisandbox-alert-field' ).plain() );
+                               return $.Deferred().resolve( ok ).promise();
+                       }
+               },
+
+               tagWidget: {
+                       parseApiValue: function ( v ) {
+                               if ( v === undefined || v === '' || v === '\x1f' ) {
+                                       return [];
+                               } else {
+                                       v = String( v );
+                                       if ( v[ 0 ] !== '\x1f' ) {
+                                               return v.split( '|' );
+                                       } else {
+                                               return v.substr( 1 ).split( '\x1f' );
+                                       }
+                               }
+                       },
+                       getApiValueForTemplates: function () {
+                               return this.isDisabled() ? this.parseApiValue( this.paramInfo[ 'default' ] ) : this.getValue();
+                       },
+                       getApiValue: function () {
+                               var items = this.getValue();
+                               if ( items.join( '' ).indexOf( '|' ) === -1 ) {
+                                       return items.join( '|' );
+                               } else {
+                                       return '\x1f' + items.join( '\x1f' );
+                               }
+                       },
+                       setApiValue: function ( v ) {
+                               if ( v === undefined ) {
+                                       v = this.paramInfo[ 'default' ];
+                               }
+                               this.setValue( this.parseApiValue( v ) );
+                       },
+                       apiCheckValid: function () {
+                               var ok = true,
+                                       pi = this.paramInfo;
+
+                               if ( !suppressErrors ) {
+                                       ok = this.getApiValue() !== undefined && !(
+                                               pi.allspecifier !== undefined &&
+                                               this.getValue().length > 1 &&
+                                               this.getValue().indexOf( pi.allspecifier ) !== -1
+                                       );
+                               }
+
+                               this.setIcon( ok ? null : 'alert' );
+                               this.setIconTitle( ok ? '' : mw.message( 'apisandbox-alert-field' ).plain() );
+                               return $.Deferred().resolve( ok ).promise();
+                       },
+                       createTagItemWidget: function ( data, label ) {
+                               var item = OO.ui.TagMultiselectWidget.prototype.createTagItemWidget.call( this, data, label );
+                               if ( this.paramInfo.deprecatedvalues &&
+                                       this.paramInfo.deprecatedvalues.indexOf( data ) >= 0
+                               ) {
+                                       item.$element.addClass( 'apihelp-deprecated-value' );
+                               }
+                               return item;
+                       }
+               },
+
+               optionalWidget: {
+                       getApiValue: function () {
+                               return this.isDisabled() ? undefined : this.widget.getApiValue();
+                       },
+                       setApiValue: function ( v ) {
+                               this.setDisabled( v === undefined );
+                               this.widget.setApiValue( v );
+                       },
+                       apiCheckValid: function () {
+                               if ( this.isDisabled() ) {
+                                       return $.Deferred().resolve( true ).promise();
+                               } else {
+                                       return this.widget.apiCheckValid();
+                               }
+                       }
+               },
+
+               submoduleWidget: {
+                       single: function () {
+                               var v = this.isDisabled() ? this.paramInfo[ 'default' ] : this.getApiValue();
+                               return v === undefined ? [] : [ { value: v, path: this.paramInfo.submodules[ v ] } ];
+                       },
+                       multi: function () {
+                               var map = this.paramInfo.submodules,
+                                       v = this.isDisabled() ? this.paramInfo[ 'default' ] : this.getApiValue();
+                               return v === undefined || v === '' ? [] : String( v ).split( '|' ).map( function ( v ) {
+                                       return { value: v, path: map[ v ] };
+                               } );
+                       }
+               },
+
+               uploadWidget: {
+                       getApiValueForDisplay: function () {
+                               return '...';
+                       },
+                       getApiValue: function () {
+                               return this.getValue();
+                       },
+                       setApiValue: function () {
+                               // Can't, sorry.
+                       },
+                       apiCheckValid: function () {
+                               var ok = this.getValue() !== null || suppressErrors;
+                               this.setIcon( ok ? null : 'alert' );
+                               this.setIconTitle( ok ? '' : mw.message( 'apisandbox-alert-field' ).plain() );
+                               return $.Deferred().resolve( ok ).promise();
+                       }
+               }
+       };
+
+       Validators = {
+               generic: function () {
+                       return !Util.apiBool( this.paramInfo.required ) || this.getApiValue() !== '';
+               }
+       };
+
+       /**
+        * @class mw.special.ApiSandbox.Util
+        * @private
+        */
+       Util = {
+               /**
+                * Fetch API module info
+                *
+                * @param {string} module Module to fetch data for
+                * @return {jQuery.Promise}
+                */
+               fetchModuleInfo: function ( module ) {
+                       var apiPromise,
+                               deferred = $.Deferred();
+
+                       if ( moduleInfoCache.hasOwnProperty( module ) ) {
+                               return deferred
+                                       .resolve( moduleInfoCache[ module ] )
+                                       .promise( { abort: function () {} } );
+                       } else {
+                               apiPromise = api.post( {
+                                       action: 'paraminfo',
+                                       modules: module,
+                                       helpformat: 'html',
+                                       uselang: mw.config.get( 'wgUserLanguage' )
+                               } ).done( function ( data ) {
+                                       var info;
+
+                                       if ( data.warnings && data.warnings.paraminfo ) {
+                                               deferred.reject( '???', data.warnings.paraminfo[ '*' ] );
+                                               return;
+                                       }
+
+                                       info = data.paraminfo.modules;
+                                       if ( !info || info.length !== 1 || info[ 0 ].path !== module ) {
+                                               deferred.reject( '???', 'No module data returned' );
+                                               return;
+                                       }
+
+                                       moduleInfoCache[ module ] = info[ 0 ];
+                                       deferred.resolve( info[ 0 ] );
+                               } ).fail( function ( code, details ) {
+                                       if ( code === 'http' ) {
+                                               details = 'HTTP error: ' + details.exception;
+                                       } else if ( details.error ) {
+                                               details = details.error.info;
+                                       }
+                                       deferred.reject( code, details );
+                               } );
+                               return deferred
+                                       .promise( { abort: apiPromise.abort } );
+                       }
+               },
+
+               /**
+                * Mark all currently-in-use tokens as bad
+                */
+               markTokensBad: function () {
+                       var page, subpages, i,
+                               checkPages = [ pages.main ];
+
+                       while ( checkPages.length ) {
+                               page = checkPages.shift();
+
+                               if ( page.tokenWidget ) {
+                                       api.badToken( page.tokenWidget.paramInfo.tokentype );
+                               }
+
+                               subpages = page.getSubpages();
+                               for ( i = 0; i < subpages.length; i++ ) {
+                                       if ( pages.hasOwnProperty( subpages[ i ].key ) ) {
+                                               checkPages.push( pages[ subpages[ i ].key ] );
+                                       }
+                               }
+                       }
+               },
+
+               /**
+                * Test an API boolean
+                *
+                * @param {Mixed} value
+                * @return {boolean}
+                */
+               apiBool: function ( value ) {
+                       return value !== undefined && value !== false;
+               },
+
+               /**
+                * Create a widget for a parameter.
+                *
+                * @param {Object} pi Parameter info from API
+                * @param {Object} opts Additional options
+                * @return {OO.ui.Widget}
+                */
+               createWidgetForParameter: function ( pi, opts ) {
+                       var widget, innerWidget, finalWidget, items, $content, func,
+                               multiModeButton = null,
+                               multiModeInput = null,
+                               multiModeAllowed = false;
+
+                       opts = opts || {};
+
+                       switch ( pi.type ) {
+                               case 'boolean':
+                                       widget = new OO.ui.ToggleSwitchWidget();
+                                       widget.paramInfo = pi;
+                                       $.extend( widget, WidgetMethods.toggleSwitchWidget );
+                                       pi.required = true; // Avoid wrapping in the non-required widget
+                                       break;
+
+                               case 'string':
+                               case 'user':
+                                       if ( Util.apiBool( pi.multi ) ) {
+                                               widget = new OO.ui.TagMultiselectWidget( {
+                                                       allowArbitrary: true,
+                                                       allowDuplicates: Util.apiBool( pi.allowsduplicates ),
+                                                       $overlay: true
+                                               } );
+                                               widget.paramInfo = pi;
+                                               $.extend( widget, WidgetMethods.tagWidget );
+                                       } else {
+                                               widget = new OO.ui.TextInputWidget( {
+                                                       required: Util.apiBool( pi.required )
+                                               } );
+                                       }
+                                       if ( !Util.apiBool( pi.multi ) ) {
+                                               widget.paramInfo = pi;
+                                               $.extend( widget, WidgetMethods.textInputWidget );
+                                               widget.setValidation( Validators.generic );
+                                       }
+                                       if ( pi.tokentype ) {
+                                               widget.paramInfo = pi;
+                                               $.extend( widget, WidgetMethods.textInputWidget );
+                                               $.extend( widget, WidgetMethods.tokenWidget );
+                                       }
+                                       break;
+
+                               case 'text':
+                                       widget = new OO.ui.MultilineTextInputWidget( {
+                                               required: Util.apiBool( pi.required )
+                                       } );
+                                       widget.paramInfo = pi;
+                                       $.extend( widget, WidgetMethods.textInputWidget );
+                                       widget.setValidation( Validators.generic );
+                                       break;
+
+                               case 'password':
+                                       widget = new OO.ui.TextInputWidget( {
+                                               type: 'password',
+                                               required: Util.apiBool( pi.required )
+                                       } );
+                                       widget.paramInfo = pi;
+                                       $.extend( widget, WidgetMethods.textInputWidget );
+                                       $.extend( widget, WidgetMethods.passwordWidget );
+                                       widget.setValidation( Validators.generic );
+                                       multiModeAllowed = true;
+                                       multiModeInput = widget;
+                                       break;
+
+                               case 'integer':
+                                       widget = new OO.ui.NumberInputWidget( {
+                                               required: Util.apiBool( pi.required ),
+                                               isInteger: true
+                                       } );
+                                       widget.setIcon = widget.input.setIcon.bind( widget.input );
+                                       widget.setIconTitle = widget.input.setIconTitle.bind( widget.input );
+                                       widget.getValidity = widget.input.getValidity.bind( widget.input );
+                                       widget.paramInfo = pi;
+                                       $.extend( widget, WidgetMethods.textInputWidget );
+                                       if ( Util.apiBool( pi.enforcerange ) ) {
+                                               widget.setRange( pi.min || -Infinity, pi.max || Infinity );
+                                       }
+                                       multiModeAllowed = true;
+                                       multiModeInput = widget;
+                                       break;
+
+                               case 'limit':
+                                       widget = new OO.ui.TextInputWidget( {
+                                               required: Util.apiBool( pi.required )
+                                       } );
+                                       widget.setValidation( function ( value ) {
+                                               var n, pi = this.paramInfo;
+
+                                               if ( value === 'max' ) {
+                                                       return true;
+                                               } else {
+                                                       n = +value;
+                                                       return !isNaN( n ) && isFinite( n ) &&
+                                                               Math.floor( n ) === n &&
+                                                               n >= pi.min && n <= pi.apiSandboxMax;
+                                               }
+                                       } );
+                                       pi.min = pi.min || 0;
+                                       pi.apiSandboxMax = mw.config.get( 'apihighlimits' ) ? pi.highmax : pi.max;
+                                       widget.paramInfo = pi;
+                                       $.extend( widget, WidgetMethods.textInputWidget );
+                                       multiModeAllowed = true;
+                                       multiModeInput = widget;
+                                       break;
+
+                               case 'timestamp':
+                                       widget = new mw.widgets.datetime.DateTimeInputWidget( {
+                                               formatter: {
+                                                       format: '${year|0}-${month|0}-${day|0}T${hour|0}:${minute|0}:${second|0}${zone|short}'
+                                               },
+                                               required: Util.apiBool( pi.required ),
+                                               clearable: false
+                                       } );
+                                       widget.paramInfo = pi;
+                                       $.extend( widget, WidgetMethods.textInputWidget );
+                                       $.extend( widget, WidgetMethods.dateTimeInputWidget );
+                                       multiModeAllowed = true;
+                                       break;
+
+                               case 'upload':
+                                       widget = new OO.ui.SelectFileWidget();
+                                       widget.paramInfo = pi;
+                                       $.extend( widget, WidgetMethods.uploadWidget );
+                                       break;
+
+                               case 'namespace':
+                                       items = $.map( mw.config.get( 'wgFormattedNamespaces' ), function ( name, ns ) {
+                                               if ( ns === '0' ) {
+                                                       name = mw.message( 'blanknamespace' ).text();
+                                               }
+                                               return new OO.ui.MenuOptionWidget( { data: ns, label: name } );
+                                       } ).sort( function ( a, b ) {
+                                               return a.data - b.data;
+                                       } );
+                                       if ( Util.apiBool( pi.multi ) ) {
+                                               if ( pi.allspecifier !== undefined ) {
+                                                       items.unshift( new OO.ui.MenuOptionWidget( {
+                                                               data: pi.allspecifier,
+                                                               label: mw.message( 'apisandbox-multivalue-all-namespaces', pi.allspecifier ).text()
+                                                       } ) );
+                                               }
+
+                                               widget = new OO.ui.MenuTagMultiselectWidget( {
+                                                       menu: { items: items },
+                                                       $overlay: true
+                                               } );
+                                               widget.paramInfo = pi;
+                                               $.extend( widget, WidgetMethods.tagWidget );
+                                       } else {
+                                               widget = new OO.ui.DropdownWidget( {
+                                                       menu: { items: items },
+                                                       $overlay: true
+                                               } );
+                                               widget.paramInfo = pi;
+                                               $.extend( widget, WidgetMethods.dropdownWidget );
+                                       }
+                                       break;
+
+                               default:
+                                       if ( !Array.isArray( pi.type ) ) {
+                                               throw new Error( 'Unknown parameter type ' + pi.type );
+                                       }
+
+                                       items = pi.type.map( function ( v ) {
+                                               var config = {
+                                                       data: String( v ),
+                                                       label: String( v ),
+                                                       classes: []
+                                               };
+                                               if ( pi.deprecatedvalues && pi.deprecatedvalues.indexOf( v ) >= 0 ) {
+                                                       config.classes.push( 'apihelp-deprecated-value' );
+                                               }
+                                               return new OO.ui.MenuOptionWidget( config );
+                                       } );
+                                       if ( Util.apiBool( pi.multi ) ) {
+                                               if ( pi.allspecifier !== undefined ) {
+                                                       items.unshift( new OO.ui.MenuOptionWidget( {
+                                                               data: pi.allspecifier,
+                                                               label: mw.message( 'apisandbox-multivalue-all-values', pi.allspecifier ).text()
+                                                       } ) );
+                                               }
+
+                                               widget = new OO.ui.MenuTagMultiselectWidget( {
+                                                       menu: { items: items },
+                                                       $overlay: true
+                                               } );
+                                               widget.paramInfo = pi;
+                                               $.extend( widget, WidgetMethods.tagWidget );
+                                               if ( Util.apiBool( pi.submodules ) ) {
+                                                       widget.getSubmodules = WidgetMethods.submoduleWidget.multi;
+                                                       widget.on( 'change', ApiSandbox.updateUI );
+                                               }
+                                       } else {
+                                               widget = new OO.ui.DropdownWidget( {
+                                                       menu: { items: items },
+                                                       $overlay: true
+                                               } );
+                                               widget.paramInfo = pi;
+                                               $.extend( widget, WidgetMethods.dropdownWidget );
+                                               if ( Util.apiBool( pi.submodules ) ) {
+                                                       widget.getSubmodules = WidgetMethods.submoduleWidget.single;
+                                                       widget.getMenu().on( 'select', ApiSandbox.updateUI );
+                                               }
+                                               if ( pi.deprecatedvalues ) {
+                                                       widget.getMenu().on( 'select', function ( item ) {
+                                                               this.$element.toggleClass(
+                                                                       'apihelp-deprecated-value',
+                                                                       pi.deprecatedvalues.indexOf( item.data ) >= 0
+                                                               );
+                                                       }, [], widget );
+                                               }
+                                       }
+
+                                       break;
+                       }
+
+                       if ( Util.apiBool( pi.multi ) && multiModeAllowed ) {
+                               innerWidget = widget;
+
+                               multiModeButton = new OO.ui.ButtonWidget( {
+                                       label: mw.message( 'apisandbox-add-multi' ).text()
+                               } );
+                               $content = innerWidget.$element.add( multiModeButton.$element );
+
+                               widget = new OO.ui.PopupTagMultiselectWidget( {
+                                       allowArbitrary: true,
+                                       allowDuplicates: Util.apiBool( pi.allowsduplicates ),
+                                       $overlay: true,
+                                       popup: {
+                                               classes: [ 'mw-apisandbox-popup' ],
+                                               padded: true,
+                                               $content: $content
+                                       }
+                               } );
+                               widget.paramInfo = pi;
+                               $.extend( widget, WidgetMethods.tagWidget );
+
+                               func = function () {
+                                       if ( !innerWidget.isDisabled() ) {
+                                               innerWidget.apiCheckValid().done( function ( ok ) {
+                                                       if ( ok ) {
+                                                               widget.addTag( innerWidget.getApiValue() );
+                                                               innerWidget.setApiValue( undefined );
+                                                       }
+                                               } );
+                                               return false;
+                                       }
+                               };
+
+                               if ( multiModeInput ) {
+                                       multiModeInput.on( 'enter', func );
+                               }
+                               multiModeButton.on( 'click', func );
+                       }
+
+                       if ( Util.apiBool( pi.required ) || opts.nooptional ) {
+                               finalWidget = widget;
+                       } else {
+                               finalWidget = new OptionalWidget( widget );
+                               finalWidget.paramInfo = pi;
+                               $.extend( finalWidget, WidgetMethods.optionalWidget );
+                               if ( widget.getSubmodules ) {
+                                       finalWidget.getSubmodules = widget.getSubmodules.bind( widget );
+                                       finalWidget.on( 'disable', function () { setTimeout( ApiSandbox.updateUI ); } );
+                               }
+                               if ( widget.getApiValueForTemplates ) {
+                                       finalWidget.getApiValueForTemplates = widget.getApiValueForTemplates.bind( widget );
+                               }
+                               finalWidget.setDisabled( true );
+                       }
+
+                       widget.setApiValue( pi[ 'default' ] );
+
+                       return finalWidget;
+               },
+
+               /**
+                * Parse an HTML string and call Util.fixupHTML()
+                *
+                * @param {string} html HTML to parse
+                * @return {jQuery}
+                */
+               parseHTML: function ( html ) {
+                       var $ret = $( $.parseHTML( html ) );
+                       return Util.fixupHTML( $ret );
+               },
+
+               /**
+                * Parse an i18n message and call Util.fixupHTML()
+                *
+                * @param {string} key Key of message to get
+                * @param {...Mixed} parameters Values for $N replacements
+                * @return {jQuery}
+                */
+               parseMsg: function () {
+                       var $ret = mw.message.apply( mw.message, arguments ).parseDom();
+                       return Util.fixupHTML( $ret );
+               },
+
+               /**
+                * Fix HTML for ApiSandbox display
+                *
+                * Fixes are:
+                * - Add target="_blank" to any links
+                *
+                * @param {jQuery} $html DOM to process
+                * @return {jQuery}
+                */
+               fixupHTML: function ( $html ) {
+                       $html.filter( 'a' ).add( $html.find( 'a' ) )
+                               .filter( '[href]:not([target])' )
+                               .attr( 'target', '_blank' );
+                       return $html;
+               },
+
+               /**
+                * Format a request and return a bunch of menu option widgets
+                *
+                * @param {Object} displayParams Query parameters, sanitized for display.
+                * @param {Object} rawParams Query parameters. You should probably use displayParams instead.
+                * @return {OO.ui.MenuOptionWidget[]} Each item's data should be an OO.ui.FieldLayout
+                */
+               formatRequest: function ( displayParams, rawParams ) {
+                       var jsonInput,
+                               items = [
+                                       new OO.ui.MenuOptionWidget( {
+                                               label: Util.parseMsg( 'apisandbox-request-format-url-label' ),
+                                               data: new OO.ui.FieldLayout(
+                                                       new OO.ui.TextInputWidget( {
+                                                               readOnly: true,
+                                                               value: mw.util.wikiScript( 'api' ) + '?' + $.param( displayParams )
+                                                       } ), {
+                                                               label: Util.parseMsg( 'apisandbox-request-url-label' )
+                                                       }
+                                               )
+                                       } ),
+                                       new OO.ui.MenuOptionWidget( {
+                                               label: Util.parseMsg( 'apisandbox-request-format-json-label' ),
+                                               data: new OO.ui.FieldLayout(
+                                                       jsonInput = new OO.ui.MultilineTextInputWidget( {
+                                                               classes: [ 'mw-apisandbox-textInputCode' ],
+                                                               readOnly: true,
+                                                               autosize: true,
+                                                               maxRows: 6,
+                                                               value: JSON.stringify( displayParams, null, '\t' )
+                                                       } ), {
+                                                               label: Util.parseMsg( 'apisandbox-request-json-label' )
+                                                       }
+                                               ).on( 'toggle', function ( visible ) {
+                                                       if ( visible ) {
+                                                               // Call updatePosition instead of adjustSize
+                                                               // because the latter has weird caching
+                                                               // behavior and the former bypasses it.
+                                                               jsonInput.updatePosition();
+                                                       }
+                                               } )
+                                       } )
+                               ];
+
+                       mw.hook( 'apisandbox.formatRequest' ).fire( items, displayParams, rawParams );
+
+                       return items;
+               },
+
+               /**
+                * Event handler for when formatDropdown's selection changes
+                */
+               onFormatDropdownChange: function () {
+                       var i,
+                               menu = formatDropdown.getMenu(),
+                               items = menu.getItems(),
+                               selectedField = menu.findSelectedItem() ? menu.findSelectedItem().getData() : null;
+
+                       for ( i = 0; i < items.length; i++ ) {
+                               items[ i ].getData().toggle( items[ i ].getData() === selectedField );
+                       }
+               }
+       };
+
+       /**
+       * Interface to ApiSandbox UI
+       *
+       * @class mw.special.ApiSandbox
+       */
+       ApiSandbox = {
+               /**
+                * Initialize the UI
+                *
+                * Automatically called on $.ready()
+                */
+               init: function () {
+                       var $toolbar;
+
+                       $content = $( '#mw-apisandbox' );
+
+                       windowManager = new OO.ui.WindowManager();
+                       $( 'body' ).append( windowManager.$element );
+                       windowManager.addWindows( {
+                               errorAlert: new OO.ui.MessageDialog()
+                       } );
+
+                       $toolbar = $( '<div>' )
+                               .addClass( 'mw-apisandbox-toolbar' )
+                               .append(
+                                       new OO.ui.ButtonWidget( {
+                                               label: mw.message( 'apisandbox-submit' ).text(),
+                                               flags: [ 'primary', 'progressive' ]
+                                       } ).on( 'click', ApiSandbox.sendRequest ).$element,
+                                       new OO.ui.ButtonWidget( {
+                                               label: mw.message( 'apisandbox-reset' ).text(),
+                                               flags: 'destructive'
+                                       } ).on( 'click', ApiSandbox.resetUI ).$element
+                               );
+
+                       booklet = new OO.ui.BookletLayout( {
+                               expanded: false,
+                               outlined: true,
+                               autoFocus: false
+                       } );
+
+                       panel = new OO.ui.PanelLayout( {
+                               classes: [ 'mw-apisandbox-container' ],
+                               content: [ booklet ],
+                               expanded: false,
+                               framed: true
+                       } );
+
+                       pages.main = new ApiSandbox.PageLayout( { key: 'main', path: 'main' } );
+
+                       // Parse the current hash string
+                       if ( !ApiSandbox.loadFromHash() ) {
+                               ApiSandbox.updateUI();
+                       }
+
+                       $( window ).on( 'hashchange', ApiSandbox.loadFromHash );
+
+                       $content
+                               .empty()
+                               .append( $( '<p>' ).append( Util.parseMsg( 'apisandbox-intro' ) ) )
+                               .append(
+                                       $( '<div>' ).attr( 'id', 'mw-apisandbox-ui' )
+                                               .append( $toolbar )
+                                               .append( panel.$element )
+                               );
+               },
+
+               /**
+                * Update the current query when the page hash changes
+                *
+                * @return {boolean} Successful
+                */
+               loadFromHash: function () {
+                       var params, m, re,
+                               hash = location.hash;
+
+                       if ( oldhash === hash ) {
+                               return false;
+                       }
+                       oldhash = hash;
+                       if ( hash === '' ) {
+                               return false;
+                       }
+
+                       // I'm surprised this doesn't seem to exist in jQuery or mw.util.
+                       params = {};
+                       hash = hash.replace( /\+/g, '%20' );
+                       re = /([^&=#]+)=?([^&#]*)/g;
+                       while ( ( m = re.exec( hash ) ) ) {
+                               params[ decodeURIComponent( m[ 1 ] ) ] = decodeURIComponent( m[ 2 ] );
+                       }
+
+                       ApiSandbox.updateUI( params );
+                       return true;
+               },
+
+               /**
+                * Update the pages in the booklet
+                *
+                * @param {Object} [params] Optional query parameters to load
+                */
+               updateUI: function ( params ) {
+                       var i, page, subpages, j, removePages,
+                               addPages = [];
+
+                       if ( !$.isPlainObject( params ) ) {
+                               params = undefined;
+                       }
+
+                       if ( updatingBooklet ) {
+                               return;
+                       }
+                       updatingBooklet = true;
+                       try {
+                               if ( params !== undefined ) {
+                                       pages.main.loadQueryParams( params );
+                               }
+                               addPages.push( pages.main );
+                               if ( resultPage !== null ) {
+                                       addPages.push( resultPage );
+                               }
+                               pages.main.apiCheckValid();
+
+                               i = 0;
+                               while ( addPages.length ) {
+                                       page = addPages.shift();
+                                       if ( bookletPages[ i ] !== page ) {
+                                               for ( j = i; j < bookletPages.length; j++ ) {
+                                                       if ( bookletPages[ j ].getName() === page.getName() ) {
+                                                               bookletPages.splice( j, 1 );
+                                                       }
+                                               }
+                                               bookletPages.splice( i, 0, page );
+                                               booklet.addPages( [ page ], i );
+                                       }
+                                       i++;
+
+                                       if ( page.getSubpages ) {
+                                               subpages = page.getSubpages();
+                                               for ( j = 0; j < subpages.length; j++ ) {
+                                                       if ( !pages.hasOwnProperty( subpages[ j ].key ) ) {
+                                                               subpages[ j ].indentLevel = page.indentLevel + 1;
+                                                               pages[ subpages[ j ].key ] = new ApiSandbox.PageLayout( subpages[ j ] );
+                                                       }
+                                                       if ( params !== undefined ) {
+                                                               pages[ subpages[ j ].key ].loadQueryParams( params );
+                                                       }
+                                                       addPages.splice( j, 0, pages[ subpages[ j ].key ] );
+                                                       pages[ subpages[ j ].key ].apiCheckValid();
+                                               }
+                                       }
+                               }
+
+                               if ( bookletPages.length > i ) {
+                                       removePages = bookletPages.splice( i, bookletPages.length - i );
+                                       booklet.removePages( removePages );
+                               }
+
+                               if ( !booklet.getCurrentPageName() ) {
+                                       booklet.selectFirstSelectablePage();
+                               }
+                       } finally {
+                               updatingBooklet = false;
+                       }
+               },
+
+               /**
+                * Reset button handler
+                */
+               resetUI: function () {
+                       suppressErrors = true;
+                       pages = {
+                               main: new ApiSandbox.PageLayout( { key: 'main', path: 'main' } )
+                       };
+                       resultPage = null;
+                       ApiSandbox.updateUI();
+               },
+
+               /**
+                * Submit button handler
+                *
+                * @param {Object} [params] Use this set of params instead of those in the form fields.
+                *   The form fields will be updated to match.
+                */
+               sendRequest: function ( params ) {
+                       var page, subpages, i, query, $result, $focus,
+                               progress, $progressText, progressLoading,
+                               deferreds = [],
+                               paramsAreForced = !!params,
+                               displayParams = {},
+                               tokenWidgets = [],
+                               checkPages = [ pages.main ];
+
+                       // Blur any focused widget before submit, because
+                       // OO.ui.ButtonWidget doesn't take focus itself (T128054)
+                       $focus = $( '#mw-apisandbox-ui' ).find( document.activeElement );
+                       if ( $focus.length ) {
+                               $focus[ 0 ].blur();
+                       }
+
+                       suppressErrors = false;
+
+                       // save widget state in params (or load from it if we are forced)
+                       if ( paramsAreForced ) {
+                               ApiSandbox.updateUI( params );
+                       }
+                       params = {};
+                       while ( checkPages.length ) {
+                               page = checkPages.shift();
+                               if ( page.tokenWidget ) {
+                                       tokenWidgets.push( page.tokenWidget );
+                               }
+                               deferreds = deferreds.concat( page.apiCheckValid() );
+                               page.getQueryParams( params, displayParams );
+                               subpages = page.getSubpages();
+                               for ( i = 0; i < subpages.length; i++ ) {
+                                       if ( pages.hasOwnProperty( subpages[ i ].key ) ) {
+                                               checkPages.push( pages[ subpages[ i ].key ] );
+                                       }
+                               }
+                       }
+
+                       if ( !paramsAreForced ) {
+                               // forced params means we are continuing a query; the base query should be preserved
+                               baseRequestParams = $.extend( {}, params );
+                       }
+
+                       $.when.apply( $, deferreds ).done( function () {
+                               var formatItems, menu, selectedLabel, deferred, actions, errorCount;
+
+                               // Count how many times `value` occurs in `array`.
+                               function countValues( value, array ) {
+                                       var count, i;
+                                       count = 0;
+                                       for ( i = 0; i < array.length; i++ ) {
+                                               if ( array[ i ] === value ) {
+                                                       count++;
+                                               }
+                                       }
+                                       return count;
+                               }
+
+                               errorCount = countValues( false, arguments );
+                               if ( errorCount > 0 ) {
+                                       actions = [
+                                               {
+                                                       action: 'accept',
+                                                       label: OO.ui.msg( 'ooui-dialog-process-dismiss' ),
+                                                       flags: 'primary'
+                                               }
+                                       ];
+                                       if ( tokenWidgets.length ) {
+                                               // Check all token widgets' validity separately
+                                               deferred = $.when.apply( $, tokenWidgets.map( function ( w ) {
+                                                       return w.apiCheckValid();
+                                               } ) );
+
+                                               deferred.done( function () {
+                                                       // If only the tokens are invalid, offer to fix them
+                                                       var tokenErrorCount = countValues( false, arguments );
+                                                       if ( tokenErrorCount === errorCount ) {
+                                                               delete actions[ 0 ].flags;
+                                                               actions.push( {
+                                                                       action: 'fix',
+                                                                       label: mw.message( 'apisandbox-results-fixtoken' ).text(),
+                                                                       flags: 'primary'
+                                                               } );
+                                                       }
+                                               } );
+                                       } else {
+                                               deferred = $.Deferred().resolve();
+                                       }
+                                       deferred.always( function () {
+                                               windowManager.openWindow( 'errorAlert', {
+                                                       title: Util.parseMsg( 'apisandbox-submit-invalid-fields-title' ),
+                                                       message: Util.parseMsg( 'apisandbox-submit-invalid-fields-message' ),
+                                                       actions: actions
+                                               } ).closed.then( function ( data ) {
+                                                       if ( data && data.action === 'fix' ) {
+                                                               ApiSandbox.fixTokenAndResend();
+                                                       }
+                                               } );
+                                       } );
+                                       return;
+                               }
+
+                               query = $.param( displayParams );
+
+                               formatItems = Util.formatRequest( displayParams, params );
+
+                               // Force a 'fm' format with wrappedhtml=1, if available
+                               if ( params.format !== undefined ) {
+                                       if ( availableFormats.hasOwnProperty( params.format + 'fm' ) ) {
+                                               params.format = params.format + 'fm';
+                                       }
+                                       if ( params.format.substr( -2 ) === 'fm' ) {
+                                               params.wrappedhtml = 1;
+                                       }
+                               }
+
+                               progressLoading = false;
+                               $progressText = $( '<span>' ).text( mw.message( 'apisandbox-sending-request' ).text() );
+                               progress = new OO.ui.ProgressBarWidget( {
+                                       progress: false,
+                                       $content: $progressText
+                               } );
+
+                               $result = $( '<div>' )
+                                       .append( progress.$element );
+
+                               resultPage = page = new OO.ui.PageLayout( '|results|', { expanded: false } );
+                               page.setupOutlineItem = function () {
+                                       this.outlineItem.setLabel( mw.message( 'apisandbox-results' ).text() );
+                               };
+
+                               if ( !formatDropdown ) {
+                                       formatDropdown = new OO.ui.DropdownWidget( {
+                                               menu: { items: [] },
+                                               $overlay: true
+                                       } );
+                                       formatDropdown.getMenu().on( 'select', Util.onFormatDropdownChange );
+                               }
+
+                               menu = formatDropdown.getMenu();
+                               selectedLabel = menu.findSelectedItem() ? menu.findSelectedItem().getLabel() : '';
+                               if ( typeof selectedLabel !== 'string' ) {
+                                       selectedLabel = selectedLabel.text();
+                               }
+                               menu.clearItems().addItems( formatItems );
+                               menu.chooseItem( menu.getItemFromLabel( selectedLabel ) || menu.findFirstSelectableItem() );
+
+                               // Fire the event to update field visibilities
+                               Util.onFormatDropdownChange();
+
+                               page.$element.empty()
+                                       .append(
+                                               new OO.ui.FieldLayout(
+                                                       formatDropdown, {
+                                                               label: Util.parseMsg( 'apisandbox-request-selectformat-label' )
+                                                       }
+                                               ).$element,
+                                               formatItems.map( function ( item ) {
+                                                       return item.getData().$element;
+                                               } ),
+                                               $result
+                                       );
+                               ApiSandbox.updateUI();
+                               booklet.setPage( '|results|' );
+
+                               location.href = oldhash = '#' + query;
+
+                               api.post( params, {
+                                       contentType: 'multipart/form-data',
+                                       dataType: 'text',
+                                       xhr: function () {
+                                               var xhr = new window.XMLHttpRequest();
+                                               xhr.upload.addEventListener( 'progress', function ( e ) {
+                                                       if ( !progressLoading ) {
+                                                               if ( e.lengthComputable ) {
+                                                                       progress.setProgress( e.loaded * 100 / e.total );
+                                                               } else {
+                                                                       progress.setProgress( false );
+                                                               }
+                                                       }
+                                               } );
+                                               xhr.addEventListener( 'progress', function ( e ) {
+                                                       if ( !progressLoading ) {
+                                                               progressLoading = true;
+                                                               $progressText.text( mw.message( 'apisandbox-loading-results' ).text() );
+                                                       }
+                                                       if ( e.lengthComputable ) {
+                                                               progress.setProgress( e.loaded * 100 / e.total );
+                                                       } else {
+                                                               progress.setProgress( false );
+                                                       }
+                                               } );
+                                               return xhr;
+                                       }
+                               } )
+                                       .catch( function ( code, data, result, jqXHR ) {
+                                               var deferred = $.Deferred();
+
+                                               if ( code !== 'http' ) {
+                                                       // Not really an error, work around mw.Api thinking it is.
+                                                       deferred.resolve( result, jqXHR );
+                                               } else {
+                                                       // Just forward it.
+                                                       deferred.reject.apply( deferred, arguments );
+                                               }
+                                               return deferred.promise();
+                                       } )
+                                       .then( function ( data, jqXHR ) {
+                                               var m, loadTime, button, clear,
+                                                       ct = jqXHR.getResponseHeader( 'Content-Type' ),
+                                                       loginSuppressed = jqXHR.getResponseHeader( 'MediaWiki-Login-Suppressed' ) || 'false';
+
+                                               $result.empty();
+                                               if ( loginSuppressed !== 'false' ) {
+                                                       $( '<div>' )
+                                                               .addClass( 'warning' )
+                                                               .append( Util.parseMsg( 'apisandbox-results-login-suppressed' ) )
+                                                               .appendTo( $result );
+                                               }
+                                               if ( /^text\/mediawiki-api-prettyprint-wrapped(?:;|$)/.test( ct ) ) {
+                                                       data = JSON.parse( data );
+                                                       if ( data.modules.length ) {
+                                                               mw.loader.load( data.modules );
+                                                       }
+                                                       if ( data.status && data.status !== 200 ) {
+                                                               $( '<div>' )
+                                                                       .addClass( 'api-pretty-header api-pretty-status' )
+                                                                       .append( Util.parseMsg( 'api-format-prettyprint-status', data.status, data.statustext ) )
+                                                                       .appendTo( $result );
+                                                       }
+                                                       $result.append( Util.parseHTML( data.html ) );
+                                                       loadTime = data.time;
+                                               } else if ( ( m = data.match( /<pre[ >][\s\S]*<\/pre>/ ) ) ) {
+                                                       $result.append( Util.parseHTML( m[ 0 ] ) );
+                                                       if ( ( m = data.match( /"wgBackendResponseTime":\s*(\d+)/ ) ) ) {
+                                                               loadTime = parseInt( m[ 1 ], 10 );
+                                                       }
+                                               } else {
+                                                       $( '<pre>' )
+                                                               .addClass( 'api-pretty-content' )
+                                                               .text( data )
+                                                               .appendTo( $result );
+                                               }
+                                               if ( paramsAreForced || data[ 'continue' ] ) {
+                                                       $result.append(
+                                                               $( '<div>' ).append(
+                                                                       new OO.ui.ButtonWidget( {
+                                                                               label: mw.message( 'apisandbox-continue' ).text()
+                                                                       } ).on( 'click', function () {
+                                                                               ApiSandbox.sendRequest( $.extend( {}, baseRequestParams, data[ 'continue' ] ) );
+                                                                       } ).setDisabled( !data[ 'continue' ] ).$element,
+                                                                       ( clear = new OO.ui.ButtonWidget( {
+                                                                               label: mw.message( 'apisandbox-continue-clear' ).text()
+                                                                       } ).on( 'click', function () {
+                                                                               ApiSandbox.updateUI( baseRequestParams );
+                                                                               clear.setDisabled( true );
+                                                                               booklet.setPage( '|results|' );
+                                                                       } ).setDisabled( !paramsAreForced ) ).$element,
+                                                                       new OO.ui.PopupButtonWidget( {
+                                                                               $overlay: true,
+                                                                               framed: false,
+                                                                               icon: 'info',
+                                                                               popup: {
+                                                                                       $content: $( '<div>' ).append( Util.parseMsg( 'apisandbox-continue-help' ) ),
+                                                                                       padded: true,
+                                                                                       width: 'auto'
+                                                                               }
+                                                                       } ).$element
+                                                               )
+                                                       );
+                                               }
+                                               if ( typeof loadTime === 'number' ) {
+                                                       $result.append(
+                                                               $( '<div>' ).append(
+                                                                       new OO.ui.LabelWidget( {
+                                                                               label: mw.message( 'apisandbox-request-time', loadTime ).text()
+                                                                       } ).$element
+                                                               )
+                                                       );
+                                               }
+
+                                               if ( jqXHR.getResponseHeader( 'MediaWiki-API-Error' ) === 'badtoken' ) {
+                                                       // Flush all saved tokens in case one of them is the bad one.
+                                                       Util.markTokensBad();
+                                                       button = new OO.ui.ButtonWidget( {
+                                                               label: mw.message( 'apisandbox-results-fixtoken' ).text()
+                                                       } );
+                                                       button.on( 'click', ApiSandbox.fixTokenAndResend )
+                                                               .on( 'click', button.setDisabled, [ true ], button )
+                                                               .$element.appendTo( $result );
+                                               }
+                                       }, function ( code, data ) {
+                                               var details = 'HTTP error: ' + data.exception;
+                                               $result.empty()
+                                                       .append(
+                                                               new OO.ui.LabelWidget( {
+                                                                       label: mw.message( 'apisandbox-results-error', details ).text(),
+                                                                       classes: [ 'error' ]
+                                                               } ).$element
+                                                       );
+                                       } );
+                       } );
+               },
+
+               /**
+                * Handler for the "Correct token and resubmit" button
+                *
+                * Used on a 'badtoken' error, it re-fetches token parameters for all
+                * pages and then re-submits the query.
+                */
+               fixTokenAndResend: function () {
+                       var page, subpages, i, k,
+                               ok = true,
+                               tokenWait = { dummy: true },
+                               checkPages = [ pages.main ],
+                               success = function ( k ) {
+                                       delete tokenWait[ k ];
+                                       if ( ok && $.isEmptyObject( tokenWait ) ) {
+                                               ApiSandbox.sendRequest();
+                                       }
+                               },
+                               failure = function ( k ) {
+                                       delete tokenWait[ k ];
+                                       ok = false;
+                               };
+
+                       while ( checkPages.length ) {
+                               page = checkPages.shift();
+
+                               if ( page.tokenWidget ) {
+                                       k = page.apiModule + page.tokenWidget.paramInfo.name;
+                                       tokenWait[ k ] = page.tokenWidget.fetchToken();
+                                       tokenWait[ k ]
+                                               .done( success.bind( page.tokenWidget, k ) )
+                                               .fail( failure.bind( page.tokenWidget, k ) );
+                               }
+
+                               subpages = page.getSubpages();
+                               for ( i = 0; i < subpages.length; i++ ) {
+                                       if ( pages.hasOwnProperty( subpages[ i ].key ) ) {
+                                               checkPages.push( pages[ subpages[ i ].key ] );
+                                       }
+                               }
+                       }
+
+                       success( 'dummy', '' );
+               },
+
+               /**
+                * Reset validity indicators for all widgets
+                */
+               updateValidityIndicators: function () {
+                       var page, subpages, i,
+                               checkPages = [ pages.main ];
+
+                       while ( checkPages.length ) {
+                               page = checkPages.shift();
+                               page.apiCheckValid();
+                               subpages = page.getSubpages();
+                               for ( i = 0; i < subpages.length; i++ ) {
+                                       if ( pages.hasOwnProperty( subpages[ i ].key ) ) {
+                                               checkPages.push( pages[ subpages[ i ].key ] );
+                                       }
+                               }
+                       }
+               }
+       };
+
+       /**
+        * PageLayout for API modules
+        *
+        * @class
+        * @private
+        * @extends OO.ui.PageLayout
+        * @constructor
+        * @param {Object} [config] Configuration options
+        */
+       ApiSandbox.PageLayout = function ( config ) {
+               config = $.extend( { prefix: '', expanded: false }, config );
+               this.displayText = config.key;
+               this.apiModule = config.path;
+               this.prefix = config.prefix;
+               this.paramInfo = null;
+               this.apiIsValid = true;
+               this.loadFromQueryParams = null;
+               this.widgets = {};
+               this.itemsFieldset = null;
+               this.deprecatedItemsFieldset = null;
+               this.templatedItemsCache = {};
+               this.tokenWidget = null;
+               this.indentLevel = config.indentLevel ? config.indentLevel : 0;
+               ApiSandbox.PageLayout[ 'super' ].call( this, config.key, config );
+               this.loadParamInfo();
+       };
+       OO.inheritClass( ApiSandbox.PageLayout, OO.ui.PageLayout );
+       ApiSandbox.PageLayout.prototype.setupOutlineItem = function () {
+               this.outlineItem.setLevel( this.indentLevel );
+               this.outlineItem.setLabel( this.displayText );
+               this.outlineItem.setIcon( this.apiIsValid || suppressErrors ? null : 'alert' );
+               this.outlineItem.setIconTitle(
+                       this.apiIsValid || suppressErrors ? '' : mw.message( 'apisandbox-alert-page' ).plain()
+               );
+       };
+
+       function widgetLabelOnClick() {
+               var f = this.getField();
+               if ( $.isFunction( f.setDisabled ) ) {
+                       f.setDisabled( false );
+               }
+               if ( $.isFunction( f.focus ) ) {
+                       f.focus();
+               }
+       }
+
+       /**
+        * Create a widget and the FieldLayouts it needs
+        * @private
+        * @param {Object} ppi API paraminfo data for the parameter
+        * @param {string} name API parameter name
+        * @return {Object}
+        * @return {OO.ui.Widget} return.widget
+        * @return {OO.ui.FieldLayout} return.widgetField
+        * @return {OO.ui.FieldLayout} return.helpField
+        */
+       ApiSandbox.PageLayout.prototype.makeWidgetFieldLayouts = function ( ppi, name ) {
+               var j, l, widget, descriptionContainer, tmp, flag, count, button, widgetField, helpField, layoutConfig;
+
+               widget = Util.createWidgetForParameter( ppi );
+               if ( ppi.tokentype ) {
+                       this.tokenWidget = widget;
+               }
+               if ( this.paramInfo.templatedparameters.length ) {
+                       widget.on( 'change', this.updateTemplatedParameters, [ null ], this );
+               }
+
+               descriptionContainer = $( '<div>' );
+
+               tmp = Util.parseHTML( ppi.description );
+               tmp.filter( 'dl' ).makeCollapsible( {
+                       collapsed: true
+               } ).children( '.mw-collapsible-toggle' ).each( function () {
+                       var $this = $( this );
+                       $this.parent().prev( 'p' ).append( $this );
+               } );
+               descriptionContainer.append( $( '<div>' ).addClass( 'description' ).append( tmp ) );
+
+               if ( ppi.info && ppi.info.length ) {
+                       for ( j = 0; j < ppi.info.length; j++ ) {
+                               descriptionContainer.append( $( '<div>' )
+                                       .addClass( 'info' )
+                                       .append( Util.parseHTML( ppi.info[ j ] ) )
+                               );
+                       }
+               }
+               flag = true;
+               count = Infinity;
+               switch ( ppi.type ) {
+                       case 'namespace':
+                               flag = false;
+                               count = mw.config.get( 'wgFormattedNamespaces' ).length;
+                               break;
+
+                       case 'limit':
+                               if ( ppi.highmax !== undefined ) {
+                                       descriptionContainer.append( $( '<div>' )
+                                               .addClass( 'info' )
+                                               .append(
+                                                       Util.parseMsg(
+                                                               'api-help-param-limit2', ppi.max, ppi.highmax
+                                                       ),
+                                                       ' ',
+                                                       Util.parseMsg( 'apisandbox-param-limit' )
+                                               )
+                                       );
+                               } else {
+                                       descriptionContainer.append( $( '<div>' )
+                                               .addClass( 'info' )
+                                               .append(
+                                                       Util.parseMsg( 'api-help-param-limit', ppi.max ),
+                                                       ' ',
+                                                       Util.parseMsg( 'apisandbox-param-limit' )
+                                               )
+                                       );
+                               }
+                               break;
+
+                       case 'integer':
+                               tmp = '';
+                               if ( ppi.min !== undefined ) {
+                                       tmp += 'min';
+                               }
+                               if ( ppi.max !== undefined ) {
+                                       tmp += 'max';
+                               }
+                               if ( tmp !== '' ) {
+                                       descriptionContainer.append( $( '<div>' )
+                                               .addClass( 'info' )
+                                               .append( Util.parseMsg(
+                                                       'api-help-param-integer-' + tmp,
+                                                       Util.apiBool( ppi.multi ) ? 2 : 1,
+                                                       ppi.min, ppi.max
+                                               ) )
+                                       );
+                               }
+                               break;
+
+                       default:
+                               if ( Array.isArray( ppi.type ) ) {
+                                       flag = false;
+                                       count = ppi.type.length;
+                               }
+                               break;
+               }
+               if ( Util.apiBool( ppi.multi ) ) {
+                       tmp = [];
+                       if ( flag && !( widget instanceof OO.ui.TagMultiselectWidget ) &&
+                               !(
+                                       widget instanceof OptionalWidget &&
+                                       widget.widget instanceof OO.ui.TagMultiselectWidget
+                               )
+                       ) {
+                               tmp.push( mw.message( 'api-help-param-multi-separate' ).parse() );
+                       }
+                       if ( count > ppi.lowlimit ) {
+                               tmp.push(
+                                       mw.message( 'api-help-param-multi-max', ppi.lowlimit, ppi.highlimit ).parse()
+                               );
+                       }
+                       if ( tmp.length ) {
+                               descriptionContainer.append( $( '<div>' )
+                                       .addClass( 'info' )
+                                       .append( Util.parseHTML( tmp.join( ' ' ) ) )
+                               );
+                       }
+               }
+               if ( 'maxbytes' in ppi ) {
+                       descriptionContainer.append( $( '<div>' )
+                               .addClass( 'info' )
+                               .append( Util.parseMsg( 'api-help-param-maxbytes', ppi.maxbytes ) )
+                       );
+               }
+               if ( 'maxchars' in ppi ) {
+                       descriptionContainer.append( $( '<div>' )
+                               .addClass( 'info' )
+                               .append( Util.parseMsg( 'api-help-param-maxchars', ppi.maxchars ) )
+                       );
+               }
+               if ( ppi.usedTemplateVars && ppi.usedTemplateVars.length ) {
+                       tmp = $();
+                       for ( j = 0, l = ppi.usedTemplateVars.length; j < l; j++ ) {
+                               tmp = tmp.add( $( '<var>' ).text( ppi.usedTemplateVars[ j ] ) );
+                               if ( j === l - 2 ) {
+                                       tmp = tmp.add( mw.message( 'and' ).parseDom() );
+                                       tmp = tmp.add( mw.message( 'word-separator' ).parseDom() );
+                               } else if ( j !== l - 1 ) {
+                                       tmp = tmp.add( mw.message( 'comma-separator' ).parseDom() );
+                               }
+                       }
+                       descriptionContainer.append( $( '<div>' )
+                               .addClass( 'info' )
+                               .append( Util.parseMsg(
+                                       'apisandbox-templated-parameter-reason',
+                                       ppi.usedTemplateVars.length,
+                                       tmp
+                               ) )
+                       );
+               }
+
+               helpField = new OO.ui.FieldLayout(
+                       new OO.ui.Widget( {
+                               $content: '\xa0',
+                               classes: [ 'mw-apisandbox-spacer' ]
+                       } ), {
+                               align: 'inline',
+                               classes: [ 'mw-apisandbox-help-field' ],
+                               label: descriptionContainer
+                       }
+               );
+
+               layoutConfig = {
+                       align: 'left',
+                       classes: [ 'mw-apisandbox-widget-field' ],
+                       label: name
+               };
+
+               if ( ppi.tokentype ) {
+                       button = new OO.ui.ButtonWidget( {
+                               label: mw.message( 'apisandbox-fetch-token' ).text()
+                       } );
+                       button.on( 'click', widget.fetchToken, [], widget );
+
+                       widgetField = new OO.ui.ActionFieldLayout( widget, button, layoutConfig );
+               } else {
+                       widgetField = new OO.ui.FieldLayout( widget, layoutConfig );
+               }
+
+               // We need our own click handler on the widget label to
+               // turn off the disablement.
+               widgetField.$label.on( 'click', widgetLabelOnClick.bind( widgetField ) );
+
+               // Don't grey out the label when the field is disabled,
+               // it makes it too hard to read and our "disabled"
+               // isn't really disabled.
+               widgetField.onFieldDisable( false );
+               widgetField.onFieldDisable = $.noop;
+
+               widgetField.apiParamIndex = ppi.index;
+
+               return {
+                       widget: widget,
+                       widgetField: widgetField,
+                       helpField: helpField
+               };
+       };
+
+       /**
+        * Update templated parameters in the page
+        * @private
+        * @param {Object} [params] Query parameters for initializing the widgets
+        */
+       ApiSandbox.PageLayout.prototype.updateTemplatedParameters = function ( params ) {
+               var p, toProcess, doProcess, tmp, toRemove,
+                       that = this,
+                       pi = this.paramInfo,
+                       prefix = that.prefix + pi.prefix;
+
+               if ( !pi || !pi.templatedparameters.length ) {
+                       return;
+               }
+
+               if ( !$.isPlainObject( params ) ) {
+                       params = null;
+               }
+
+               toRemove = {};
+               $.each( this.templatedItemsCache, function ( k, el ) {
+                       if ( el.widget.isElementAttached() ) {
+                               toRemove[ k ] = el;
+                       }
+               } );
+
+               // This bit duplicates the PHP logic in ApiBase::extractRequestParams().
+               // If you update this, see if that needs updating too.
+               toProcess = pi.templatedparameters.map( function ( p ) {
+                       return {
+                               name: prefix + p.name,
+                               info: p,
+                               vars: $.extend( {}, p.templatevars ),
+                               usedVars: []
+                       };
+               } );
+               doProcess = function ( placeholder, target ) {
+                       var values, container, index, usedVars, done;
+
+                       target = prefix + target;
+
+                       if ( !that.widgets[ target ] ) {
+                               // The target wasn't processed yet, try the next one.
+                               // If all hit this case, the parameter has no expansions.
+                               return true;
+                       }
+
+                       if ( !that.widgets[ target ].getApiValueForTemplates ) {
+                               // Not a multi-valued widget, so it can't have expansions.
+                               return false;
+                       }
+
+                       values = that.widgets[ target ].getApiValueForTemplates();
+                       if ( !Array.isArray( values ) || !values.length ) {
+                               // The target was processed but has no (valid) values.
+                               // That means it has no expansions.
+                               return false;
+                       }
+
+                       // Expand this target in the name and all other targets,
+                       // then requeue if there are more targets left or create the widget
+                       // and add it to the form if all are done.
+                       delete p.vars[ placeholder ];
+                       usedVars = p.usedVars.concat( [ target ] );
+                       placeholder = '{' + placeholder + '}';
+                       done = $.isEmptyObject( p.vars );
+                       if ( done ) {
+                               container = Util.apiBool( p.info.deprecated ) ? that.deprecatedItemsFieldset : that.itemsFieldset;
+                               index = container.getItems().findIndex( function ( el ) {
+                                       return el.apiParamIndex !== undefined && el.apiParamIndex > p.info.index;
+                               } );
+                               if ( index < 0 ) {
+                                       index = undefined;
+                               }
+                       }
+                       values.forEach( function ( value ) {
+                               var name, newVars;
+
+                               if ( !/^[^{}]*$/.exec( value ) ) {
+                                       // Skip values that make invalid parameter names
+                                       return;
+                               }
+
+                               name = p.name.replace( placeholder, value );
+                               if ( done ) {
+                                       if ( that.templatedItemsCache[ name ] ) {
+                                               tmp = that.templatedItemsCache[ name ];
+                                       } else {
+                                               tmp = that.makeWidgetFieldLayouts(
+                                                       $.extend( {}, p.info, { usedTemplateVars: usedVars } ), name
+                                               );
+                                               that.templatedItemsCache[ name ] = tmp;
+                                       }
+                                       delete toRemove[ name ];
+                                       if ( !tmp.widget.isElementAttached() ) {
+                                               that.widgets[ name ] = tmp.widget;
+                                               container.addItems( [ tmp.widgetField, tmp.helpField ], index );
+                                               if ( index !== undefined ) {
+                                                       index += 2;
+                                               }
+                                       }
+                                       if ( params ) {
+                                               tmp.widget.setApiValue( params.hasOwnProperty( name ) ? params[ name ] : undefined );
+                                       }
+                               } else {
+                                       newVars = {};
+                                       $.each( p.vars, function ( k, v ) {
+                                               newVars[ k ] = v.replace( placeholder, value );
+                                       } );
+                                       toProcess.push( {
+                                               name: name,
+                                               info: p.info,
+                                               vars: newVars,
+                                               usedVars: usedVars
+                                       } );
+                               }
+                       } );
+                       return false;
+               };
+               while ( toProcess.length ) {
+                       p = toProcess.shift();
+                       $.each( p.vars, doProcess );
+               }
+
+               toRemove = $.map( toRemove, function ( el, name ) {
+                       delete that.widgets[ name ];
+                       return [ el.widgetField, el.helpField ];
+               } );
+               if ( toRemove.length ) {
+                       this.itemsFieldset.removeItems( toRemove );
+                       this.deprecatedItemsFieldset.removeItems( toRemove );
+               }
+       };
+
+       /**
+        * Fetch module information for this page's module, then create UI
+        */
+       ApiSandbox.PageLayout.prototype.loadParamInfo = function () {
+               var dynamicFieldset, dynamicParamNameWidget,
+                       that = this,
+                       removeDynamicParamWidget = function ( name, layout ) {
+                               dynamicFieldset.removeItems( [ layout ] );
+                               delete that.widgets[ name ];
+                       },
+                       addDynamicParamWidget = function () {
+                               var name, layout, widget, button;
+
+                               // Check name is filled in
+                               name = dynamicParamNameWidget.getValue().trim();
+                               if ( name === '' ) {
+                                       dynamicParamNameWidget.focus();
+                                       return;
+                               }
+
+                               if ( that.widgets[ name ] !== undefined ) {
+                                       windowManager.openWindow( 'errorAlert', {
+                                               title: Util.parseMsg( 'apisandbox-dynamic-error-exists', name ),
+                                               actions: [
+                                                       {
+                                                               action: 'accept',
+                                                               label: OO.ui.msg( 'ooui-dialog-process-dismiss' ),
+                                                               flags: 'primary'
+                                                       }
+                                               ]
+                                       } );
+                                       return;
+                               }
+
+                               widget = Util.createWidgetForParameter( {
+                                       name: name,
+                                       type: 'string',
+                                       'default': ''
+                               }, {
+                                       nooptional: true
+                               } );
+                               button = new OO.ui.ButtonWidget( {
+                                       icon: 'trash',
+                                       flags: 'destructive'
+                               } );
+                               layout = new OO.ui.ActionFieldLayout(
+                                       widget,
+                                       button,
+                                       {
+                                               label: name,
+                                               align: 'left'
+                                       }
+                               );
+                               button.on( 'click', removeDynamicParamWidget, [ name, layout ] );
+                               that.widgets[ name ] = widget;
+                               dynamicFieldset.addItems( [ layout ], dynamicFieldset.getItems().length - 1 );
+                               widget.focus();
+
+                               dynamicParamNameWidget.setValue( '' );
+                       };
+
+               this.$element.empty()
+                       .append( new OO.ui.ProgressBarWidget( {
+                               progress: false,
+                               text: mw.message( 'apisandbox-loading', this.displayText ).text()
+                       } ).$element );
+
+               Util.fetchModuleInfo( this.apiModule )
+                       .done( function ( pi ) {
+                               var prefix, i, j, tmp,
+                                       items = [],
+                                       deprecatedItems = [],
+                                       buttons = [],
+                                       filterFmModules = function ( v ) {
+                                               return v.substr( -2 ) !== 'fm' ||
+                                                       !availableFormats.hasOwnProperty( v.substr( 0, v.length - 2 ) );
+                                       };
+
+                               // This is something of a hack. We always want the 'format' and
+                               // 'action' parameters from the main module to be specified,
+                               // and for 'format' we also want to simplify the dropdown since
+                               // we always send the 'fm' variant.
+                               if ( that.apiModule === 'main' ) {
+                                       for ( i = 0; i < pi.parameters.length; i++ ) {
+                                               if ( pi.parameters[ i ].name === 'action' ) {
+                                                       pi.parameters[ i ].required = true;
+                                                       delete pi.parameters[ i ][ 'default' ];
+                                               }
+                                               if ( pi.parameters[ i ].name === 'format' ) {
+                                                       tmp = pi.parameters[ i ].type;
+                                                       for ( j = 0; j < tmp.length; j++ ) {
+                                                               availableFormats[ tmp[ j ] ] = true;
+                                                       }
+                                                       pi.parameters[ i ].type = tmp.filter( filterFmModules );
+                                                       pi.parameters[ i ][ 'default' ] = 'json';
+                                                       pi.parameters[ i ].required = true;
+                                               }
+                                       }
+                               }
+
+                               // Hide the 'wrappedhtml' parameter on format modules
+                               if ( pi.group === 'format' ) {
+                                       pi.parameters = pi.parameters.filter( function ( p ) {
+                                               return p.name !== 'wrappedhtml';
+                                       } );
+                               }
+
+                               that.paramInfo = pi;
+
+                               items.push( new OO.ui.FieldLayout(
+                                       new OO.ui.Widget( {} ).toggle( false ), {
+                                               align: 'top',
+                                               label: Util.parseHTML( pi.description )
+                                       }
+                               ) );
+
+                               if ( pi.helpurls.length ) {
+                                       buttons.push( new OO.ui.PopupButtonWidget( {
+                                               $overlay: true,
+                                               label: mw.message( 'apisandbox-helpurls' ).text(),
+                                               icon: 'help',
+                                               popup: {
+                                                       width: 'auto',
+                                                       padded: true,
+                                                       $content: $( '<ul>' ).append( pi.helpurls.map( function ( link ) {
+                                                               return $( '<li>' ).append( $( '<a>' )
+                                                                       .attr( { href: link, target: '_blank' } )
+                                                                       .text( link )
+                                                               );
+                                                       } ) )
+                                               }
+                                       } ) );
+                               }
+
+                               if ( pi.examples.length ) {
+                                       buttons.push( new OO.ui.PopupButtonWidget( {
+                                               $overlay: true,
+                                               label: mw.message( 'apisandbox-examples' ).text(),
+                                               icon: 'code',
+                                               popup: {
+                                                       width: 'auto',
+                                                       padded: true,
+                                                       $content: $( '<ul>' ).append( pi.examples.map( function ( example ) {
+                                                               var a = $( '<a>' )
+                                                                       .attr( 'href', '#' + example.query )
+                                                                       .html( example.description );
+                                                               a.find( 'a' ).contents().unwrap(); // Can't nest links
+                                                               return $( '<li>' ).append( a );
+                                                       } ) )
+                                               }
+                                       } ) );
+                               }
+
+                               if ( buttons.length ) {
+                                       items.push( new OO.ui.FieldLayout(
+                                               new OO.ui.ButtonGroupWidget( {
+                                                       items: buttons
+                                               } ), { align: 'top' }
+                                       ) );
+                               }
+
+                               if ( pi.parameters.length ) {
+                                       prefix = that.prefix + pi.prefix;
+                                       for ( i = 0; i < pi.parameters.length; i++ ) {
+                                               tmp = that.makeWidgetFieldLayouts( pi.parameters[ i ], prefix + pi.parameters[ i ].name );
+                                               that.widgets[ prefix + pi.parameters[ i ].name ] = tmp.widget;
+                                               if ( Util.apiBool( pi.parameters[ i ].deprecated ) ) {
+                                                       deprecatedItems.push( tmp.widgetField, tmp.helpField );
+                                               } else {
+                                                       items.push( tmp.widgetField, tmp.helpField );
+                                               }
+                                       }
+                               }
+
+                               if ( !pi.parameters.length && !Util.apiBool( pi.dynamicparameters ) ) {
+                                       items.push( new OO.ui.FieldLayout(
+                                               new OO.ui.Widget( {} ).toggle( false ), {
+                                                       align: 'top',
+                                                       label: Util.parseMsg( 'apisandbox-no-parameters' )
+                                               }
+                                       ) );
+                               }
+
+                               that.$element.empty();
+
+                               that.itemsFieldset = new OO.ui.FieldsetLayout( {
+                                       label: that.displayText
+                               } );
+                               that.itemsFieldset.addItems( items );
+                               that.itemsFieldset.$element.appendTo( that.$element );
+
+                               if ( Util.apiBool( pi.dynamicparameters ) ) {
+                                       dynamicFieldset = new OO.ui.FieldsetLayout();
+                                       dynamicParamNameWidget = new OO.ui.TextInputWidget( {
+                                               placeholder: mw.message( 'apisandbox-dynamic-parameters-add-placeholder' ).text()
+                                       } ).on( 'enter', addDynamicParamWidget );
+                                       dynamicFieldset.addItems( [
+                                               new OO.ui.FieldLayout(
+                                                       new OO.ui.Widget( {} ).toggle( false ), {
+                                                               align: 'top',
+                                                               label: Util.parseHTML( pi.dynamicparameters )
+                                                       }
+                                               ),
+                                               new OO.ui.ActionFieldLayout(
+                                                       dynamicParamNameWidget,
+                                                       new OO.ui.ButtonWidget( {
+                                                               icon: 'add',
+                                                               flags: 'progressive'
+                                                       } ).on( 'click', addDynamicParamWidget ),
+                                                       {
+                                                               label: mw.message( 'apisandbox-dynamic-parameters-add-label' ).text(),
+                                                               align: 'left'
+                                                       }
+                                               )
+                                       ] );
+                                       $( '<fieldset>' )
+                                               .append(
+                                                       $( '<legend>' ).text( mw.message( 'apisandbox-dynamic-parameters' ).text() ),
+                                                       dynamicFieldset.$element
+                                               )
+                                               .appendTo( that.$element );
+                               }
+
+                               that.deprecatedItemsFieldset = new OO.ui.FieldsetLayout().addItems( deprecatedItems ).toggle( false );
+                               tmp = $( '<fieldset>' )
+                                       .toggle( !that.deprecatedItemsFieldset.isEmpty() )
+                                       .append(
+                                               $( '<legend>' ).append(
+                                                       new OO.ui.ToggleButtonWidget( {
+                                                               label: mw.message( 'apisandbox-deprecated-parameters' ).text()
+                                                       } ).on( 'change', that.deprecatedItemsFieldset.toggle, [], that.deprecatedItemsFieldset ).$element
+                                               ),
+                                               that.deprecatedItemsFieldset.$element
+                                       )
+                                       .appendTo( that.$element );
+                               that.deprecatedItemsFieldset.on( 'add', function () {
+                                       this.toggle( !that.deprecatedItemsFieldset.isEmpty() );
+                               }, [], tmp );
+                               that.deprecatedItemsFieldset.on( 'remove', function () {
+                                       this.toggle( !that.deprecatedItemsFieldset.isEmpty() );
+                               }, [], tmp );
+
+                               // Load stored params, if any, then update the booklet if we
+                               // have subpages (or else just update our valid-indicator).
+                               tmp = that.loadFromQueryParams;
+                               that.loadFromQueryParams = null;
+                               if ( $.isPlainObject( tmp ) ) {
+                                       that.loadQueryParams( tmp );
+                               } else {
+                                       that.updateTemplatedParameters();
+                               }
+                               if ( that.getSubpages().length > 0 ) {
+                                       ApiSandbox.updateUI( tmp );
+                               } else {
+                                       that.apiCheckValid();
+                               }
+                       } ).fail( function ( code, detail ) {
+                               that.$element.empty()
+                                       .append(
+                                               new OO.ui.LabelWidget( {
+                                                       label: mw.message( 'apisandbox-load-error', that.apiModule, detail ).text(),
+                                                       classes: [ 'error' ]
+                                               } ).$element,
+                                               new OO.ui.ButtonWidget( {
+                                                       label: mw.message( 'apisandbox-retry' ).text()
+                                               } ).on( 'click', that.loadParamInfo, [], that ).$element
+                                       );
+                       } );
+       };
+
+       /**
+        * Check that all widgets on the page are in a valid state.
+        *
+        * @return {jQuery.Promise[]} One promise for each widget, resolved with `false` if invalid
+        */
+       ApiSandbox.PageLayout.prototype.apiCheckValid = function () {
+               var promises, that = this;
+
+               if ( this.paramInfo === null ) {
+                       return [];
+               } else {
+                       promises = $.map( this.widgets, function ( widget ) {
+                               return widget.apiCheckValid();
+                       } );
+                       $.when.apply( $, promises ).then( function () {
+                               that.apiIsValid = $.inArray( false, arguments ) === -1;
+                               if ( that.getOutlineItem() ) {
+                                       that.getOutlineItem().setIcon( that.apiIsValid || suppressErrors ? null : 'alert' );
+                                       that.getOutlineItem().setIconTitle(
+                                               that.apiIsValid || suppressErrors ? '' : mw.message( 'apisandbox-alert-page' ).plain()
+                                       );
+                               }
+                       } );
+                       return promises;
+               }
+       };
+
+       /**
+        * Load form fields from query parameters
+        *
+        * @param {Object} params
+        */
+       ApiSandbox.PageLayout.prototype.loadQueryParams = function ( params ) {
+               if ( this.paramInfo === null ) {
+                       this.loadFromQueryParams = params;
+               } else {
+                       $.each( this.widgets, function ( name, widget ) {
+                               var v = params.hasOwnProperty( name ) ? params[ name ] : undefined;
+                               widget.setApiValue( v );
+                       } );
+                       this.updateTemplatedParameters( params );
+               }
+       };
+
+       /**
+        * Load query params from form fields
+        *
+        * @param {Object} params Write query parameters into this object
+        * @param {Object} displayParams Write query parameters for display into this object
+        */
+       ApiSandbox.PageLayout.prototype.getQueryParams = function ( params, displayParams ) {
+               $.each( this.widgets, function ( name, widget ) {
+                       var value = widget.getApiValue();
+                       if ( value !== undefined ) {
+                               params[ name ] = value;
+                               if ( $.isFunction( widget.getApiValueForDisplay ) ) {
+                                       value = widget.getApiValueForDisplay();
+                               }
+                               displayParams[ name ] = value;
+                       }
+               } );
+       };
+
+       /**
+        * Fetch a list of subpage names loaded by this page
+        *
+        * @return {Array}
+        */
+       ApiSandbox.PageLayout.prototype.getSubpages = function () {
+               var ret = [];
+               $.each( this.widgets, function ( name, widget ) {
+                       var submodules, i;
+                       if ( $.isFunction( widget.getSubmodules ) ) {
+                               submodules = widget.getSubmodules();
+                               for ( i = 0; i < submodules.length; i++ ) {
+                                       ret.push( {
+                                               key: name + '=' + submodules[ i ].value,
+                                               path: submodules[ i ].path,
+                                               prefix: widget.paramInfo.submoduleparamprefix || ''
+                                       } );
+                               }
+                       }
+               } );
+               return ret;
+       };
+
+       $( ApiSandbox.init );
+
+       module.exports = ApiSandbox;
+
+}( jQuery, mediaWiki, OO ) );
diff --git a/resources/src/mediawiki.special.block.js b/resources/src/mediawiki.special.block.js
new file mode 100644 (file)
index 0000000..180f040
--- /dev/null
@@ -0,0 +1,58 @@
+/*!
+ * JavaScript for Special:Block
+ */
+( function ( mw, $ ) {
+       // Like OO.ui.infuse(), but if the element doesn't exist, return null instead of throwing an exception.
+       function infuseOrNull( elem ) {
+               try {
+                       return OO.ui.infuse( elem );
+               } catch ( er ) {
+                       return null;
+               }
+       }
+
+       $( function () {
+               // This code is also loaded on the "block succeeded" page where there is no form,
+               // so username and expiry fields might also be missing.
+               var blockTargetWidget = infuseOrNull( 'mw-bi-target' ),
+                       anonOnlyField = infuseOrNull( $( '#mw-input-wpHardBlock' ).closest( '.oo-ui-fieldLayout' ) ),
+                       enableAutoblockField = infuseOrNull( $( '#mw-input-wpAutoBlock' ).closest( '.oo-ui-fieldLayout' ) ),
+                       hideUserField = infuseOrNull( $( '#mw-input-wpHideUser' ).closest( '.oo-ui-fieldLayout' ) ),
+                       watchUserField = infuseOrNull( $( '#mw-input-wpWatch' ).closest( '.oo-ui-fieldLayout' ) ),
+                       expiryWidget = infuseOrNull( 'mw-input-wpExpiry' );
+
+               function updateBlockOptions() {
+                       var blocktarget = blockTargetWidget.getValue().trim(),
+                               isEmpty = blocktarget === '',
+                               isIp = mw.util.isIPAddress( blocktarget, true ),
+                               isIpRange = isIp && blocktarget.match( /\/\d+$/ ),
+                               isNonEmptyIp = isIp && !isEmpty,
+                               expiryValue = expiryWidget.getValue(),
+                               // infinityValues  are the values the SpecialBlock class accepts as infinity (sf. wfIsInfinity)
+                               infinityValues = [ 'infinite', 'indefinite', 'infinity', 'never' ],
+                               isIndefinite = infinityValues.indexOf( expiryValue ) !== -1;
+
+                       if ( enableAutoblockField ) {
+                               enableAutoblockField.toggle( !( isNonEmptyIp ) );
+                       }
+                       if ( hideUserField ) {
+                               hideUserField.toggle( !( isNonEmptyIp || !isIndefinite ) );
+                       }
+                       if ( anonOnlyField ) {
+                               anonOnlyField.toggle( !( !isIp && !isEmpty ) );
+                       }
+                       if ( watchUserField ) {
+                               watchUserField.toggle( !( isIpRange && !isEmpty ) );
+                       }
+               }
+
+               if ( blockTargetWidget ) {
+                       // Bind functions so they're checked whenever stuff changes
+                       blockTargetWidget.on( 'change', updateBlockOptions );
+                       expiryWidget.on( 'change', updateBlockOptions );
+
+                       // Call them now to set initial state (ie. Special:Block/Foobar?wpBlockExpiry=2+hours)
+                       updateBlockOptions();
+               }
+       } );
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special.changecredentials.js b/resources/src/mediawiki.special.changecredentials.js
new file mode 100644 (file)
index 0000000..ad8a4f4
--- /dev/null
@@ -0,0 +1,55 @@
+/*!
+ * JavaScript for change credentials form.
+ */
+( function ( mw, $, OO ) {
+       mw.hook( 'htmlform.enhance' ).add( function ( $root ) {
+               var api = new mw.Api();
+
+               $root.find( '.mw-changecredentials-validate-password.oo-ui-fieldLayout' ).each( function () {
+                       var currentApiPromise,
+                               self = OO.ui.FieldLayout.static.infuse( $( this ) );
+
+                       self.getField().setValidation( function ( password ) {
+                               var d;
+
+                               if ( currentApiPromise ) {
+                                       currentApiPromise.abort();
+                                       currentApiPromise = undefined;
+                               }
+
+                               password = password.trim();
+
+                               if ( password === '' ) {
+                                       self.setErrors( [] );
+                                       return true;
+                               }
+
+                               d = $.Deferred();
+                               currentApiPromise = api.post( {
+                                       action: 'validatepassword',
+                                       password: password,
+                                       formatversion: 2,
+                                       errorformat: 'html',
+                                       errorsuselocal: true,
+                                       uselang: mw.config.get( 'wgUserLanguage' )
+                               } ).done( function ( resp ) {
+                                       var pwinfo = resp.validatepassword,
+                                               good = pwinfo.validity === 'Good',
+                                               errors = [];
+
+                                       currentApiPromise = undefined;
+
+                                       if ( !good ) {
+                                               pwinfo.validitymessages.map( function ( m ) {
+                                                       errors.push( new OO.ui.HtmlSnippet( m.html ) );
+                                               } );
+                                       }
+                                       self.setErrors( errors );
+                                       d.resolve( good );
+                               } ).fail( d.reject );
+
+                               return d.promise( { abort: currentApiPromise.abort } );
+                       } );
+               } );
+       } );
+}( mediaWiki, jQuery, OO ) );
diff --git a/resources/src/mediawiki.special.changeslist.css b/resources/src/mediawiki.special.changeslist.css
new file mode 100644 (file)
index 0000000..65860ea
--- /dev/null
@@ -0,0 +1,56 @@
+/*!
+ * Styling for Special:Watchlist and Special:RecentChanges
+ */
+
+.mw-changeslist-line-watched .mw-title {
+       font-weight: bold;
+}
+
+/*
+ * Titles, including username links, and also tag names
+ * are prone to getting jumbled up
+ * with other titles, usernames, etc. in mixed RTL-LTR environment.
+ */
+.mw-changeslist .mw-tag-marker,
+.mw-changeslist .mw-title {
+       unicode-bidi: embed;
+}
+
+/* Colored watchlist and recent changes numbers */
+.mw-plusminus-pos {
+       color: #006400; /* dark green */
+}
+
+.mw-plusminus-neg {
+       color: #8b0000; /* dark red */
+}
+
+.mw-plusminus-null {
+       color: #a2a9b1; /* gray */
+}
+
+/*
+ * Bidi-isolate these numbers.
+ * See https://phabricator.wikimedia.org/T93484
+ */
+.mw-plusminus-pos,
+.mw-plusminus-neg,
+.mw-plusminus-null {
+       unicode-bidi: -moz-isolate;
+       unicode-bidi: isolate;
+}
+
+/* Prevent FOUC if legend is initially collapsed */
+.mw-changeslist-legend.mw-collapsed .mw-collapsible-content {
+       display: none;
+}
+
+.mw-changeslist-legend.mw-collapsed {
+       margin-bottom: 0;
+}
+
+/* Prevent pushing down the content if legend is collapsed */
+.mw-changeslist-legend.mw-collapsed ~ ul:first-of-type > li:first-child,
+.mw-changeslist-legend.mw-collapsed + h4 + div > table.mw-changeslist-line:first-child {
+       clear: right;
+}
diff --git a/resources/src/mediawiki.special.changeslist.enhanced.css b/resources/src/mediawiki.special.changeslist.enhanced.css
new file mode 100644 (file)
index 0000000..275004f
--- /dev/null
@@ -0,0 +1,58 @@
+/*!
+ * Styling for Special:Watchlist and Special:RecentChanges when preference 'usenewrc'
+ * a.k.a. Enhanced Recent Changes is enabled.
+ */
+
+table.mw-enhanced-rc {
+       border: 0;
+       border-spacing: 0;
+}
+
+table.mw-enhanced-rc th,
+table.mw-enhanced-rc td {
+       padding: 0;
+       vertical-align: top;
+}
+
+td.mw-enhanced-rc {
+       white-space: nowrap;
+       font-family: monospace, monospace;
+}
+
+.mw-enhanced-rc-time {
+       font-family: monospace, monospace;
+}
+
+table.mw-enhanced-rc td.mw-enhanced-rc-nested {
+       padding-left: 1em;
+}
+
+/* Show/hide arrows in enhanced changeslist */
+.mw-enhanced-rc .collapsible-expander {
+       float: none;
+}
+
+/* If JS is disabled, the arrows or the placeholder space shouldn't be shown */
+.client-nojs .mw-enhancedchanges-arrow-space {
+       display: none;
+}
+
+.mw-enhancedchanges-arrow {
+       padding-top: 2px;
+}
+
+.mw-enhancedchanges-arrow-space {
+       display: inline-block;
+       *display: inline; /* IE7 and below */
+       zoom: 1;
+       width: 15px;
+       height: 15px;
+}
+
+.mw-enhanced-watched .mw-enhanced-rc-time {
+       font-weight: bold;
+}
+
+span.changedby {
+       font-size: 95%;
+}
diff --git a/resources/src/mediawiki.special.changeslist.legend.css b/resources/src/mediawiki.special.changeslist.legend.css
new file mode 100644 (file)
index 0000000..14f6aee
--- /dev/null
@@ -0,0 +1,33 @@
+/*!
+ * Styling for changes list legend
+ */
+
+.mw-changeslist-legend {
+       float: right;
+       margin-left: 1em;
+       margin-bottom: 0.5em;
+       clear: right;
+       font-size: 85%;
+       line-height: 1.2em;
+       padding: 0.5em;
+       border: 1px solid #ddd;
+}
+
+.mw-changeslist-legend dl {
+       /* Parent element defines sufficient padding */
+       margin-bottom: 0;
+}
+
+.mw-changeslist-legend dt {
+       float: left;
+       margin: 0 0.5em 0 0;
+}
+
+.mw-changeslist-legend dd {
+       margin-left: 1.5em;
+}
+
+.mw-changeslist-legend dt,
+.mw-changeslist-legend dd {
+       line-height: 1.3em;
+}
diff --git a/resources/src/mediawiki.special.changeslist.legend.js b/resources/src/mediawiki.special.changeslist.legend.js
new file mode 100644 (file)
index 0000000..0792762
--- /dev/null
@@ -0,0 +1,24 @@
+/*!
+ * Script for changes list legend
+ */
+
+/* Remember the collapse state of the legend on recent changes and watchlist pages. */
+( function ( mw ) {
+       var
+               cookieName = 'changeslist-state',
+               // Expanded by default
+               doCollapsibleLegend = function ( $container ) {
+                       $container.find( '.mw-changeslist-legend' )
+                               .makeCollapsible( {
+                                       collapsed: mw.cookie.get( cookieName ) === 'collapsed'
+                               } )
+                               .on( 'beforeExpand.mw-collapsible', function () {
+                                       mw.cookie.set( cookieName, 'expanded' );
+                               } )
+                               .on( 'beforeCollapse.mw-collapsible', function () {
+                                       mw.cookie.set( cookieName, 'collapsed' );
+                               } );
+               };
+
+       mw.hook( 'wikipage.content' ).add( doCollapsibleLegend );
+}( mediaWiki ) );
diff --git a/resources/src/mediawiki.special.contributions.js b/resources/src/mediawiki.special.contributions.js
new file mode 100644 (file)
index 0000000..f65a257
--- /dev/null
@@ -0,0 +1,12 @@
+( function ( mw, $ ) {
+       $( function () {
+               var startInput = mw.widgets.DateInputWidget.static.infuse( 'mw-date-start' ),
+                       endInput = mw.widgets.DateInputWidget.static.infuse( 'mw-date-end' );
+
+               startInput.on( 'deactivate', function ( userSelected ) {
+                       if ( userSelected ) {
+                               endInput.focus();
+                       }
+               } );
+       } );
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special.edittags.js b/resources/src/mediawiki.special.edittags.js
new file mode 100644 (file)
index 0000000..4f51e9b
--- /dev/null
@@ -0,0 +1,38 @@
+/*!
+ * JavaScript for Special:EditTags
+ */
+( function ( mw, $ ) {
+       $( function () {
+               var summaryCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
+                       summaryByteLimit = mw.config.get( 'wgCommentByteLimit' ),
+                       $wpReason = $( '#wpReason' ),
+                       $tagList = $( '#mw-edittags-tag-list' );
+
+               if ( $tagList.length ) {
+                       $tagList.chosen( {
+                               /* eslint-disable camelcase */
+                               placeholder_text_multiple: mw.msg( 'tags-edit-chosen-placeholder' ),
+                               no_results_text: mw.msg( 'tags-edit-chosen-no-results' )
+                               /* eslint-enable camelcase */
+                       } );
+               }
+
+               $( '#mw-edittags-remove-all' ).on( 'change', function ( e ) {
+                       $( '.mw-edittags-remove-checkbox' ).prop( 'checked', e.target.checked );
+               } );
+               $( '.mw-edittags-remove-checkbox' ).on( 'change', function ( e ) {
+                       if ( !e.target.checked ) {
+                               $( '#mw-edittags-remove-all' ).prop( 'checked', false );
+                       }
+               } );
+
+               // Limit to bytes or UTF-8 codepoints, depending on MediaWiki's configuration
+               // use maxLength because it's leaving room for log entry text.
+               if ( summaryCodePointLimit ) {
+                       $wpReason.codePointLimit();
+               } else if ( summaryByteLimit ) {
+                       $wpReason.byteLimit();
+               }
+       } );
+
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special.import.js b/resources/src/mediawiki.special.import.js
new file mode 100644 (file)
index 0000000..2cb96af
--- /dev/null
@@ -0,0 +1,37 @@
+/*!
+ * JavaScript for Special:Import
+ */
+( function ( $ ) {
+       var subprojectListAlreadyShown;
+       function updateImportSubprojectList() {
+               var $projectField = $( '#mw-import-table-interwiki #interwiki' ),
+                       $subprojectField = $projectField.parent().find( '#subproject' ),
+                       $selected = $projectField.find( ':selected' ),
+                       oldValue = $subprojectField.val(),
+                       option, options;
+
+               if ( $selected.attr( 'data-subprojects' ) ) {
+                       options = $selected.attr( 'data-subprojects' ).split( ' ' ).map( function ( el ) {
+                               option = document.createElement( 'option' );
+                               option.appendChild( document.createTextNode( el ) );
+                               option.setAttribute( 'value', el );
+                               if ( oldValue === el && subprojectListAlreadyShown === true ) {
+                                       option.setAttribute( 'selected', 'selected' );
+                               }
+                               return option;
+                       } );
+                       $subprojectField.show().empty().append( options );
+                       subprojectListAlreadyShown = true;
+               } else {
+                       $subprojectField.hide();
+               }
+       }
+
+       $( function () {
+               var $projectField = $( '#mw-import-table-interwiki #interwiki' );
+               if ( $projectField.length ) {
+                       $projectField.change( updateImportSubprojectList );
+                       updateImportSubprojectList();
+               }
+       } );
+}( jQuery ) );
diff --git a/resources/src/mediawiki.special.movePage.js b/resources/src/mediawiki.special.movePage.js
new file mode 100644 (file)
index 0000000..d828396
--- /dev/null
@@ -0,0 +1,23 @@
+/*!
+ * JavaScript for Special:MovePage
+ */
+( function ( mw, $ ) {
+       $( function () {
+               var summaryCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
+                       summaryByteLimit = mw.config.get( 'wgCommentByteLimit' ),
+                       wpReason = OO.ui.infuse( $( '#wpReason' ) );
+
+               // Infuse for pretty dropdown
+               OO.ui.infuse( $( '#wpNewTitle' ) );
+               // Limit to bytes or UTF-8 codepoints, depending on MediaWiki's configuration
+               if ( summaryCodePointLimit ) {
+                       mw.widgets.visibleCodePointLimit( wpReason, summaryCodePointLimit );
+               } else if ( summaryByteLimit ) {
+                       mw.widgets.visibleByteLimit( wpReason, summaryByteLimit );
+               }
+               // Infuse for nicer "help" popup
+               if ( $( '#wpMovetalk-field' ).length ) {
+                       OO.ui.infuse( $( '#wpMovetalk-field' ) );
+               }
+       } );
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special.pageLanguage.js b/resources/src/mediawiki.special.pageLanguage.js
new file mode 100644 (file)
index 0000000..edfbe1e
--- /dev/null
@@ -0,0 +1,11 @@
+/*!
+ * JavaScript module used on Special:PageLanguage
+ */
+( function ( $, OO ) {
+       $( function () {
+               // Select the 'Language select' option if user is trying to select language
+               OO.ui.infuse( 'mw-pl-languageselector' ).on( 'change', function () {
+                       OO.ui.infuse( 'mw-pl-options' ).setValue( '2' );
+               } );
+       } );
+}( jQuery, OO ) );
diff --git a/resources/src/mediawiki.special.preferences.ooui/editfont.js b/resources/src/mediawiki.special.preferences.ooui/editfont.js
new file mode 100644 (file)
index 0000000..fe48886
--- /dev/null
@@ -0,0 +1,32 @@
+/*!
+ * JavaScript for Special:Preferences: editfont field enhancements.
+ */
+( function ( mw, $ ) {
+       $( function () {
+               var widget, lastValue;
+
+               try {
+                       widget = OO.ui.infuse( $( '#mw-input-wpeditfont' ) );
+               } catch ( err ) {
+                       // This preference could theoretically be disabled ($wgHiddenPrefs)
+                       return;
+               }
+
+               // Style options
+               widget.dropdownWidget.menu.items.forEach( function ( item ) {
+                       item.$label.addClass( 'mw-editfont-' + item.getData() );
+               } );
+
+               function updateLabel( value ) {
+                       // Style selected item label
+                       widget.dropdownWidget.$label
+                               .removeClass( 'mw-editfont-' + lastValue )
+                               .addClass( 'mw-editfont-' + value );
+                       lastValue = value;
+               }
+
+               widget.on( 'change', updateLabel );
+               updateLabel( widget.getValue() );
+
+       } );
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special.preferences.ooui/tabs.js b/resources/src/mediawiki.special.preferences.ooui/tabs.js
new file mode 100644 (file)
index 0000000..795a2b7
--- /dev/null
@@ -0,0 +1,139 @@
+/*!
+ * JavaScript for Special:Preferences: Tab navigation.
+ */
+( function ( mw, $ ) {
+       $( function () {
+               var $preferences, tabs, wrapper, previousTab;
+
+               $preferences = $( '#preferences' );
+
+               // Make sure the accessibility tip is selectable so that screen reader users take notice,
+               // but hide it by default to reduce visual clutter.
+               // Make sure it becomes visible when focused.
+               $( '<div>' ).addClass( 'mw-navigation-hint' )
+                       .text( mw.msg( 'prefs-tabs-navigation-hint' ) )
+                       .attr( 'tabIndex', 0 )
+                       .on( 'focus blur', function ( e ) {
+                               if ( e.type === 'blur' || e.type === 'focusout' ) {
+                                       $( this ).css( 'height', '0' );
+                               } else {
+                                       $( this ).css( 'height', 'auto' );
+                               }
+                       } ).prependTo( '#mw-content-text' );
+
+               tabs = new OO.ui.IndexLayout( {
+                       expanded: false,
+                       // Do not remove focus from the tabs menu after choosing a tab
+                       autoFocus: false
+               } );
+
+               mw.config.get( 'wgPreferencesTabs' ).forEach( function ( tabConfig ) {
+                       var panel, $panelContents;
+
+                       panel = new OO.ui.TabPanelLayout( tabConfig.name, {
+                               expanded: false,
+                               label: tabConfig.label
+                       } );
+                       $panelContents = $( '#mw-prefsection-' + tabConfig.name );
+
+                       // Hide the unnecessary PHP PanelLayouts
+                       // (Do not use .remove(), as that would remove event handlers for everything inside them)
+                       $panelContents.parent().detach();
+
+                       panel.$element.append( $panelContents );
+                       tabs.addTabPanels( [ panel ] );
+
+                       // Remove duplicate labels
+                       // (This must be after .addTabPanels(), otherwise the tab item doesn't exist yet)
+                       $panelContents.children( 'legend' ).remove();
+                       $panelContents.attr( 'aria-labelledby', panel.getTabItem().getElementId() );
+               } );
+
+               wrapper = new OO.ui.PanelLayout( {
+                       expanded: false,
+                       padded: false,
+                       framed: true
+               } );
+               wrapper.$element.append( tabs.$element );
+               $preferences.prepend( wrapper.$element );
+               $( '.mw-prefs-faketabs' ).remove();
+
+               function updateHash( panel ) {
+                       var scrollTop, active;
+                       // Handle hash manually to prevent jumping,
+                       // therefore save and restore scrollTop to prevent jumping.
+                       scrollTop = $( window ).scrollTop();
+                       // Changing the hash apparently causes keyboard focus to be lost?
+                       // Save and restore it. This makes no sense though.
+                       active = document.activeElement;
+                       location.hash = '#mw-prefsection-' + panel.getName();
+                       if ( active ) {
+                               active.focus();
+                       }
+                       $( window ).scrollTop( scrollTop );
+               }
+
+               tabs.on( 'set', updateHash );
+
+               /**
+                * @ignore
+                * @param {string} name the name of a tab without the prefix ("mw-prefsection-")
+                * @param {string} [mode] A hash will be set according to the current
+                *  open section. Set mode 'noHash' to supress this.
+                */
+               function switchPrefTab( name, mode ) {
+                       if ( mode === 'noHash' ) {
+                               tabs.off( 'set', updateHash );
+                       }
+                       tabs.setTabPanel( name );
+                       if ( mode === 'noHash' ) {
+                               tabs.on( 'set', updateHash );
+                       }
+               }
+
+               // Jump to correct section as indicated by the hash.
+               // This function is called onload and onhashchange.
+               function detectHash() {
+                       var hash = location.hash,
+                               matchedElement, parentSection;
+                       if ( hash.match( /^#mw-prefsection-[\w]+$/ ) ) {
+                               mw.storage.session.remove( 'mwpreferences-prevTab' );
+                               switchPrefTab( hash.replace( '#mw-prefsection-', '' ) );
+                       } else if ( hash.match( /^#mw-[\w-]+$/ ) ) {
+                               matchedElement = document.getElementById( hash.slice( 1 ) );
+                               parentSection = $( matchedElement ).parent().closest( '[id^="mw-prefsection-"]' );
+                               if ( parentSection.length ) {
+                                       mw.storage.session.remove( 'mwpreferences-prevTab' );
+                                       // Switch to proper tab and scroll to selected item.
+                                       switchPrefTab( parentSection.attr( 'id' ).replace( 'mw-prefsection-', '' ), 'noHash' );
+                                       matchedElement.scrollIntoView();
+                               }
+                       }
+               }
+
+               $( window ).on( 'hashchange', function () {
+                       var hash = location.hash;
+                       if ( hash.match( /^#mw-[\w-]+/ ) ) {
+                               detectHash();
+                       } else if ( hash === '' ) {
+                               switchPrefTab( 'personal', 'noHash' );
+                       }
+               } )
+                       // Run the function immediately to select the proper tab on startup.
+                       .trigger( 'hashchange' );
+
+               // Restore the active tab after saving the preferences
+               previousTab = mw.storage.session.get( 'mwpreferences-prevTab' );
+               if ( previousTab ) {
+                       switchPrefTab( previousTab, 'noHash' );
+                       // Deleting the key, the tab states should be reset until we press Save
+                       mw.storage.session.remove( 'mwpreferences-prevTab' );
+               }
+
+               $( '#mw-prefs-form' ).on( 'submit', function () {
+                       var value = tabs.getCurrentTabPanelName();
+                       mw.storage.session.set( 'mwpreferences-prevTab', value );
+               } );
+
+       } );
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special.preferences.styles.css b/resources/src/mediawiki.special.preferences.styles.css
new file mode 100644 (file)
index 0000000..33b630a
--- /dev/null
@@ -0,0 +1,47 @@
+/* Reuses colors from mediawiki.legacy/shared.css */
+.mw-email-not-authenticated .mw-input,
+.mw-email-none .mw-input {
+       border: 1px solid #fde29b;
+       background-color: #fdf1d1;
+       color: #000;
+}
+/* Authenticated email field has its own class too. Unstyled by default */
+/*
+.mw-email-authenticated .mw-input { }
+*/
+/* This breaks due to nolabel styling */
+#preferences > fieldset td.mw-label {
+       width: 20%;
+}
+
+#preferences > fieldset table {
+       width: 100%;
+}
+#preferences > fieldset table.mw-htmlform-matrix {
+       width: auto;
+}
+
+/* The CSS below is also for JS enabled version, because we want to prevent FOUC */
+
+/*
+ * Hide, but keep accessible for screen-readers.
+ * Like .mw-jump, #jump-to-nav from shared.css
+ */
+.client-js .mw-navigation-hint {
+       overflow: hidden;
+       height: 0;
+       zoom: 1;
+}
+
+.client-nojs #preftoc {
+       display: none;
+}
+
+.client-js #preferences > fieldset {
+       display: none;
+}
+
+/* Only the 1st tab is shown by default in JS mode */
+.client-js #preferences #mw-prefsection-personal {
+       display: block;
+}
diff --git a/resources/src/mediawiki.special.preferences.styles.ooui.css b/resources/src/mediawiki.special.preferences.styles.ooui.css
new file mode 100644 (file)
index 0000000..a72186b
--- /dev/null
@@ -0,0 +1,146 @@
+/* Reuses colors from mediawiki.legacy/shared.css */
+.mw-email-not-authenticated .oo-ui-labelWidget,
+.mw-email-none .oo-ui-labelWidget {
+       border: 1px solid #fde29b;
+       background-color: #fdf1d1;
+       color: #000;
+       padding: 0.5em;
+}
+/* Authenticated email field has its own class too. Unstyled by default */
+/*
+.mw-email-authenticated .oo-ui-labelWidget { }
+*/
+
+/* This is needed because add extra buttons in a weird way */
+.mw-prefs-buttons .mw-htmlform-submit-buttons {
+       margin: 0;
+       display: inline;
+}
+
+.mw-prefs-buttons {
+       margin-top: 1em;
+}
+
+#prefcontrol {
+       margin-right: 0.5em;
+}
+
+/*
+ * Hide, but keep accessible for screen-readers.
+ * Like .mw-jump, #jump-to-nav from shared.css
+ */
+.client-js .mw-navigation-hint {
+       overflow: hidden;
+       height: 0;
+       zoom: 1;
+}
+
+/* Override OOUI styles so that dropdowns near the bottom of the form don't get clipped,
+ * e.g.'Appearance' / 'Threshold for stub link formatting'. This is hacky and bad, it would be
+ * better solved by setting overlays for the widgets, but we can't do it from PHP... */
+#preferences .oo-ui-panelLayout {
+       position: static;
+       overflow: visible;
+       -webkit-transform: none;
+       transform: none;
+}
+
+#preferences .oo-ui-menuLayout .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed {
+       border-width: 0;
+       border-radius: 0;
+       box-shadow: none;
+       padding-left: 0;
+       padding-right: 0;
+}
+
+.mw-prefs-faketabs > .oo-ui-menuLayout > .oo-ui-menuLayout-menu a {
+       color: inherit;
+       text-decoration: none;
+}
+
+/* Adjust the borders when JS is disabled: frame each prefsection instead of the
+ * whole tabLayout wrapper */
+.client-nojs #preferences .oo-ui-menuLayout .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed {
+       border-color: #c8ccd1;
+       border-width: 1px 0 0;
+}
+
+.client-nojs .mw-prefs-faketabs {
+       border-width: 0;
+       border-radius: 0;
+       box-shadow: none;
+}
+
+.client-nojs .mw-prefs-faketabs > .oo-ui-menuLayout > .oo-ui-menuLayout-content > .oo-ui-stackLayout {
+       margin-bottom: 1em;
+}
+
+/* Hide the tab menu when JS is disabled as we can't use this feature */
+.client-nojs .mw-prefs-faketabs > .oo-ui-menuLayout > .oo-ui-menuLayout-menu {
+       display: none;
+}
+
+.client-nojs #preferences .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed:last-child {
+       padding-bottom: 0;
+       margin-bottom: 0;
+}
+
+/* Hide top level legends when JS is enabled, as they will not be visible
+ * when the real tabLayout is built */
+.client-js #preferences .oo-ui-tabPanelLayout > fieldset > legend {
+       display: none;
+}
+
+.client-js #preferences .oo-ui-tabPanelLayout {
+       padding-top: 0.5em;
+}
+
+.client-js #preferences .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed {
+       margin-left: 0;
+       margin-bottom: 0;
+       padding: 0;
+       border-width: 0;
+       border-radius: 0;
+       box-shadow: none;
+}
+
+.client-js #preferences > .oo-ui-panelLayout > .oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-header {
+       margin-bottom: 1em;
+}
+
+/* Make the "Basic information" section more compact */
+/* OOUI's `align: 'left'` for FieldLayouts sucks, so we do our own */
+#mw-htmlform-info > .oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header {
+       width: 20%;
+       display: inline-block;
+       vertical-align: middle;
+       padding: 0;
+}
+
+#mw-htmlform-info > .oo-ui-fieldLayout-align-top .oo-ui-fieldLayout-help {
+       margin-right: 0;
+}
+
+#mw-htmlform-info > .oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
+       width: 80%;
+       display: inline-block;
+       vertical-align: middle;
+}
+
+/* Expand the dropdown and textfield of "Time zone" field to the */
+/* usual maximum width and display them on separate lines. */
+#wpTimeCorrection .oo-ui-dropdownInputWidget,
+#wpTimeCorrection .oo-ui-textInputWidget {
+       display: block;
+       max-width: 50em;
+}
+
+#wpTimeCorrection .oo-ui-textInputWidget {
+       margin-top: 0.5em;
+}
+
+/* HACK: expand width of gadget descriptions.
+ * This should be moved to the Gadgets extension */
+#mw-htmlform-gadgets .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body {
+       max-width: none;
+}
diff --git a/resources/src/mediawiki.special.preferences/confirmClose.js b/resources/src/mediawiki.special.preferences/confirmClose.js
new file mode 100644 (file)
index 0000000..244154b
--- /dev/null
@@ -0,0 +1,86 @@
+/*!
+ * JavaScript for Special:Preferences: Enable save button and prevent the window being accidentally
+ * closed when any form field is changed.
+ */
+( function ( mw, $ ) {
+       $( function () {
+               var allowCloseWindow, saveButton, restoreButton,
+                       oouiEnabled = $( '#mw-prefs-form' ).hasClass( 'mw-htmlform-ooui' );
+
+               // Check if all of the form values are unchanged.
+               // (This function could be changed to infuse and check OOUI widgets, but that would only make it
+               // slower and more complicated. It works fine to treat them as HTML elements.)
+               function isPrefsChanged() {
+                       var inputs = $( '#mw-prefs-form :input[name]' ),
+                               input, $input, inputType,
+                               index, optIndex,
+                               opt;
+
+                       for ( index = 0; index < inputs.length; index++ ) {
+                               input = inputs[ index ];
+                               $input = $( input );
+
+                               // Different types of inputs have different methods for accessing defaults
+                               if ( $input.is( 'select' ) ) {
+                                       // <select> has the property defaultSelected for each option
+                                       for ( optIndex = 0; optIndex < input.options.length; optIndex++ ) {
+                                               opt = input.options[ optIndex ];
+                                               if ( opt.selected !== opt.defaultSelected ) {
+                                                       return true;
+                                               }
+                                       }
+                               } else if ( $input.is( 'input' ) || $input.is( 'textarea' ) ) {
+                                       // <input> has defaultValue or defaultChecked
+                                       inputType = input.type;
+                                       if ( inputType === 'radio' || inputType === 'checkbox' ) {
+                                               if ( input.checked !== input.defaultChecked ) {
+                                                       return true;
+                                               }
+                                       } else if ( input.value !== input.defaultValue ) {
+                                               return true;
+                                       }
+                               }
+                       }
+
+                       return false;
+               }
+
+               if ( oouiEnabled ) {
+                       saveButton = OO.ui.infuse( $( '#prefcontrol' ) );
+                       restoreButton = OO.ui.infuse( $( '#mw-prefs-restoreprefs' ) );
+
+                       // Disable the button to save preferences unless preferences have changed
+                       // Check if preferences have been changed before JS has finished loading
+                       saveButton.setDisabled( !isPrefsChanged() );
+                       $( '#preferences .oo-ui-fieldsetLayout' ).on( 'change keyup mouseup', function () {
+                               saveButton.setDisabled( !isPrefsChanged() );
+                       } );
+               } else {
+                       // Disable the button to save preferences unless preferences have changed
+                       // Check if preferences have been changed before JS has finished loading
+                       $( '#prefcontrol' ).prop( 'disabled', !isPrefsChanged() );
+                       $( '#preferences > fieldset' ).on( 'change keyup mouseup', function () {
+                               $( '#prefcontrol' ).prop( 'disabled', !isPrefsChanged() );
+                       } );
+               }
+
+               // Set up a message to notify users if they try to leave the page without
+               // saving.
+               allowCloseWindow = mw.confirmCloseWindow( {
+                       test: isPrefsChanged,
+                       message: mw.msg( 'prefswarning-warning', mw.msg( 'saveprefs' ) ),
+                       namespace: 'prefswarning'
+               } );
+               $( '#mw-prefs-form' ).on( 'submit', $.proxy( allowCloseWindow, 'release' ) );
+               if ( oouiEnabled ) {
+                       restoreButton.on( 'click', function () {
+                               allowCloseWindow.release();
+                               // The default behavior of events in OOUI is always prevented. Follow the link manually.
+                               // Note that middle-click etc. still works, as it doesn't emit a OOUI 'click' event.
+                               location.href = restoreButton.getHref();
+                       } );
+               } else {
+                       $( '#mw-prefs-restoreprefs' ).on( 'click', $.proxy( allowCloseWindow, 'release' ) );
+               }
+       } );
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special.preferences/convertmessagebox.js b/resources/src/mediawiki.special.preferences/convertmessagebox.js
new file mode 100644 (file)
index 0000000..e6b7432
--- /dev/null
@@ -0,0 +1,9 @@
+/*!
+ * JavaScript for Special:Preferences: Check for successbox to replace with notifications.
+ */
+( function ( $ ) {
+       $( function () {
+               var convertmessagebox = require( 'mediawiki.notification.convertmessagebox' );
+               convertmessagebox();
+       } );
+}( jQuery ) );
diff --git a/resources/src/mediawiki.special.preferences/personalEmail.js b/resources/src/mediawiki.special.preferences/personalEmail.js
new file mode 100644 (file)
index 0000000..f934d59
--- /dev/null
@@ -0,0 +1,24 @@
+/*!
+ * JavaScript for Special:Preferences: Email preferences better UX
+ */
+( function ( $ ) {
+       $( function () {
+               var allowEmail, allowEmailFromNewUsers;
+
+               allowEmail = $( '#wpAllowEmail' );
+               allowEmailFromNewUsers = $( '#wpAllowEmailFromNewUsers' );
+
+               function toggleDisabled() {
+                       if ( allowEmail.is( ':checked' ) && allowEmail.is( ':enabled' ) ) {
+                               allowEmailFromNewUsers.prop( 'disabled', false );
+                       } else {
+                               allowEmailFromNewUsers.prop( 'disabled', true );
+                       }
+               }
+
+               if ( allowEmail ) {
+                       allowEmail.on( 'change', toggleDisabled );
+                       toggleDisabled();
+               }
+       } );
+}( jQuery ) );
diff --git a/resources/src/mediawiki.special.preferences/tabs.legacy.js b/resources/src/mediawiki.special.preferences/tabs.legacy.js
new file mode 100644 (file)
index 0000000..598b8f8
--- /dev/null
@@ -0,0 +1,143 @@
+/*!
+ * JavaScript for Special:Preferences: Tab navigation.
+ */
+( function ( mw, $ ) {
+       $( function () {
+               var $preftoc, $preferences, $fieldsets, labelFunc, previousTab;
+
+               labelFunc = function () {
+                       return this.id.replace( /^mw-prefsection/g, 'preftab' );
+               };
+
+               $preftoc = $( '#preftoc' );
+               $preferences = $( '#preferences' );
+
+               $fieldsets = $preferences.children( 'fieldset' )
+                       .attr( {
+                               role: 'tabpanel',
+                               'aria-labelledby': labelFunc
+                       } );
+               $fieldsets.not( '#mw-prefsection-personal' )
+                       .hide()
+                       .attr( 'aria-hidden', 'true' );
+
+               // T115692: The following is kept for backwards compatibility with older skins
+               $preferences.addClass( 'jsprefs' );
+               $fieldsets.addClass( 'prefsection' );
+               $fieldsets.children( 'legend' ).addClass( 'mainLegend' );
+
+               // Make sure the accessibility tip is selectable so that screen reader users take notice,
+               // but hide it by default to reduce visual clutter.
+               // Make sure it becomes visible when focused.
+               $( '<div>' ).addClass( 'mw-navigation-hint' )
+                       .text( mw.msg( 'prefs-tabs-navigation-hint' ) )
+                       .attr( 'tabIndex', 0 )
+                       .on( 'focus blur', function ( e ) {
+                               if ( e.type === 'blur' || e.type === 'focusout' ) {
+                                       $( this ).css( 'height', '0' );
+                               } else {
+                                       $( this ).css( 'height', 'auto' );
+                               }
+                       } ).insertBefore( $preftoc );
+
+               /**
+                * It uses document.getElementById for security reasons (HTML injections in $()).
+                *
+                * @ignore
+                * @param {string} name the name of a tab without the prefix ("mw-prefsection-")
+                * @param {string} [mode] A hash will be set according to the current
+                *  open section. Set mode 'noHash' to surpress this.
+                */
+               function switchPrefTab( name, mode ) {
+                       var $tab, scrollTop;
+                       // Handle hash manually to prevent jumping,
+                       // therefore save and restore scrollTop to prevent jumping.
+                       scrollTop = $( window ).scrollTop();
+                       if ( mode !== 'noHash' ) {
+                               location.hash = '#mw-prefsection-' + name;
+                       }
+                       $( window ).scrollTop( scrollTop );
+
+                       $preftoc.find( 'li' ).removeClass( 'selected' )
+                               .find( 'a' ).attr( {
+                                       tabIndex: -1,
+                                       'aria-selected': 'false'
+                               } );
+
+                       $tab = $( document.getElementById( 'preftab-' + name ) );
+                       if ( $tab.length ) {
+                               $tab.attr( {
+                                       tabIndex: 0,
+                                       'aria-selected': 'true'
+                               } ).focus()
+                                       .parent().addClass( 'selected' );
+
+                               $preferences.children( 'fieldset' ).hide().attr( 'aria-hidden', 'true' );
+                               $( document.getElementById( 'mw-prefsection-' + name ) ).show().attr( 'aria-hidden', 'false' );
+                       }
+               }
+
+               // Enable keyboard users to use left and right keys to switch tabs
+               $preftoc.on( 'keydown', function ( event ) {
+                       var keyLeft = 37,
+                               keyRight = 39,
+                               $el;
+
+                       if ( event.keyCode === keyLeft ) {
+                               $el = $( '#preftoc li.selected' ).prev().find( 'a' );
+                       } else if ( event.keyCode === keyRight ) {
+                               $el = $( '#preftoc li.selected' ).next().find( 'a' );
+                       } else {
+                               return;
+                       }
+                       if ( $el.length > 0 ) {
+                               switchPrefTab( $el.attr( 'href' ).replace( '#mw-prefsection-', '' ) );
+                       }
+               } );
+
+               // Jump to correct section as indicated by the hash.
+               // This function is called onload and onhashchange.
+               function detectHash() {
+                       var hash = location.hash,
+                               matchedElement, parentSection;
+                       if ( hash.match( /^#mw-prefsection-[\w]+$/ ) ) {
+                               mw.storage.session.remove( 'mwpreferences-prevTab' );
+                               switchPrefTab( hash.replace( '#mw-prefsection-', '' ) );
+                       } else if ( hash.match( /^#mw-[\w-]+$/ ) ) {
+                               matchedElement = document.getElementById( hash.slice( 1 ) );
+                               parentSection = $( matchedElement ).parent().closest( '[id^="mw-prefsection-"]' );
+                               if ( parentSection.length ) {
+                                       mw.storage.session.remove( 'mwpreferences-prevTab' );
+                                       // Switch to proper tab and scroll to selected item.
+                                       switchPrefTab( parentSection.attr( 'id' ).replace( 'mw-prefsection-', '' ), 'noHash' );
+                                       matchedElement.scrollIntoView();
+                               }
+                       }
+               }
+
+               $( window ).on( 'hashchange', function () {
+                       var hash = location.hash;
+                       if ( hash.match( /^#mw-[\w-]+/ ) ) {
+                               detectHash();
+                       } else if ( hash === '' ) {
+                               switchPrefTab( 'personal', 'noHash' );
+                       }
+               } )
+                       // Run the function immediately to select the proper tab on startup.
+                       .trigger( 'hashchange' );
+
+               // Restore the active tab after saving the preferences
+               previousTab = mw.storage.session.get( 'mwpreferences-prevTab' );
+               if ( previousTab ) {
+                       switchPrefTab( previousTab, 'noHash' );
+                       // Deleting the key, the tab states should be reset until we press Save
+                       mw.storage.session.remove( 'mwpreferences-prevTab' );
+               }
+
+               $( '#mw-prefs-form' ).on( 'submit', function () {
+                       var value = $( $preftoc ).find( 'li.selected a' ).attr( 'id' ).replace( 'preftab-', '' );
+                       mw.storage.session.set( 'mwpreferences-prevTab', value );
+               } );
+
+       } );
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special.preferences/timezone.js b/resources/src/mediawiki.special.preferences/timezone.js
new file mode 100644 (file)
index 0000000..f938bcf
--- /dev/null
@@ -0,0 +1,111 @@
+/*!
+ * JavaScript for Special:Preferences: Timezone field enhancements.
+ */
+( function ( mw, $ ) {
+       $( function () {
+               var $tzSelect, $tzTextbox, timezoneWidget, $localtimeHolder, servertime,
+                       oouiEnabled = $( '#mw-prefs-form' ).hasClass( 'mw-htmlform-ooui' );
+
+               // Timezone functions.
+               // Guesses Timezone from browser and updates fields onchange.
+
+               if ( oouiEnabled ) {
+                       // This is identical to OO.ui.infuse( ... ), but it makes the class name of the result known.
+                       try {
+                               timezoneWidget = mw.widgets.SelectWithInputWidget.static.infuse( $( '#wpTimeCorrection' ) );
+                       } catch ( err ) {
+                               // This preference could theoretically be disabled ($wgHiddenPrefs)
+                               timezoneWidget = null;
+                       }
+               } else {
+                       $tzSelect = $( '#wpTimeCorrection' );
+                       $tzTextbox = $( '#wpTimeCorrection-other' );
+               }
+
+               $localtimeHolder = $( '#wpLocalTime' );
+               servertime = parseInt( $( 'input[name="wpServerTime"]' ).val(), 10 );
+
+               function minutesToHours( min ) {
+                       var tzHour = Math.floor( Math.abs( min ) / 60 ),
+                               tzMin = Math.abs( min ) % 60,
+                               tzString = ( ( min >= 0 ) ? '' : '-' ) + ( ( tzHour < 10 ) ? '0' : '' ) + tzHour +
+                                       ':' + ( ( tzMin < 10 ) ? '0' : '' ) + tzMin;
+                       return tzString;
+               }
+
+               function hoursToMinutes( hour ) {
+                       var minutes,
+                               arr = hour.split( ':' );
+
+                       arr[ 0 ] = parseInt( arr[ 0 ], 10 );
+
+                       if ( arr.length === 1 ) {
+                               // Specification is of the form [-]XX
+                               minutes = arr[ 0 ] * 60;
+                       } else {
+                               // Specification is of the form [-]XX:XX
+                               minutes = Math.abs( arr[ 0 ] ) * 60 + parseInt( arr[ 1 ], 10 );
+                               if ( arr[ 0 ] < 0 ) {
+                                       minutes *= -1;
+                               }
+                       }
+                       // Gracefully handle non-numbers.
+                       if ( isNaN( minutes ) ) {
+                               return 0;
+                       } else {
+                               return minutes;
+                       }
+               }
+
+               function updateTimezoneSelection() {
+                       var minuteDiff, localTime,
+                               type = oouiEnabled ? timezoneWidget.dropdowninput.getValue() : $tzSelect.val(),
+                               val = oouiEnabled ? timezoneWidget.textinput.getValue() : $tzTextbox.val();
+
+                       if ( type === 'other' ) {
+                               // User specified time zone manually in <input>
+                               // Grab data from the textbox, parse it.
+                               minuteDiff = hoursToMinutes( val );
+                       } else {
+                               // Time zone not manually specified by user
+                               if ( type === 'guess' ) {
+                                       // Get browser timezone & fill it in
+                                       minuteDiff = -( new Date().getTimezoneOffset() );
+                                       if ( oouiEnabled ) {
+                                               timezoneWidget.textinput.setValue( minutesToHours( minuteDiff ) );
+                                               timezoneWidget.dropdowninput.setValue( 'other' );
+                                       } else {
+                                               $tzTextbox.val( minutesToHours( minuteDiff ) );
+                                               $tzSelect.val( 'other' );
+                                       }
+                               } else {
+                                       // Grab data from the dropdown value
+                                       minuteDiff = parseInt( type.split( '|' )[ 1 ], 10 ) || 0;
+                               }
+                       }
+
+                       // Determine local time from server time and minutes difference, for display.
+                       localTime = servertime + minuteDiff;
+
+                       // Bring time within the [0,1440) range.
+                       localTime = ( ( localTime % 1440 ) + 1440 ) % 1440;
+
+                       $localtimeHolder.text( mw.language.convertNumber( minutesToHours( localTime ) ) );
+               }
+
+               if ( oouiEnabled ) {
+                       if ( timezoneWidget ) {
+                               timezoneWidget.dropdowninput.on( 'change', updateTimezoneSelection );
+                               timezoneWidget.textinput.on( 'change', updateTimezoneSelection );
+                               updateTimezoneSelection();
+                       }
+               } else {
+                       if ( $tzSelect.length && $tzTextbox.length ) {
+                               $tzSelect.change( updateTimezoneSelection );
+                               $tzTextbox.blur( updateTimezoneSelection );
+                               updateTimezoneSelection();
+                       }
+               }
+
+       } );
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special.recentchanges.js b/resources/src/mediawiki.special.recentchanges.js
new file mode 100644 (file)
index 0000000..29c0fea
--- /dev/null
@@ -0,0 +1,38 @@
+/*!
+ * JavaScript for Special:RecentChanges
+ */
+( function ( mw, $ ) {
+       var rc, $checkboxes, $select;
+
+       /**
+        * @class mw.special.recentchanges
+        * @singleton
+        */
+       rc = {
+               /**
+                * Handler to disable/enable the namespace selector checkboxes when the
+                * special 'all' namespace is selected/unselected respectively.
+                */
+               updateCheckboxes: function () {
+                       // The option element for the 'all' namespace has an empty value
+                       var isAllNS = $select.val() === '';
+
+                       // Iterates over checkboxes and propagate the selected option
+                       $checkboxes.prop( 'disabled', isAllNS );
+               },
+
+               init: function () {
+                       $select = $( '#namespace' );
+                       $checkboxes = $( '#nsassociated, #nsinvert' );
+
+                       // Bind to change event, and trigger once to set the initial state of the checkboxes.
+                       rc.updateCheckboxes();
+                       $select.change( rc.updateCheckboxes );
+               }
+       };
+
+       $( rc.init );
+
+       module.exports = rc;
+
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special.revisionDelete.js b/resources/src/mediawiki.special.revisionDelete.js
new file mode 100644 (file)
index 0000000..cad9db0
--- /dev/null
@@ -0,0 +1,29 @@
+/*!
+ * JavaScript for Special:RevisionDelete
+ */
+( function ( mw, $ ) {
+       var colonSeparator = mw.message( 'colon-separator' ).text(),
+               summaryCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
+               summaryByteLimit = mw.config.get( 'wgCommentByteLimit' ),
+               $wpRevDeleteReasonList = $( '#wpRevDeleteReasonList' ),
+               $wpReason = $( '#wpReason' ),
+               filterFn = function ( input ) {
+                       // Should be built the same as in SpecialRevisionDelete::submit()
+                       var comment = $wpRevDeleteReasonList.val();
+                       if ( comment === 'other' ) {
+                               comment = input;
+                       } else if ( input !== '' ) {
+                               // Entry from drop down menu + additional comment
+                               comment += colonSeparator + input;
+                       }
+                       return comment;
+               };
+
+       // Limit to bytes or UTF-8 codepoints, depending on MediaWiki's configuration
+       if ( summaryCodePointLimit ) {
+               $wpReason.codePointLimit( summaryCodePointLimit, filterFn );
+       } else if ( summaryByteLimit ) {
+               $wpReason.byteLimit( summaryByteLimit, filterFn );
+       }
+
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special.search.commonsInterwikiWidget.js b/resources/src/mediawiki.special.search.commonsInterwikiWidget.js
new file mode 100644 (file)
index 0000000..648bf67
--- /dev/null
@@ -0,0 +1,78 @@
+( function ( mw, $ ) {
+
+       var api = new mw.Api(),
+               pageUrl = new mw.Uri(),
+               imagesText = new mw.Message( mw.messages, 'searchprofile-images' ),
+               moreResultsText = new mw.Message( mw.messages, 'search-interwiki-more-results' );
+
+       function itemTemplate( results ) {
+
+               var resultOutput = '', i, result, imageCaption, imageThumbnailSrc;
+
+               for ( i = 0; i < results.length; i++ ) {
+                       result = results[ i ];
+                       imageCaption = mw.html.element( 'span', { 'class': 'iw-result__mini-gallery__caption' }, result.title );
+                       imageThumbnailSrc = ( result.thumbnail ) ? result.thumbnail.source : '';
+                       resultOutput += '<div class="iw-result__mini-gallery">' +
+                                               /* escaping response content */
+                                               mw.html.element( 'a', {
+                                                       href: '/wiki/' + result.title,
+                                                       'class': 'iw-result__mini-gallery__image',
+                                                       style: 'background-image: url(' + imageThumbnailSrc + ');'
+                                               }, new mw.html.Raw( imageCaption ) ) +
+                                       '</div>';
+               }
+
+               return resultOutput;
+       }
+
+       function itemWrapperTemplate( pageQuery, itemTemplateOutput ) {
+
+               return '<li class="iw-resultset iw-resultset--image" data-iw-resultset-pos="0">' +
+                               '<div class="iw-result__header">' +
+                                       '<strong>' + imagesText.escaped() + '</strong>' +
+                               '</div>' +
+                               '<div class="iw-result__content">' +
+                               /* template output has been sanitized by mw.html.element */
+                               itemTemplateOutput +
+                               '</div>' +
+                               '<div class="iw-result__footer">' +
+                                       '<a href="/w/index.php?title=Special:Search&search=' + encodeURIComponent( pageQuery ) + '&fulltext=1&profile=images">' +
+                                               moreResultsText.escaped() +
+                                       '</a>' +
+                               '</div>' +
+                       '</li>';
+
+       }
+
+       api.get( {
+               action: 'query',
+               generator: 'search',
+               gsrsearch: pageUrl.query.search,
+               gsrnamespace: mw.config.get( 'wgNamespaceIds' ).file,
+               gsrlimit: 3,
+               prop: 'pageimages',
+               pilimit: 3,
+               piprop: 'thumbnail',
+               pithumbsize: 300,
+               formatversion: 2
+       } ).done( function ( resp ) {
+               var results = ( resp.query && resp.query.pages ) ? resp.query.pages : false,
+                       multimediaWidgetTemplate;
+
+               if ( !results ) {
+                       return;
+               }
+
+               results.sort( function ( a, b ) {
+                       return a.index - b.index;
+               } );
+
+               multimediaWidgetTemplate = itemWrapperTemplate( pageUrl.query.search, itemTemplate( results ) );
+               /* we really only need to wait for document ready for DOM manipulation */
+               $( function () {
+                       $( '.iw-results' ).append( multimediaWidgetTemplate );
+               } );
+       } );
+
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special.search.interwikiwidget.styles.less b/resources/src/mediawiki.special.search.interwikiwidget.styles.less
new file mode 100644 (file)
index 0000000..8ec2735
--- /dev/null
@@ -0,0 +1,121 @@
+/* interwiki search results */
+/*==========================*/
+
+@import 'mediawiki.ui/variables.less';
+@import 'mediawiki.mixins';
+
+.mw-searchresults-has-iw {
+
+       .iw-headline {
+               font-weight: bold;
+       }
+
+       .iw-results {
+               list-style: none;
+               margin: 0;
+       }
+
+       .iw-resultset {
+               .box-sizing(border-box);
+               padding: 0.5em;
+               vertical-align: top;
+               width: 100%;
+               float: left;
+               background-color: @colorGray15;
+               margin-bottom: 1em;
+               word-break: break-word;
+       }
+
+       .iw-result__title {
+               font-size: 108%; /* matching regular search title */
+       }
+
+       .iw-result:after,
+       .iw-result__content:after { /* clearfix */
+               visibility: hidden;
+               display: block;
+               font-size: 0;
+               content: ' ';
+               clear: both;
+               height: 0;
+       }
+
+       .iw-result__footer {
+               float: right;
+               font-size: 97%; /* matching main search result font-size */
+               margin-top: 0.5em;
+       }
+       .iw-result__footer a {
+               vertical-align: middle;
+               font-style: italic;
+       }
+
+       .oo-ui-icon-favicon {
+               padding-right: 1em;
+       }
+
+       /* image search result */
+       .iw-result__mini-gallery {
+               position: relative;
+               float: left;
+               width: 100%;
+               height: 200px;
+               .box-sizing(border-box);
+               padding: 0.25rem;
+       }
+
+       /* second and third images are small */
+       .iw-result__mini-gallery:nth-child( 2 ),
+       .iw-result__mini-gallery:nth-child( 3 ) { /* stylelint-disable-line indentation */
+               width: 50%;
+               height: 100px;
+       }
+
+       .iw-result__mini-gallery__image {
+               display: block;
+               position: relative;
+               width: 100%;
+               height: 100%;
+               background-size: 100% auto;
+               background-size: cover;
+               background-repeat: no-repeat;
+               background-position: center center;
+       }
+
+       /* image gallery text */
+       .iw-result__mini-gallery__image > .iw-result__mini-gallery__caption {
+               visibility: hidden;
+               position: absolute;
+               bottom: 0;
+               left: 0;
+               text-align: center;
+               color: #fff;
+               font-size: 0.8em;
+               padding: 0.5em;
+               background-color: rgba( 0, 0, 0, 0.5 );
+       }
+
+       .iw-result__mini-gallery__image:hover > .iw-result__mini-gallery__caption {
+               visibility: visible;
+       }
+
+       /* tablet and up */
+
+       @media only screen and ( min-width: @deviceWidthTablet ) {
+
+               #mw-interwiki-results {
+                       width: 30%;
+                       display: inline-block; /* used to align interwiki sidebar with the top of the main search results */
+                       margin-left: 8%; /* since inline-block causes whitespace issues, this is 8 instead of 10% */
+               }
+               .mw-search-createlink,
+               .mw-search-nonefound,
+               .mw-search-results,
+               .mw-search-interwiki-header {
+                       float: left;
+                       width: 60%;
+                       clear: left;
+                       max-width: 60%;
+               }
+       }
+}
diff --git a/resources/src/mediawiki.special.search.styles.css b/resources/src/mediawiki.special.search.styles.css
new file mode 100644 (file)
index 0000000..ea9b987
--- /dev/null
@@ -0,0 +1,166 @@
+/* Special:Search */
+
+/*
+ * Fixes sister projects box moving down the extract
+ * of the first result (bug #16886).
+ * It only happens when the window is small and
+ * This changes slightly the layout for big screens
+ * where there was space for the extracts and the
+ * sister projects and thus it showed like in any
+ * other browser.
+ *
+ * This will only affect IE 7 and lower
+ */
+.searchresult {
+       display: inline !ie;
+}
+.searchresults {
+       margin: 1em 0 1em 0.4em;
+}
+/* needs extra specificity to override `.mw-body p` selector */
+.mw-body .mw-search-nonefound {
+       margin: 0;
+}
+
+.searchdidyoumean em,
+.searchmatch {
+       font-weight: bold;
+}
+
+.mw-search-results {
+       margin: 0;
+       max-width: 38em;
+}
+
+.mw-search-visualclear {
+       clear: both;
+}
+.mw-search-results li {
+       padding-bottom: 1.2em;
+       list-style: none;
+       list-style-image: none;
+}
+.mw-search-results li a {
+       font-size: 108%;
+}
+.mw-search-result-data {
+       color: #008000;
+       font-size: 97%;
+}
+.mw-search-profile-tabs {
+       background-color: #f8f9fa;
+       margin-top: 1em;
+       border: 1px solid #c8ccd1;
+       border-radius: 2px;
+}
+.search-types {
+       float: left;
+       padding-left: 0.25em;
+}
+.search-types ul {
+       margin: 0;
+       padding: 0;
+       list-style: none;
+}
+.search-types li {
+       float: left;
+       margin: 0;
+       padding: 0;
+}
+.search-types a {
+       display: block;
+       padding: 0.5em;
+}
+.search-types .current a {
+       color: #222;
+       cursor: default;
+}
+.search-types .current a:hover {
+       text-decoration: none;
+}
+.results-info {
+       float: right;
+       padding: 0.5em;
+       padding-right: 0.75em;
+       color: #54595d;
+       font-size: 95%;
+}
+#mw-search-top-table div.oo-ui-actionFieldLayout {
+       float: left;
+       width: 100%;
+}
+
+/* Advanced options menu */
+/*==========================*/
+
+#mw-searchoptions {
+       /* Support: Firefox, needs `clear: both` on `fieldset` when zoom level > 100%, see T176499 */
+       clear: both;
+       padding: 0.5em 0.75em 0.75em 0.75em;
+       background-color: #f8f9fa;
+       margin: -1px 0 0;
+       border: 1px solid #c8ccd1;
+       border-radius: 0 0 2px 2px;
+}
+#mw-searchoptions legend {
+       display: none;
+}
+#mw-searchoptions h4 {
+       padding: 0;
+       margin: 0;
+       float: left;
+}
+#mw-searchoptions table {
+       float: left;
+       margin-right: 3em;
+       border-collapse: collapse;
+}
+#mw-searchoptions table td {
+       padding: 0 1em 0 0;
+       white-space: nowrap;
+}
+#mw-searchoptions .divider {
+       clear: both;
+       border-bottom: 1px solid #eaecf0;
+       padding-top: 0.5em;
+       margin-bottom: 0.5em;
+}
+#mw-search-menu {
+       padding-left: 6em;
+       font-size: 85%;
+}
+
+#mw-search-interwiki {
+       float: right;
+       width: 18em;
+       border: 1px solid #a2a9b1;
+       margin-top: 2ex;
+}
+
+.searchalttitle,
+#mw-search-interwiki li {
+       font-size: 95%;
+}
+.mw-search-interwiki-more {
+       float: right;
+       font-size: 90%;
+}
+#mw-search-interwiki-caption {
+       text-align: center;
+       font-weight: bold;
+       font-size: 95%;
+}
+.mw-search-interwiki-project {
+       font-size: 97%;
+       text-align: left;
+       padding: 0.15em 0.15em 0.2em 0.2em;
+       background-color: #eaecf0;
+       border-top: 1px solid #c8ccd1;
+}
+
+.searchdidyoumean {
+       font-size: 127%;
+       margin-top: 0.8em;
+       /* Note that this color won't affect the link, as desired. */
+       color: #d33;
+}
diff --git a/resources/src/mediawiki.special.search/search.css b/resources/src/mediawiki.special.search/search.css
new file mode 100644 (file)
index 0000000..aad784e
--- /dev/null
@@ -0,0 +1,9 @@
+#mw-search-togglebox {
+       float: right;
+}
+#mw-search-togglebox label {
+       margin-right: 0.25em;
+}
+#mw-search-togglebox input {
+       margin-left: 0.25em;
+}
diff --git a/resources/src/mediawiki.special.search/search.js b/resources/src/mediawiki.special.search/search.js
new file mode 100644 (file)
index 0000000..e809f2e
--- /dev/null
@@ -0,0 +1,60 @@
+/*!
+ * JavaScript for Special:Search
+ */
+( function ( mw, $ ) {
+       $( function () {
+               var $checkboxes, $headerLinks, updateHeaderLinks, searchWidget;
+
+               // Emulate HTML5 autofocus behavior in non HTML5 compliant browsers
+               if ( !( 'autofocus' in document.createElement( 'input' ) ) ) {
+                       $( 'input[autofocus]' ).eq( 0 ).focus();
+               }
+
+               // Create check all/none button
+               $checkboxes = $( '#powersearch input[id^=mw-search-ns]' );
+               $( '#mw-search-togglebox' ).append(
+                       $( '<label>' )
+                               .text( mw.msg( 'powersearch-togglelabel' ) )
+               ).append(
+                       $( '<input>' ).attr( 'type', 'button' )
+                               .attr( 'id', 'mw-search-toggleall' )
+                               .prop( 'value', mw.msg( 'powersearch-toggleall' ) )
+                               .click( function () {
+                                       $checkboxes.prop( 'checked', true );
+                               } )
+               ).append(
+                       $( '<input>' ).attr( 'type', 'button' )
+                               .attr( 'id', 'mw-search-togglenone' )
+                               .prop( 'value', mw.msg( 'powersearch-togglenone' ) )
+                               .click( function () {
+                                       $checkboxes.prop( 'checked', false );
+                               } )
+               );
+
+               // Change the header search links to what user entered
+               $headerLinks = $( '.search-types a' );
+               searchWidget = OO.ui.infuse( 'searchText' );
+               updateHeaderLinks = function ( value ) {
+                       $headerLinks.each( function () {
+                               var parts = $( this ).attr( 'href' ).split( 'search=' ),
+                                       lastpart = '',
+                                       prefix = 'search=';
+                               if ( parts.length > 1 && parts[ 1 ].indexOf( '&' ) !== -1 ) {
+                                       lastpart = parts[ 1 ].slice( parts[ 1 ].indexOf( '&' ) );
+                               } else {
+                                       prefix = '&search=';
+                               }
+                               this.href = parts[ 0 ] + prefix + encodeURIComponent( value ) + lastpart;
+                       } );
+               };
+               searchWidget.on( 'change', updateHeaderLinks );
+               updateHeaderLinks( searchWidget.getValue() );
+
+               // When saving settings, use the proper request method (POST instead of GET).
+               $( '#mw-search-powersearch-remember' ).change( function () {
+                       this.form.method = this.checked ? 'post' : 'get';
+               } ).trigger( 'change' );
+
+       } );
+
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special.undelete.js b/resources/src/mediawiki.special.undelete.js
new file mode 100644 (file)
index 0000000..e3cf598
--- /dev/null
@@ -0,0 +1,23 @@
+/*!
+ * JavaScript for Special:Undelete
+ */
+( function ( mw, $ ) {
+       $( function () {
+               var summaryCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
+                       summaryByteLimit = mw.config.get( 'wgCommentByteLimit' ),
+                       wpComment = OO.ui.infuse( $( '#wpComment' ).closest( '.oo-ui-widget' ) );
+
+               $( '#mw-undelete-invert' ).click( function () {
+                       $( '.mw-undelete-revlist input[type="checkbox"]' ).prop( 'checked', function ( i, val ) {
+                               return !val;
+                       } );
+               } );
+
+               // Limit to bytes or UTF-8 codepoints, depending on MediaWiki's configuration
+               if ( summaryCodePointLimit ) {
+                       mw.widgets.visibleCodePointLimit( wpComment, summaryCodePointLimit );
+               } else if ( summaryByteLimit ) {
+                       mw.widgets.visibleByteLimit( wpComment, summaryByteLimit );
+               }
+       } );
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special.unwatchedPages/unwatchedPages.css b/resources/src/mediawiki.special.unwatchedPages/unwatchedPages.css
new file mode 100644 (file)
index 0000000..69fec08
--- /dev/null
@@ -0,0 +1,7 @@
+.mw-watched-item {
+       text-decoration: line-through;
+}
+
+.mw-watch-link-disabled {
+       pointer-events: none;
+}
diff --git a/resources/src/mediawiki.special.unwatchedPages/unwatchedPages.js b/resources/src/mediawiki.special.unwatchedPages/unwatchedPages.js
new file mode 100644 (file)
index 0000000..0886f8c
--- /dev/null
@@ -0,0 +1,49 @@
+/*!
+ * JavaScript for Special:UnwatchedPages
+ */
+( function ( mw, $ ) {
+       $( function () {
+               $( 'a.mw-watch-link' ).click( function ( e ) {
+                       var promise,
+                               api = new mw.Api(),
+                               $link = $( this ),
+                               $subjectLink = $link.closest( 'li' ).children( 'a' ).eq( 0 ),
+                               title = mw.util.getParamValue( 'title', $link.attr( 'href' ) );
+                       // nice format
+                       title = mw.Title.newFromText( title ).toText();
+                       $link.addClass( 'mw-watch-link-disabled' );
+
+                       // Preload the notification module for mw.notify
+                       mw.loader.load( 'mediawiki.notification' );
+
+                       // Use the class to determine whether to watch or unwatch
+                       if ( !$subjectLink.hasClass( 'mw-watched-item' ) ) {
+                               $link.text( mw.msg( 'watching' ) );
+                               promise = api.watch( title ).done( function () {
+                                       $subjectLink.addClass( 'mw-watched-item' );
+                                       $link.text( mw.msg( 'unwatch' ) );
+                                       mw.notify( mw.msg( 'addedwatchtext-short', title ) );
+                               } ).fail( function () {
+                                       $link.text( mw.msg( 'watch' ) );
+                                       mw.notify( mw.msg( 'watcherrortext', title ), { type: 'error' } );
+                               } );
+                       } else {
+                               $link.text( mw.msg( 'unwatching' ) );
+                               promise = api.unwatch( title ).done( function () {
+                                       $subjectLink.removeClass( 'mw-watched-item' );
+                                       $link.text( mw.msg( 'watch' ) );
+                                       mw.notify( mw.msg( 'removedwatchtext-short', title ) );
+                               } ).fail( function () {
+                                       $link.text( mw.msg( 'unwatch' ) );
+                                       mw.notify( mw.msg( 'watcherrortext', title ), { type: 'error' } );
+                               } );
+                       }
+
+                       promise.always( function () {
+                               $link.removeClass( 'mw-watch-link-disabled' );
+                       } );
+
+                       e.preventDefault();
+               } );
+       } );
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special.upload/templates/thumbnail.html b/resources/src/mediawiki.special.upload/templates/thumbnail.html
new file mode 100644 (file)
index 0000000..bf0e701
--- /dev/null
@@ -0,0 +1,8 @@
+<div id="mw-upload-thumbnail" class="thumb tright">
+       <div class="thumbinner">
+               <div class="thumbcaption">
+                       <div class="filename"></div>
+                       <div class="fileinfo"></div>
+               </div>
+       </div>
+</div>
diff --git a/resources/src/mediawiki.special.upload/upload.js b/resources/src/mediawiki.special.upload/upload.js
new file mode 100644 (file)
index 0000000..144659a
--- /dev/null
@@ -0,0 +1,654 @@
+/**
+ * JavaScript for Special:Upload
+ *
+ * @private
+ * @class mw.special.upload
+ * @singleton
+ */
+
+/* global Uint8Array */
+
+( function ( mw, $ ) {
+       var uploadWarning, uploadTemplatePreview,
+               ajaxUploadDestCheck = mw.config.get( 'wgAjaxUploadDestCheck' ),
+               $license = $( '#wpLicense' );
+
+       window.wgUploadWarningObj = uploadWarning = {
+               responseCache: { '': '&nbsp;' },
+               nameToCheck: '',
+               typing: false,
+               delay: 500, // ms
+               timeoutID: false,
+
+               keypress: function () {
+                       if ( !ajaxUploadDestCheck ) {
+                               return;
+                       }
+
+                       // Find file to upload
+                       if ( !$( '#wpDestFile' ).length || !$( '#wpDestFile-warning' ).length ) {
+                               return;
+                       }
+
+                       this.nameToCheck = $( '#wpDestFile' ).val();
+
+                       // Clear timer
+                       if ( this.timeoutID ) {
+                               clearTimeout( this.timeoutID );
+                       }
+                       // Check response cache
+                       if ( this.responseCache.hasOwnProperty( this.nameToCheck ) ) {
+                               this.setWarning( this.responseCache[ this.nameToCheck ] );
+                               return;
+                       }
+
+                       this.timeoutID = setTimeout( function () {
+                               uploadWarning.timeout();
+                       }, this.delay );
+               },
+
+               checkNow: function ( fname ) {
+                       if ( !ajaxUploadDestCheck ) {
+                               return;
+                       }
+                       if ( this.timeoutID ) {
+                               clearTimeout( this.timeoutID );
+                       }
+                       this.nameToCheck = fname;
+                       this.timeout();
+               },
+
+               timeout: function () {
+                       var $spinnerDestCheck, title;
+                       if ( !ajaxUploadDestCheck || this.nameToCheck.trim() === '' ) {
+                               return;
+                       }
+                       $spinnerDestCheck = $.createSpinner().insertAfter( '#wpDestFile' );
+                       title = mw.Title.newFromText( this.nameToCheck, mw.config.get( 'wgNamespaceIds' ).file );
+
+                       ( new mw.Api() ).get( {
+                               formatversion: 2,
+                               action: 'query',
+                               // If title is empty, user input is invalid, the API call will produce details about why
+                               titles: [ title ? title.getPrefixedText() : this.nameToCheck ],
+                               prop: 'imageinfo',
+                               iiprop: 'uploadwarning',
+                               errorformat: 'html',
+                               errorlang: mw.config.get( 'wgUserLanguage' )
+                       } ).done( function ( result ) {
+                               var
+                                       resultOut = '',
+                                       page = result.query.pages[ 0 ];
+                               if ( page.imageinfo ) {
+                                       resultOut = page.imageinfo[ 0 ].html;
+                               } else if ( page.invalidreason ) {
+                                       resultOut = page.invalidreason.html;
+                               }
+                               uploadWarning.processResult( resultOut, uploadWarning.nameToCheck );
+                       } ).always( function () {
+                               $spinnerDestCheck.remove();
+                       } );
+               },
+
+               processResult: function ( result, fileName ) {
+                       this.setWarning( result );
+                       this.responseCache[ fileName ] = result;
+               },
+
+               setWarning: function ( warning ) {
+                       var $warningBox = $( '#wpDestFile-warning' ),
+                               $warning = $( $.parseHTML( warning ) );
+                       mw.hook( 'wikipage.content' ).fire( $warning );
+                       $warningBox.empty().append( $warning );
+
+                       // Set a value in the form indicating that the warning is acknowledged and
+                       // doesn't need to be redisplayed post-upload
+                       if ( !warning ) {
+                               $( '#wpDestFileWarningAck' ).val( '' );
+                               $warningBox.removeAttr( 'class' );
+                       } else {
+                               $( '#wpDestFileWarningAck' ).val( '1' );
+                               $warningBox.attr( 'class', 'mw-destfile-warning' );
+                       }
+
+               }
+       };
+
+       window.wgUploadTemplatePreviewObj = uploadTemplatePreview = {
+
+               responseCache: { '': '' },
+
+               /**
+                * @param {jQuery} $element The element whose .val() will be previewed
+                * @param {jQuery} $previewContainer The container to display the preview in
+                */
+               getPreview: function ( $element, $previewContainer ) {
+                       var template = $element.val(),
+                               $spinner;
+
+                       if ( this.responseCache.hasOwnProperty( template ) ) {
+                               this.showPreview( this.responseCache[ template ], $previewContainer );
+                               return;
+                       }
+
+                       $spinner = $.createSpinner().insertAfter( $element );
+
+                       ( new mw.Api() ).parse( '{{' + template + '}}', {
+                               title: $( '#wpDestFile' ).val() || 'File:Sample.jpg',
+                               prop: 'text',
+                               pst: true,
+                               uselang: mw.config.get( 'wgUserLanguage' )
+                       } ).done( function ( result ) {
+                               uploadTemplatePreview.processResult( result, template, $previewContainer );
+                       } ).always( function () {
+                               $spinner.remove();
+                       } );
+               },
+
+               processResult: function ( result, template, $previewContainer ) {
+                       this.responseCache[ template ] = result;
+                       this.showPreview( this.responseCache[ template ], $previewContainer );
+               },
+
+               showPreview: function ( preview, $previewContainer ) {
+                       $previewContainer.html( preview );
+               }
+
+       };
+
+       $( function () {
+               // AJAX wpDestFile warnings
+               if ( ajaxUploadDestCheck ) {
+                       // Insert an event handler that fetches upload warnings when wpDestFile
+                       // has been changed
+                       $( '#wpDestFile' ).change( function () {
+                               uploadWarning.checkNow( $( this ).val() );
+                       } );
+                       // Insert a row where the warnings will be displayed just below the
+                       // wpDestFile row
+                       $( '#mw-htmlform-description tbody' ).append(
+                               $( '<tr>' ).append(
+                                       $( '<td>' )
+                                               .attr( 'id', 'wpDestFile-warning' )
+                                               .attr( 'colspan', 2 )
+                               )
+                       );
+               }
+
+               if ( mw.config.get( 'wgAjaxLicensePreview' ) && $license.length ) {
+                       // License selector check
+                       $license.change( function () {
+                               // We might show a preview
+                               uploadTemplatePreview.getPreview( $license, $( '#mw-license-preview' ) );
+                       } );
+
+                       // License selector table row
+                       $license.closest( 'tr' ).after(
+                               $( '<tr>' ).append(
+                                       $( '<td>' ),
+                                       $( '<td>' ).attr( 'id', 'mw-license-preview' )
+                               )
+                       );
+               }
+
+               // fillDestFile setup
+               mw.config.get( 'wgUploadSourceIds' ).forEach( function ( sourceId ) {
+                       $( '#' + sourceId ).change( function () {
+                               var path, slash, backslash, fname;
+                               if ( !mw.config.get( 'wgUploadAutoFill' ) ) {
+                                       return;
+                               }
+                               // Remove any previously flagged errors
+                               $( '#mw-upload-permitted' ).attr( 'class', '' );
+                               $( '#mw-upload-prohibited' ).attr( 'class', '' );
+
+                               path = $( this ).val();
+                               // Find trailing part
+                               slash = path.lastIndexOf( '/' );
+                               backslash = path.lastIndexOf( '\\' );
+                               if ( slash === -1 && backslash === -1 ) {
+                                       fname = path;
+                               } else if ( slash > backslash ) {
+                                       fname = path.slice( slash + 1 );
+                               } else {
+                                       fname = path.slice( backslash + 1 );
+                               }
+
+                               // Clear the filename if it does not have a valid extension.
+                               // URLs are less likely to have a useful extension, so don't include them in the
+                               // extension check.
+                               if (
+                                       mw.config.get( 'wgCheckFileExtensions' ) &&
+                                       mw.config.get( 'wgStrictFileExtensions' ) &&
+                                       Array.isArray( mw.config.get( 'wgFileExtensions' ) ) &&
+                                       $( this ).attr( 'id' ) !== 'wpUploadFileURL'
+                               ) {
+                                       if (
+                                               fname.lastIndexOf( '.' ) === -1 ||
+                                               mw.config.get( 'wgFileExtensions' ).map( function ( element ) {
+                                                       return element.toLowerCase();
+                                               } ).indexOf( fname.slice( fname.lastIndexOf( '.' ) + 1 ).toLowerCase() ) === -1
+                                       ) {
+                                               // Not a valid extension
+                                               // Clear the upload and set mw-upload-permitted to error
+                                               $( this ).val( '' );
+                                               $( '#mw-upload-permitted' ).attr( 'class', 'error' );
+                                               $( '#mw-upload-prohibited' ).attr( 'class', 'error' );
+                                               // Clear wpDestFile as well
+                                               $( '#wpDestFile' ).val( '' );
+
+                                               return false;
+                                       }
+                               }
+
+                               // Replace spaces by underscores
+                               fname = fname.replace( / /g, '_' );
+                               // Capitalise first letter if needed
+                               if ( mw.config.get( 'wgCapitalizeUploads' ) ) {
+                                       fname = fname[ 0 ].toUpperCase() + fname.slice( 1 );
+                               }
+
+                               // Output result
+                               if ( $( '#wpDestFile' ).length ) {
+                                       // Call decodeURIComponent function to remove possible URL-encoded characters
+                                       // from the file name (T32390). Especially likely with upload-form-url.
+                                       // decodeURIComponent can throw an exception if input is invalid utf-8
+                                       try {
+                                               $( '#wpDestFile' ).val( decodeURIComponent( fname ) );
+                                       } catch ( err ) {
+                                               $( '#wpDestFile' ).val( fname );
+                                       }
+                                       uploadWarning.checkNow( fname );
+                               }
+                       } );
+               } );
+       } );
+
+       // Add a preview to the upload form
+       $( function () {
+               /**
+                * Is the FileAPI available with sufficient functionality?
+                *
+                * @return {boolean}
+                */
+               function hasFileAPI() {
+                       return window.FileReader !== undefined;
+               }
+
+               /**
+                * Check if this is a recognizable image type...
+                * Also excludes files over 10M to avoid going insane on memory usage.
+                *
+                * TODO: Is there a way we can ask the browser what's supported in `<img>`s?
+                *
+                * TODO: Put SVG back after working around Firefox 7 bug <https://phabricator.wikimedia.org/T33643>
+                *
+                * @param {File} file
+                * @return {boolean}
+                */
+               function fileIsPreviewable( file ) {
+                       var known = [ 'image/png', 'image/gif', 'image/jpeg', 'image/svg+xml' ],
+                               tooHuge = 10 * 1024 * 1024;
+                       return ( known.indexOf( file.type ) !== -1 ) && file.size > 0 && file.size < tooHuge;
+               }
+
+               /**
+                * Format a file size attractively.
+                *
+                * TODO: Match numeric formatting
+                *
+                * @param {number} s
+                * @return {string}
+                */
+               function prettySize( s ) {
+                       var sizeMsgs = [ 'size-bytes', 'size-kilobytes', 'size-megabytes', 'size-gigabytes' ];
+                       while ( s >= 1024 && sizeMsgs.length > 1 ) {
+                               s /= 1024;
+                               sizeMsgs = sizeMsgs.slice( 1 );
+                       }
+                       return mw.msg( sizeMsgs[ 0 ], Math.round( s ) );
+               }
+
+               /**
+                * Start loading a file into memory; when complete, pass it as a
+                * data URL to the callback function. If the callbackBinary is set it will
+                * first be read as binary and afterwards as data URL. Useful if you want
+                * to do preprocessing on the binary data first.
+                *
+                * @param {File} file
+                * @param {Function} callback
+                * @param {Function} callbackBinary
+                */
+               function fetchPreview( file, callback, callbackBinary ) {
+                       var reader = new FileReader();
+                       if ( callbackBinary && 'readAsBinaryString' in reader ) {
+                               // To fetch JPEG metadata we need a binary string; start there.
+                               // TODO
+                               reader.onload = function () {
+                                       callbackBinary( reader.result );
+
+                                       // Now run back through the regular code path.
+                                       fetchPreview( file, callback );
+                               };
+                               reader.readAsBinaryString( file );
+                       } else if ( callbackBinary && 'readAsArrayBuffer' in reader ) {
+                               // readAsArrayBuffer replaces readAsBinaryString
+                               // However, our JPEG metadata library wants a string.
+                               // So, this is going to be an ugly conversion.
+                               reader.onload = function () {
+                                       var i,
+                                               buffer = new Uint8Array( reader.result ),
+                                               string = '';
+                                       for ( i = 0; i < buffer.byteLength; i++ ) {
+                                               string += String.fromCharCode( buffer[ i ] );
+                                       }
+                                       callbackBinary( string );
+
+                                       // Now run back through the regular code path.
+                                       fetchPreview( file, callback );
+                               };
+                               reader.readAsArrayBuffer( file );
+                       } else if ( 'URL' in window && 'createObjectURL' in window.URL ) {
+                               // Supported in Firefox 4.0 and above <https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL>
+                               // WebKit has it in a namespace for now but that's ok. ;)
+                               //
+                               // Lifetime of this URL is until document close, which is fine
+                               // for Special:Upload -- if this code gets used on longer-running
+                               // pages, add a revokeObjectURL() when it's no longer needed.
+                               //
+                               // Prefer this over readAsDataURL for Firefox 7 due to bug reading
+                               // some SVG files from data URIs <https://bugzilla.mozilla.org/show_bug.cgi?id=694165>
+                               callback( window.URL.createObjectURL( file ) );
+                       } else {
+                               // This ends up decoding the file to base-64 and back again, which
+                               // feels horribly inefficient.
+                               reader.onload = function () {
+                                       callback( reader.result );
+                               };
+                               reader.readAsDataURL( file );
+                       }
+               }
+
+               /**
+                * Clear the file upload preview area.
+                */
+               function clearPreview() {
+                       $( '#mw-upload-thumbnail' ).remove();
+               }
+
+               /**
+                * Show a thumbnail preview of PNG, JPEG, GIF, and SVG files prior to upload
+                * in browsers supporting HTML5 FileAPI.
+                *
+                * As of this writing, known good:
+                *
+                * - Firefox 3.6+
+                * - Chrome 7.something
+                *
+                * TODO: Check file size limits and warn of likely failures
+                *
+                * @param {File} file
+                */
+               function showPreview( file ) {
+                       var $canvas,
+                               ctx,
+                               meta,
+                               previewSize = 180,
+                               $spinner = $.createSpinner( { size: 'small', type: 'block' } )
+                                       .css( { width: previewSize, height: previewSize } ),
+                               thumb = mw.template.get( 'mediawiki.special.upload', 'thumbnail.html' ).render();
+
+                       thumb
+                               .find( '.filename' ).text( file.name ).end()
+                               .find( '.fileinfo' ).text( prettySize( file.size ) ).end()
+                               .find( '.thumbinner' ).prepend( $spinner ).end();
+
+                       $canvas = $( '<canvas>' ).attr( { width: previewSize, height: previewSize } );
+                       ctx = $canvas[ 0 ].getContext( '2d' );
+                       $( '#mw-htmlform-source' ).parent().prepend( thumb );
+
+                       fetchPreview( file, function ( dataURL ) {
+                               var img = new Image(),
+                                       rotation = 0;
+
+                               if ( meta && meta.tiff && meta.tiff.Orientation ) {
+                                       rotation = ( 360 - ( function () {
+                                               // See BitmapHandler class in PHP
+                                               switch ( meta.tiff.Orientation.value ) {
+                                                       case 8:
+                                                               return 90;
+                                                       case 3:
+                                                               return 180;
+                                                       case 6:
+                                                               return 270;
+                                                       default:
+                                                               return 0;
+                                               }
+                                       }() ) ) % 360;
+                               }
+
+                               img.onload = function () {
+                                       var info, width, height, x, y, dx, dy, logicalWidth, logicalHeight;
+
+                                       // Fit the image within the previewSizexpreviewSize box
+                                       if ( img.width > img.height ) {
+                                               width = previewSize;
+                                               height = img.height / img.width * previewSize;
+                                       } else {
+                                               height = previewSize;
+                                               width = img.width / img.height * previewSize;
+                                       }
+                                       // Determine the offset required to center the image
+                                       dx = ( 180 - width ) / 2;
+                                       dy = ( 180 - height ) / 2;
+                                       switch ( rotation ) {
+                                               // If a rotation is applied, the direction of the axis
+                                               // changes as well. You can derive the values below by
+                                               // drawing on paper an axis system, rotate it and see
+                                               // where the positive axis direction is
+                                               case 0:
+                                                       x = dx;
+                                                       y = dy;
+                                                       logicalWidth = img.width;
+                                                       logicalHeight = img.height;
+                                                       break;
+                                               case 90:
+
+                                                       x = dx;
+                                                       y = dy - previewSize;
+                                                       logicalWidth = img.height;
+                                                       logicalHeight = img.width;
+                                                       break;
+                                               case 180:
+                                                       x = dx - previewSize;
+                                                       y = dy - previewSize;
+                                                       logicalWidth = img.width;
+                                                       logicalHeight = img.height;
+                                                       break;
+                                               case 270:
+                                                       x = dx - previewSize;
+                                                       y = dy;
+                                                       logicalWidth = img.height;
+                                                       logicalHeight = img.width;
+                                                       break;
+                                       }
+
+                                       ctx.clearRect( 0, 0, 180, 180 );
+                                       ctx.rotate( rotation / 180 * Math.PI );
+                                       ctx.drawImage( img, x, y, width, height );
+                                       $spinner.replaceWith( $canvas );
+
+                                       // Image size
+                                       info = mw.msg( 'widthheight', logicalWidth, logicalHeight ) +
+                                               ', ' + prettySize( file.size );
+
+                                       $( '#mw-upload-thumbnail .fileinfo' ).text( info );
+                               };
+                               img.onerror = function () {
+                                       // Can happen for example for invalid SVG files
+                                       clearPreview();
+                               };
+                               img.src = dataURL;
+                       }, mw.config.get( 'wgFileCanRotate' ) ? function ( data ) {
+                               var jpegmeta = mw.loader.require( 'mediawiki.libs.jpegmeta' );
+                               try {
+                                       meta = jpegmeta( data, file.fileName );
+                                       // eslint-disable-next-line no-underscore-dangle, camelcase
+                                       meta._binary_data = null;
+                               } catch ( e ) {
+                                       meta = null;
+                               }
+                       } : null );
+               }
+
+               /**
+                * Check if the file does not exceed the maximum size
+                *
+                * @param {File} file
+                * @return {boolean}
+                */
+               function checkMaxUploadSize( file ) {
+                       var maxSize, $error;
+
+                       function getMaxUploadSize( type ) {
+                               var sizes = mw.config.get( 'wgMaxUploadSize' );
+
+                               if ( sizes[ type ] !== undefined ) {
+                                       return sizes[ type ];
+                               }
+                               return sizes[ '*' ];
+                       }
+
+                       $( '.mw-upload-source-error' ).remove();
+
+                       maxSize = getMaxUploadSize( 'file' );
+                       if ( file.size > maxSize ) {
+                               $error = $( '<p class="error mw-upload-source-error" id="wpSourceTypeFile-error">' +
+                                       mw.message( 'largefileserver', file.size, maxSize ).escaped() + '</p>' );
+
+                               $( '#wpUploadFile' ).after( $error );
+
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               /* Initialization */
+               if ( hasFileAPI() ) {
+                       // Update thumbnail when the file selection control is updated.
+                       $( '#wpUploadFile' ).change( function () {
+                               var file;
+                               clearPreview();
+                               if ( this.files && this.files.length ) {
+                                       // Note: would need to be updated to handle multiple files.
+                                       file = this.files[ 0 ];
+
+                                       if ( !checkMaxUploadSize( file ) ) {
+                                               return;
+                                       }
+
+                                       if ( fileIsPreviewable( file ) ) {
+                                               showPreview( file );
+                                       }
+                               }
+                       } );
+               }
+       } );
+
+       // Disable all upload source fields except the selected one
+       $( function () {
+               var $rows = $( '.mw-htmlform-field-UploadSourceField' );
+
+               $rows.on( 'change', 'input[type="radio"]', function ( e ) {
+                       var currentRow = e.delegateTarget;
+
+                       if ( !this.checked ) {
+                               return;
+                       }
+
+                       $( '.mw-upload-source-error' ).remove();
+
+                       // Enable selected upload method
+                       $( currentRow ).find( 'input' ).prop( 'disabled', false );
+
+                       // Disable inputs of other upload methods
+                       // (except for the radio button to re-enable it)
+                       $rows
+                               .not( currentRow )
+                               .find( 'input[type!="radio"]' )
+                               .prop( 'disabled', true );
+               } );
+
+               // Set initial state
+               if ( !$( '#wpSourceTypeurl' ).prop( 'checked' ) ) {
+                       $( '#wpUploadFileURL' ).prop( 'disabled', true );
+               }
+       } );
+
+       $( function () {
+               // Prevent losing work
+               var allowCloseWindow,
+                       $uploadForm = $( '#mw-upload-form' );
+
+               if ( !mw.user.options.get( 'useeditwarning' ) ) {
+                       // If the user doesn't want edit warnings, don't set things up.
+                       return;
+               }
+
+               $uploadForm.data( 'origtext', $uploadForm.serialize() );
+
+               allowCloseWindow = mw.confirmCloseWindow( {
+                       test: function () {
+                               return $( '#wpUploadFile' ).get( 0 ).files.length !== 0 ||
+                                       $uploadForm.data( 'origtext' ) !== $uploadForm.serialize();
+                       },
+
+                       message: mw.msg( 'editwarning-warning' ),
+                       namespace: 'uploadwarning'
+               } );
+
+               $uploadForm.submit( function () {
+                       allowCloseWindow.release();
+               } );
+       } );
+
+       // Add tabindex to mw-editTools
+       $( function () {
+               // Function to change tabindex for all links within mw-editTools
+               function setEditTabindex( $val ) {
+                       $( '.mw-editTools' ).find( 'a' ).each( function () {
+                               $( this ).attr( 'tabindex', $val );
+                       } );
+               }
+
+               // Change tabindex to 0 if user pressed spaced or enter while focused
+               $( '.mw-editTools' ).on( 'keypress', function ( e ) {
+                       // Don't continue if pressed key was not enter or spacebar
+                       if ( e.which !== 13 && e.which !== 32 ) {
+                               return;
+                       }
+
+                       // Change tabindex only when main div has focus
+                       if ( $( this ).is( ':focus' ) ) {
+                               $( this ).find( 'a' ).first().focus();
+                               setEditTabindex( '0' );
+                       }
+               } );
+
+               // Reset tabindex for elements when user focused out mw-editTools
+               $( '.mw-editTools' ).on( 'focusout', function ( e ) {
+                       // Don't continue if relatedTarget is within mw-editTools
+                       if ( e.relatedTarget !== null && $( e.relatedTarget ).closest( '.mw-editTools' ).length > 0 ) {
+                               return;
+                       }
+
+                       // Reset tabindex back to -1
+                       setEditTabindex( '-1' );
+               } );
+
+               // Set initial tabindex for mw-editTools to 0 and to -1 for all links
+               $( '.mw-editTools' ).attr( 'tabindex', '0' );
+               setEditTabindex( '-1' );
+       } );
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special.userlogin.common.styles/images/icon-lock.png b/resources/src/mediawiki.special.userlogin.common.styles/images/icon-lock.png
new file mode 100644 (file)
index 0000000..03f0eec
Binary files /dev/null and b/resources/src/mediawiki.special.userlogin.common.styles/images/icon-lock.png differ
diff --git a/resources/src/mediawiki.special.userlogin.common.styles/userlogin.css b/resources/src/mediawiki.special.userlogin.common.styles/userlogin.css
new file mode 100644 (file)
index 0000000..2366249
--- /dev/null
@@ -0,0 +1,75 @@
+/* User login and signup forms */
+.mw-ui-vform .mw-form-related-link-container {
+       margin-bottom: 0.5em;
+       text-align: center;
+}
+
+.mw-ui-vform .mw-secure {
+       /* @embed */
+       background: url( images/icon-lock.png ) no-repeat left center;
+       margin: 0 0 0 1px;
+       padding: 0 0 0 11px;
+}
+
+/*
+ * When inside the VForm style, disable the border that Vector and other skins
+ * put on the div surrounding the login/create account form.
+ * Also disable the margin and padding that Vector puts around the form.
+ */
+.mw-ui-container #userloginForm,
+.mw-ui-container #userlogin {
+       border: 0;
+       margin: 0;
+       padding: 0;
+}
+
+/* Reposition and resize language links, which appear on a per-wiki basis */
+.mw-ui-container #languagelinks {
+       margin-bottom: 2em;
+       font-size: 0.8em;
+}
+
+/* Put some space under template's header, which may contain CAPTCHA HTML. */
+section.mw-form-header {
+       margin-bottom: 10px;
+}
+
+/* shuffled CAPTCHA */
+#wpCaptchaWord {
+       margin-top: 6px;
+}
+
+.fancycaptcha-captcha-container {
+       background-color: #f8f9fa;
+       margin-bottom: 15px;
+       border: 1px solid #c8ccd1;
+       border-radius: 2px;
+       padding: 8px;
+       text-align: center;
+}
+
+.mw-createacct-captcha-assisted {
+       display: block;
+       margin-top: 0.5em;
+}
+
+/* Put a border around the fancycaptcha-image-container. */
+.fancycaptcha-captcha-and-reload {
+       border: 1px solid #c8ccd1;
+       border-radius: 2px 2px 0 0;
+       /* Other display formats end up too wide */
+       display: table-cell;
+       width: 270px;
+       background-color: #fff;
+}
+
+.fancycaptcha-captcha-container .mw-ui-input {
+       margin-top: -1px;
+       border-color: #c8ccd1;
+       border-radius: 0 0 2px 2px;
+}
+
+/* Make the fancycaptcha-image-container full-width within its parent. */
+.fancycaptcha-image-container {
+       width: 100%;
+}
diff --git a/resources/src/mediawiki.special.userlogin.login.styles/images/glyph-people-large.png b/resources/src/mediawiki.special.userlogin.login.styles/images/glyph-people-large.png
new file mode 100644 (file)
index 0000000..cba3caf
Binary files /dev/null and b/resources/src/mediawiki.special.userlogin.login.styles/images/glyph-people-large.png differ
diff --git a/resources/src/mediawiki.special.userlogin.login.styles/login.css b/resources/src/mediawiki.special.userlogin.login.styles/login.css
new file mode 100644 (file)
index 0000000..fe013bc
--- /dev/null
@@ -0,0 +1,29 @@
+/* The login form invites users to create an account */
+#mw-createaccount-cta {
+       width: 20em;
+       /* @embed */
+       background: url( images/glyph-people-large.png ) no-repeat 50%;
+       margin: 0 auto;
+       padding-top: 7.8em;
+       font-weight: bold;
+}
+
+/* Login Button, following 'ButtonWidget (progressive)' from OOUI */
+#mw-createaccount-join {
+       background-color: #f8f9fa;
+       color: #36c;
+}
+#mw-createaccount-join:hover {
+       background-color: #fff;
+       border-color: #859ecc;
+       box-shadow: none;
+}
+#mw-createaccount-join:active {
+       background-color: #eff3fa;
+       color: #2a4b8d;
+       border-color: #2a4b8d;
+}
+#mw-createaccount-join:focus {
+       border-color: #36c;
+       box-shadow: inset 0 0 0 1px #36c;
+}
diff --git a/resources/src/mediawiki.special.userlogin.signup.js b/resources/src/mediawiki.special.userlogin.signup.js
new file mode 100644 (file)
index 0000000..8a61afb
--- /dev/null
@@ -0,0 +1,122 @@
+/*!
+ * JavaScript for signup form.
+ */
+( function ( mw, $ ) {
+       // When sending password by email, hide the password input fields.
+       $( function () {
+               // Always required if checked, otherwise it depends, so we use the original
+               var $emailLabel = $( 'label[for="wpEmail"]' ),
+                       originalText = $emailLabel.text(),
+                       requiredText = mw.message( 'createacct-emailrequired' ).text(),
+                       $createByMailCheckbox = $( '#wpCreateaccountMail' ),
+                       $beforePwds = $( '.mw-row-password:first' ).prev(),
+                       $pwds;
+
+               function updateForCheckbox() {
+                       var checked = $createByMailCheckbox.prop( 'checked' );
+                       if ( checked ) {
+                               $pwds = $( '.mw-row-password' ).detach();
+                               $emailLabel.text( requiredText );
+                       } else {
+                               if ( $pwds ) {
+                                       $beforePwds.after( $pwds );
+                                       $pwds = null;
+                               }
+                               $emailLabel.text( originalText );
+                       }
+               }
+
+               $createByMailCheckbox.on( 'change', updateForCheckbox );
+               updateForCheckbox();
+       } );
+
+       // Check if the username is invalid or already taken
+       mw.hook( 'htmlform.enhance' ).add( function ( $root ) {
+               var $usernameInput = $root.find( '#wpName2' ),
+                       $passwordInput = $root.find( '#wpPassword2' ),
+                       $emailInput = $root.find( '#wpEmail' ),
+                       $realNameInput = $root.find( '#wpRealName' ),
+                       api = new mw.Api(),
+                       usernameChecker, passwordChecker;
+
+               function checkUsername( username ) {
+                       // We could just use .then() if we didn't have to pass on .abort()…
+                       var d, apiPromise;
+
+                       d = $.Deferred();
+                       apiPromise = api.get( {
+                               action: 'query',
+                               list: 'users',
+                               ususers: username,
+                               usprop: 'cancreate',
+                               formatversion: 2,
+                               errorformat: 'html',
+                               errorsuselocal: true,
+                               uselang: mw.config.get( 'wgUserLanguage' )
+                       } )
+                               .done( function ( resp ) {
+                                       var userinfo = resp.query.users[ 0 ];
+
+                                       if ( resp.query.users.length !== 1 || userinfo.invalid ) {
+                                               d.resolve( { valid: false, messages: [ mw.message( 'noname' ).parseDom() ] } );
+                                       } else if ( userinfo.userid !== undefined ) {
+                                               d.resolve( { valid: false, messages: [ mw.message( 'userexists' ).parseDom() ] } );
+                                       } else if ( !userinfo.cancreate ) {
+                                               d.resolve( {
+                                                       valid: false,
+                                                       messages: userinfo.cancreateerror ? userinfo.cancreateerror.map( function ( m ) {
+                                                               return m.html;
+                                                       } ) : []
+                                               } );
+                                       } else {
+                                               d.resolve( { valid: true, messages: [] } );
+                                       }
+                               } )
+                               .fail( d.reject );
+
+                       return d.promise( { abort: apiPromise.abort } );
+               }
+
+               function checkPassword() {
+                       // We could just use .then() if we didn't have to pass on .abort()…
+                       var apiPromise,
+                               d = $.Deferred();
+
+                       if ( $usernameInput.val().trim() === '' ) {
+                               d.resolve( { valid: true, messages: [] } );
+                               return d.promise();
+                       }
+
+                       apiPromise = api.post( {
+                               action: 'validatepassword',
+                               user: $usernameInput.val(),
+                               password: $passwordInput.val(),
+                               email: $emailInput.val() || '',
+                               realname: $realNameInput.val() || '',
+                               formatversion: 2,
+                               errorformat: 'html',
+                               errorsuselocal: true,
+                               uselang: mw.config.get( 'wgUserLanguage' )
+                       } )
+                               .done( function ( resp ) {
+                                       var pwinfo = resp.validatepassword || {};
+
+                                       d.resolve( {
+                                               valid: pwinfo.validity === 'Good',
+                                               messages: pwinfo.validitymessages ? pwinfo.validitymessages.map( function ( m ) {
+                                                       return m.html;
+                                               } ) : []
+                                       } );
+                               } )
+                               .fail( d.reject );
+
+                       return d.promise( { abort: apiPromise.abort } );
+               }
+
+               usernameChecker = new mw.htmlform.Checker( $usernameInput, checkUsername );
+               usernameChecker.attach();
+
+               passwordChecker = new mw.htmlform.Checker( $passwordInput, checkPassword );
+               passwordChecker.attach( $usernameInput.add( $emailInput ).add( $realNameInput ) );
+       } );
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special.userlogin.signup.styles/images/icon-contributors.png b/resources/src/mediawiki.special.userlogin.signup.styles/images/icon-contributors.png
new file mode 100644 (file)
index 0000000..30bf53a
Binary files /dev/null and b/resources/src/mediawiki.special.userlogin.signup.styles/images/icon-contributors.png differ
diff --git a/resources/src/mediawiki.special.userlogin.signup.styles/images/icon-edits.png b/resources/src/mediawiki.special.userlogin.signup.styles/images/icon-edits.png
new file mode 100644 (file)
index 0000000..17508f9
Binary files /dev/null and b/resources/src/mediawiki.special.userlogin.signup.styles/images/icon-edits.png differ
diff --git a/resources/src/mediawiki.special.userlogin.signup.styles/images/icon-pages.png b/resources/src/mediawiki.special.userlogin.signup.styles/images/icon-pages.png
new file mode 100644 (file)
index 0000000..8e37278
Binary files /dev/null and b/resources/src/mediawiki.special.userlogin.signup.styles/images/icon-pages.png differ
diff --git a/resources/src/mediawiki.special.userlogin.signup.styles/signup.css b/resources/src/mediawiki.special.userlogin.signup.styles/signup.css
new file mode 100644 (file)
index 0000000..3cfa5a8
--- /dev/null
@@ -0,0 +1,67 @@
+/* Disable the underline that Vector puts on h2 headings, and bold them. */
+.mw-ui-container h2 {
+       border: 0;
+       font-weight: bold;
+}
+
+/* Benefits column CSS to the right (if it fits) of the form. */
+.mw-ui-container #userloginForm {
+       float: left;
+       /* Override the right margin of the form to give space in case a benefits
+        * column appears to the side. */
+       margin-right: 100px;
+       /* Override `.mw-body-content` to ensure useful, readable paragraphs */
+       line-height: 1.4;
+}
+
+.mw-createacct-benefits-container {
+       /* Keeps this column compact and close to the form, but tends to squish contents. */
+       float: left;
+}
+
+.mw-createacct-benefits-container h2 {
+       margin-bottom: 30px;
+}
+
+.mw-number-text.icon-edits {
+       /* @embed */
+       background: url( images/icon-edits.png ) no-repeat left center;
+}
+
+.mw-number-text.icon-pages {
+       /* @embed */
+       background: url( images/icon-pages.png ) no-repeat left center;
+}
+
+.mw-number-text.icon-contributors {
+       /* @embed */
+       background: url( images/icon-contributors.png ) no-repeat left center;
+}
+
+/*
+ * Special font for numbers in benefits, same as Vector's `@content-heading-font-family`.
+ * Needs an ID so that it's more specific than Vector's div#content h3.
+ */
+#bodyContent .mw-number-text h3 {
+       color: #222;
+       margin: 0;
+       padding: 0;
+       font-family: 'Linux Libertine', 'Georgia', 'Times', serif;
+       font-weight: normal;
+       font-size: 2.2em;
+       line-height: 1.2;
+       text-align: center;
+}
+
+/* Contains a “headlined” number and explanatory text, with space for an icon */
+.mw-number-text {
+       display: block;
+       font-size: 1.2em;
+       color: #444;
+       margin-top: 1em;
+       /* 80px wide icon plus "margin" */
+       padding: 0 0 0 95px;
+       /* Matches max icon height, ensures icon emblem is visible */
+       min-height: 75px;
+       text-align: center;
+}
diff --git a/resources/src/mediawiki.special.userrights.js b/resources/src/mediawiki.special.userrights.js
new file mode 100644 (file)
index 0000000..487e63a
--- /dev/null
@@ -0,0 +1,25 @@
+/*!
+ * JavaScript for Special:UserRights
+ */
+( function ( mw, $ ) {
+       var convertmessagebox = require( 'mediawiki.notification.convertmessagebox' ),
+               summaryCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
+               summaryByteLimit = mw.config.get( 'wgCommentByteLimit' ),
+               $wpReason = $( '#wpReason' );
+
+       // Replace successbox with notifications
+       convertmessagebox();
+
+       // Dynamically show/hide the "other time" input under each dropdown
+       $( '.mw-userrights-nested select' ).on( 'change', function ( e ) {
+               $( e.target.parentNode ).find( 'input' ).toggle( $( e.target ).val() === 'other' );
+       } );
+
+       // Limit to bytes or UTF-8 codepoints, depending on MediaWiki's configuration
+       if ( summaryCodePointLimit ) {
+               $wpReason.codePointLimit( summaryCodePointLimit );
+       } else if ( summaryByteLimit ) {
+               $wpReason.byteLimit( summaryByteLimit );
+       }
+
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special.version.css b/resources/src/mediawiki.special.version.css
new file mode 100644 (file)
index 0000000..1b8581a
--- /dev/null
@@ -0,0 +1,39 @@
+/*!
+ * Styling for Special:Version
+ */
+.mw-version-ext-name,
+.mw-version-library-name {
+       font-weight: bold;
+}
+
+.mw-version-ext-license,
+.mw-version-ext-vcs-timestamp {
+       white-space: nowrap;
+}
+
+th.mw-version-ext-col-label {
+       font-size: 0.9em;
+}
+
+.mw-version-ext-vcs-version {
+       unicode-bidi: embed;
+}
+
+.mw-version-credits {
+       column-width: 18em;
+       -moz-column-width: 18em;
+       -webkit-column-width: 18em;
+}
+
+.mw-version-credits ul {
+       margin-top: 0;
+       margin-bottom: 0;
+}
+
+.mw-version-license-info strong {
+       font-weight: normal;
+}
+
+.mw-version-license-info em {
+       font-style: normal;
+}
diff --git a/resources/src/mediawiki.special.watchlist/visitedstatus.js b/resources/src/mediawiki.special.watchlist/visitedstatus.js
new file mode 100644 (file)
index 0000000..6b25327
--- /dev/null
@@ -0,0 +1,12 @@
+/*!
+ * JavaScript for Special:Watchlist
+ */
+( function ( $ ) {
+       $( function () {
+               $( '.mw-changeslist-line-watched .mw-title a' ).on( 'click', function () {
+                       $( this )
+                               .closest( '.mw-changeslist-line-watched' )
+                               .removeClass( 'mw-changeslist-line-watched' );
+               } );
+       } );
+}( jQuery ) );
diff --git a/resources/src/mediawiki.special.watchlist/watchlist.js b/resources/src/mediawiki.special.watchlist/watchlist.js
new file mode 100644 (file)
index 0000000..565ed2c
--- /dev/null
@@ -0,0 +1,158 @@
+/*!
+ * JavaScript for Special:Watchlist
+ */
+( function ( mw, $, OO ) {
+       $( function () {
+               var api = new mw.Api(), $progressBar, $resetForm = $( '#mw-watchlist-resetbutton' );
+
+               // If the user wants to reset their watchlist, use an API call to do so (no reload required)
+               // Adapted from a user script by User:NQ of English Wikipedia
+               // (User:NQ/WatchlistResetConfirm.js)
+               $resetForm.submit( function ( event ) {
+                       var $button = $resetForm.find( 'input[name=mw-watchlist-reset-submit]' );
+
+                       event.preventDefault();
+
+                       // Disable reset button to prevent multiple concurrent requests
+                       $button.prop( 'disabled', true );
+
+                       if ( !$progressBar ) {
+                               $progressBar = new OO.ui.ProgressBarWidget( { progress: false } ).$element;
+                               $progressBar.css( {
+                                       position: 'absolute', width: '100%'
+                               } );
+                       }
+                       // Show progress bar
+                       $resetForm.append( $progressBar );
+
+                       // Use action=setnotificationtimestamp to mark all as visited,
+                       // then set all watchlist lines accordingly
+                       api.postWithToken( 'csrf', {
+                               formatversion: 2, action: 'setnotificationtimestamp', entirewatchlist: true
+                       } ).done( function () {
+                               // Enable button again
+                               $button.prop( 'disabled', false );
+                               // Hide the button because further clicks can not generate any visual changes
+                               $button.css( 'visibility', 'hidden' );
+                               $progressBar.detach();
+                               $( '.mw-changeslist-line-watched' )
+                                       .removeClass( 'mw-changeslist-line-watched' )
+                                       .addClass( 'mw-changeslist-line-not-watched' );
+                       } ).fail( function () {
+                               // On error, fall back to server-side reset
+                               // First remove this submit listener and then re-submit the form
+                               $resetForm.off( 'submit' ).submit();
+                       } );
+               } );
+
+               // if the user wishes to reload the watchlist whenever a filter changes
+               if ( mw.user.options.get( 'watchlistreloadautomatically' ) ) {
+                       // add a listener on all form elements in the header form
+                       $( '#mw-watchlist-form input, #mw-watchlist-form select' ).on( 'change', function () {
+                               // submit the form when one of the input fields is modified
+                               $( '#mw-watchlist-form' ).submit();
+                       } );
+               }
+
+               if ( mw.user.options.get( 'watchlistunwatchlinks' ) ) {
+                       // Watch/unwatch toggle link:
+                       // If a page is on the watchlist, a '×' is shown which, when clicked, removes the page from the watchlist.
+                       // After unwatching a page, the '×' becomes a '+', which if clicked re-watches the page.
+                       // Unwatched page entries are struck through and have lowered opacity.
+                       $( '.mw-changeslist' ).on( 'click', '.mw-unwatch-link, .mw-watch-link', function ( event ) {
+                               var $unwatchLink = $( this ), // EnhancedChangesList uses <table> for each row, while OldChangesList uses <li> for each row
+                                       $watchlistLine = $unwatchLink.closest( 'li, table' )
+                                               .find( '[data-target-page]' ),
+                                       pageTitle = $watchlistLine.data( 'targetPage' ),
+                                       isTalk = mw.Title.newFromText( pageTitle ).getNamespaceId() % 2 === 1;
+
+                               // Utility function for looping through each watchlist line that matches
+                               // a certain page or its associated page (e.g. Talk)
+                               function forEachMatchingTitle( title, callback ) {
+
+                                       var titleObj = mw.Title.newFromText( title ),
+                                               pageNamespaceId = titleObj.getNamespaceId(),
+                                               isTalk = pageNamespaceId % 2 === 1,
+                                               associatedTitle = mw.Title.makeTitle( isTalk ? pageNamespaceId - 1 : pageNamespaceId + 1,
+                                                       titleObj.getMainText() ).getPrefixedText();
+                                       $( '.mw-changeslist-line' ).each( function () {
+                                               var $this = $( this ), $row, $unwatchLink;
+
+                                               $this.find( '[data-target-page]' ).each( function () {
+                                                       var $this = $( this ), rowTitle = $this.data( 'targetPage' );
+                                                       if ( rowTitle === title || rowTitle === associatedTitle ) {
+
+                                                               // EnhancedChangesList groups log entries by performer rather than target page. Therefore...
+                                                               // * If using OldChangesList, use the <li>
+                                                               // * If using EnhancedChangesList and $this is part of a grouped log entry, use the <td> sub-entry
+                                                               // * If using EnhancedChangesList and $this is not part of a grouped log entry, use the <table> grouped entry
+                                                               $row =
+                                                                       $this.closest(
+                                                                               'li, table.mw-collapsible.mw-changeslist-log td[data-target-page], table' );
+                                                               $unwatchLink = $row.find( '.mw-unwatch-link, .mw-watch-link' );
+
+                                                               callback( rowTitle, $row, $unwatchLink );
+                                                       }
+                                               } );
+                                       } );
+                               }
+
+                               // Preload the notification module for mw.notify
+                               mw.loader.load( 'mediawiki.notification' );
+
+                               // Depending on whether we are watching or unwatching, for each entry of the page (and its associated page i.e. Talk),
+                               // change the text, tooltip, and non-JS href of the (un)watch button, and update the styling of the watchlist entry.
+                               if ( $unwatchLink.hasClass( 'mw-unwatch-link' ) ) {
+                                       api.unwatch( pageTitle )
+                                               .done( function () {
+                                                       forEachMatchingTitle( pageTitle,
+                                                               function ( rowPageTitle, $row, $rowUnwatchLink ) {
+                                                                       $rowUnwatchLink
+                                                                               .text( mw.msg( 'watchlist-unwatch-undo' ) )
+                                                                               .attr( 'title', mw.msg( 'tooltip-ca-watch' ) )
+                                                                               .attr( 'href',
+                                                                                       mw.util.getUrl( rowPageTitle, { action: 'watch' } ) )
+                                                                               .removeClass( 'mw-unwatch-link loading' )
+                                                                               .addClass( 'mw-watch-link' );
+                                                                       $row.find(
+                                                                               '.mw-changeslist-line-inner, .mw-enhanced-rc-nested' )
+                                                                               .addBack( '.mw-enhanced-rc-nested' ) // For matching log sub-entry
+                                                                               .addClass( 'mw-changelist-line-inner-unwatched' );
+                                                               } );
+
+                                                       mw.notify(
+                                                               mw.message( isTalk ? 'removedwatchtext-talk' : 'removedwatchtext',
+                                                                       pageTitle ), { tag: 'watch-self' } );
+                                               } );
+                               } else {
+                                       api.watch( pageTitle )
+                                               .then( function () {
+                                                       forEachMatchingTitle( pageTitle,
+                                                               function ( rowPageTitle, $row, $rowUnwatchLink ) {
+                                                                       $rowUnwatchLink
+                                                                               .text( mw.msg( 'watchlist-unwatch' ) )
+                                                                               .attr( 'title', mw.msg( 'tooltip-ca-unwatch' ) )
+                                                                               .attr( 'href',
+                                                                                       mw.util.getUrl( rowPageTitle, { action: 'unwatch' } ) )
+                                                                               .removeClass( 'mw-watch-link loading' )
+                                                                               .addClass( 'mw-unwatch-link' );
+                                                                       $row.find( '.mw-changelist-line-inner-unwatched' )
+                                                                               .addBack( '.mw-enhanced-rc-nested' )
+                                                                               .removeClass( 'mw-changelist-line-inner-unwatched' );
+                                                               } );
+
+                                                       mw.notify(
+                                                               mw.message( isTalk ? 'addedwatchtext-talk' : 'addedwatchtext',
+                                                                       pageTitle ), { tag: 'watch-self' } );
+                                               } );
+                               }
+
+                               event.preventDefault();
+                               event.stopPropagation();
+                               $unwatchLink.blur();
+                       } );
+               }
+       } );
+
+}( mediaWiki, jQuery, OO )
+);
diff --git a/resources/src/mediawiki.special/apisandbox.css b/resources/src/mediawiki.special/apisandbox.css
new file mode 100644 (file)
index 0000000..4dc4c27
--- /dev/null
@@ -0,0 +1,3 @@
+.client-js .mw-apisandbox-nojs {
+       display: none;
+}
diff --git a/resources/src/mediawiki.special/comparepages.less b/resources/src/mediawiki.special/comparepages.less
new file mode 100644 (file)
index 0000000..87b7a8b
--- /dev/null
@@ -0,0 +1,19 @@
+@import 'mediawiki.mixins';
+
+.mw-special-ComparePages .mw-htmlform-ooui-wrapper {
+       width: 100%;
+}
+
+.mw-special-ComparePages .oo-ui-layout.oo-ui-panelLayout.oo-ui-panelLayout-padded.oo-ui-panelLayout-framed {
+       float: left;
+       width: 49%;
+       .box-sizing( border-box );
+}
+
+.mw-special-ComparePages .oo-ui-layout.oo-ui-panelLayout.oo-ui-panelLayout-padded.oo-ui-panelLayout-framed:nth-of-type( 2 ) {
+       margin-left: 2%;
+}
+
+.mw-special-ComparePages .mw-htmlform-submit-buttons {
+       clear: both;
+}
diff --git a/resources/src/mediawiki.special/edittags.css b/resources/src/mediawiki.special/edittags.css
new file mode 100644 (file)
index 0000000..204009c
--- /dev/null
@@ -0,0 +1,15 @@
+/*!
+ * Styling for Special:EditTags and action=editchangetags
+ */
+#mw-edittags-tags-selector td {
+       vertical-align: top;
+}
+
+#mw-edittags-tags-selector-multi td {
+       vertical-align: top;
+       padding-right: 1.5em;
+}
+
+#mw-edittags-tag-list {
+       min-width: 20em;
+}
diff --git a/resources/src/mediawiki.special/images/glyph-people-large.png b/resources/src/mediawiki.special/images/glyph-people-large.png
deleted file mode 100644 (file)
index cba3caf..0000000
Binary files a/resources/src/mediawiki.special/images/glyph-people-large.png and /dev/null differ
diff --git a/resources/src/mediawiki.special/images/icon-contributors.png b/resources/src/mediawiki.special/images/icon-contributors.png
deleted file mode 100644 (file)
index 30bf53a..0000000
Binary files a/resources/src/mediawiki.special/images/icon-contributors.png and /dev/null differ
diff --git a/resources/src/mediawiki.special/images/icon-edits.png b/resources/src/mediawiki.special/images/icon-edits.png
deleted file mode 100644 (file)
index 17508f9..0000000
Binary files a/resources/src/mediawiki.special/images/icon-edits.png and /dev/null differ
diff --git a/resources/src/mediawiki.special/images/icon-lock.png b/resources/src/mediawiki.special/images/icon-lock.png
deleted file mode 100644 (file)
index 03f0eec..0000000
Binary files a/resources/src/mediawiki.special/images/icon-lock.png and /dev/null differ
diff --git a/resources/src/mediawiki.special/images/icon-pages.png b/resources/src/mediawiki.special/images/icon-pages.png
deleted file mode 100644 (file)
index 8e37278..0000000
Binary files a/resources/src/mediawiki.special/images/icon-pages.png and /dev/null differ
diff --git a/resources/src/mediawiki.special/mediawiki.special.apisandbox.css b/resources/src/mediawiki.special/mediawiki.special.apisandbox.css
deleted file mode 100644 (file)
index fe5ac41..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-.mw-apisandbox-toolbar {
-       background: #fff;
-       -webkit-position: sticky;
-       position: sticky;
-       top: 0;
-       margin-bottom: -1px;
-       padding: 0.5em 0;
-       border-bottom: 1px solid #a2a9b1;
-       text-align: right;
-       z-index: 1;
-}
-
-#mw-apisandbox-ui .mw-apisandbox-link {
-       display: none;
-}
-
-.mw-apisandbox-popup .oo-ui-popupWidget-body > .oo-ui-widget {
-       vertical-align: middle;
-}
-
-/* So DateTimeInputWidget's calendar popup works... */
-.mw-apisandbox-popup .oo-ui-popupWidget-popup,
-.mw-apisandbox-popup .oo-ui-popupWidget-body {
-       overflow: visible;
-}
-
-/* Display contents of the popup on a single line */
-.mw-apisandbox-popup > .oo-ui-popupWidget-popup > .oo-ui-popupWidget-body {
-       display: table;
-}
-
-.mw-apisandbox-popup > .oo-ui-popupWidget-popup > .oo-ui-popupWidget-body > * {
-       display: table-cell;
-}
-
-.mw-apisandbox-popup > .oo-ui-popupWidget-popup > .oo-ui-popupWidget-body > .oo-ui-buttonWidget {
-       padding-left: 0.5em;
-       width: 1%;
-}
-
-.mw-apisandbox-spacer {
-       display: inline-block;
-       height: 1px;
-       width: 5em;
-}
-
-.mw-apisandbox-help-field {
-       border-bottom: 1px solid rgba( 0, 0, 0, 0.1 );
-}
-
-.mw-apisandbox-help-field:last-child {
-       border-bottom: 0;
-}
-
-.mw-apisandbox-optionalWidget {
-       width: 100%;
-}
-
-.mw-apisandbox-optionalWidget.oo-ui-widget-disabled {
-       position: relative;
-       z-index: 0; /* New stacking context to prevent the cover from leaking out */
-}
-
-.mw-apisandbox-optionalWidget-cover {
-       position: absolute;
-       left: 0;
-       right: 0;
-       top: 0;
-       bottom: 0;
-       z-index: 2;
-       cursor: pointer;
-}
-
-.mw-apisandbox-optionalWidget-fields {
-       display: table;
-       width: 100%;
-}
-
-.mw-apisandbox-optionalWidget-widget,
-.mw-apisandbox-optionalWidget-checkbox {
-       display: table-cell;
-       vertical-align: middle;
-}
-
-.mw-apisandbox-optionalWidget-checkbox {
-       width: 1%; /* Will be expanded by content */
-       white-space: nowrap;
-       padding-left: 0.5em;
-}
-
-.mw-apisandbox-textInputCode .oo-ui-inputWidget-input {
-       font-family: monospace, monospace;
-       font-size: 0.8125em;
-       -moz-tab-size: 4;
-       tab-size: 4;
-}
-
-.mw-apisandbox-widget-field .oo-ui-textInputWidget {
-       /* Leave at least enough space for icon, indicator, and a sliver of text */
-       min-width: 6em;
-}
-
-.apihelp-deprecated {
-       font-weight: bold;
-       color: #d33;
-}
-
-.apihelp-deprecated-value .oo-ui-labelElement-label {
-       text-decoration: line-through;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.apisandbox.js b/resources/src/mediawiki.special/mediawiki.special.apisandbox.js
deleted file mode 100644 (file)
index 523a62e..0000000
+++ /dev/null
@@ -1,1864 +0,0 @@
-( function ( $, mw, OO ) {
-       'use strict';
-       var ApiSandbox, Util, WidgetMethods, Validators,
-               $content, panel, booklet, oldhash, windowManager,
-               formatDropdown,
-               api = new mw.Api(),
-               bookletPages = [],
-               availableFormats = {},
-               resultPage = null,
-               suppressErrors = true,
-               updatingBooklet = false,
-               pages = {},
-               moduleInfoCache = {},
-               baseRequestParams;
-
-       /**
-        * A wrapper for a widget that provides an enable/disable button
-        *
-        * @class
-        * @private
-        * @constructor
-        * @param {OO.ui.Widget} widget
-        * @param {Object} [config] Configuration options
-        */
-       function OptionalWidget( widget, config ) {
-               var k;
-
-               config = config || {};
-
-               this.widget = widget;
-               this.$cover = config.$cover ||
-                       $( '<div>' ).addClass( 'mw-apisandbox-optionalWidget-cover' );
-               this.checkbox = new OO.ui.CheckboxInputWidget( config.checkbox )
-                       .on( 'change', this.onCheckboxChange, [], this );
-
-               OptionalWidget[ 'super' ].call( this, config );
-
-               // Forward most methods for convenience
-               for ( k in this.widget ) {
-                       if ( $.isFunction( this.widget[ k ] ) && !this[ k ] ) {
-                               this[ k ] = this.widget[ k ].bind( this.widget );
-                       }
-               }
-
-               this.$cover.on( 'click', this.onOverlayClick.bind( this ) );
-
-               this.$element
-                       .addClass( 'mw-apisandbox-optionalWidget' )
-                       .append(
-                               this.$cover,
-                               $( '<div>' ).addClass( 'mw-apisandbox-optionalWidget-fields' ).append(
-                                       $( '<div>' ).addClass( 'mw-apisandbox-optionalWidget-widget' ).append(
-                                               widget.$element
-                                       ),
-                                       $( '<div>' ).addClass( 'mw-apisandbox-optionalWidget-checkbox' ).append(
-                                               this.checkbox.$element
-                                       )
-                               )
-                       );
-
-               this.setDisabled( widget.isDisabled() );
-       }
-       OO.inheritClass( OptionalWidget, OO.ui.Widget );
-       OptionalWidget.prototype.onCheckboxChange = function ( checked ) {
-               this.setDisabled( !checked );
-       };
-       OptionalWidget.prototype.onOverlayClick = function () {
-               this.setDisabled( false );
-               if ( $.isFunction( this.widget.focus ) ) {
-                       this.widget.focus();
-               }
-       };
-       OptionalWidget.prototype.setDisabled = function ( disabled ) {
-               OptionalWidget[ 'super' ].prototype.setDisabled.call( this, disabled );
-               this.widget.setDisabled( this.isDisabled() );
-               this.checkbox.setSelected( !this.isDisabled() );
-               this.$cover.toggle( this.isDisabled() );
-               return this;
-       };
-
-       WidgetMethods = {
-               textInputWidget: {
-                       getApiValue: function () {
-                               return this.getValue();
-                       },
-                       setApiValue: function ( v ) {
-                               if ( v === undefined ) {
-                                       v = this.paramInfo[ 'default' ];
-                               }
-                               this.setValue( v );
-                       },
-                       apiCheckValid: function () {
-                               var that = this;
-                               return this.getValidity().then( function () {
-                                       return $.Deferred().resolve( true ).promise();
-                               }, function () {
-                                       return $.Deferred().resolve( false ).promise();
-                               } ).done( function ( ok ) {
-                                       ok = ok || suppressErrors;
-                                       that.setIcon( ok ? null : 'alert' );
-                                       that.setIconTitle( ok ? '' : mw.message( 'apisandbox-alert-field' ).plain() );
-                               } );
-                       }
-               },
-
-               dateTimeInputWidget: {
-                       getValidity: function () {
-                               if ( !Util.apiBool( this.paramInfo.required ) || this.getApiValue() !== '' ) {
-                                       return $.Deferred().resolve().promise();
-                               } else {
-                                       return $.Deferred().reject().promise();
-                               }
-                       }
-               },
-
-               tokenWidget: {
-                       alertTokenError: function ( code, error ) {
-                               windowManager.openWindow( 'errorAlert', {
-                                       title: Util.parseMsg( 'apisandbox-results-fixtoken-fail', this.paramInfo.tokentype ),
-                                       message: error,
-                                       actions: [
-                                               {
-                                                       action: 'accept',
-                                                       label: OO.ui.msg( 'ooui-dialog-process-dismiss' ),
-                                                       flags: 'primary'
-                                               }
-                                       ]
-                               } );
-                       },
-                       fetchToken: function () {
-                               this.pushPending();
-                               return api.getToken( this.paramInfo.tokentype )
-                                       .done( this.setApiValue.bind( this ) )
-                                       .fail( this.alertTokenError.bind( this ) )
-                                       .always( this.popPending.bind( this ) );
-                       },
-                       setApiValue: function ( v ) {
-                               WidgetMethods.textInputWidget.setApiValue.call( this, v );
-                               if ( v === '123ABC' ) {
-                                       this.fetchToken();
-                               }
-                       }
-               },
-
-               passwordWidget: {
-                       getApiValueForDisplay: function () {
-                               return '';
-                       }
-               },
-
-               toggleSwitchWidget: {
-                       getApiValue: function () {
-                               return this.getValue() ? 1 : undefined;
-                       },
-                       setApiValue: function ( v ) {
-                               this.setValue( Util.apiBool( v ) );
-                       },
-                       apiCheckValid: function () {
-                               return $.Deferred().resolve( true ).promise();
-                       }
-               },
-
-               dropdownWidget: {
-                       getApiValue: function () {
-                               var item = this.getMenu().findSelectedItem();
-                               return item === null ? undefined : item.getData();
-                       },
-                       setApiValue: function ( v ) {
-                               var menu = this.getMenu();
-
-                               if ( v === undefined ) {
-                                       v = this.paramInfo[ 'default' ];
-                               }
-                               if ( v === undefined ) {
-                                       menu.selectItem();
-                               } else {
-                                       menu.selectItemByData( String( v ) );
-                               }
-                       },
-                       apiCheckValid: function () {
-                               var ok = this.getApiValue() !== undefined || suppressErrors;
-                               this.setIcon( ok ? null : 'alert' );
-                               this.setIconTitle( ok ? '' : mw.message( 'apisandbox-alert-field' ).plain() );
-                               return $.Deferred().resolve( ok ).promise();
-                       }
-               },
-
-               tagWidget: {
-                       getApiValue: function () {
-                               var items = this.getValue();
-                               if ( items.join( '' ).indexOf( '|' ) === -1 ) {
-                                       return items.join( '|' );
-                               } else {
-                                       return '\x1f' + items.join( '\x1f' );
-                               }
-                       },
-                       setApiValue: function ( v ) {
-                               if ( v === undefined || v === '' || v === '\x1f' ) {
-                                       this.setValue( [] );
-                               } else {
-                                       v = String( v );
-                                       if ( v.indexOf( '\x1f' ) !== 0 ) {
-                                               this.setValue( v.split( '|' ) );
-                                       } else {
-                                               this.setValue( v.substr( 1 ).split( '\x1f' ) );
-                                       }
-                               }
-                       },
-                       apiCheckValid: function () {
-                               var ok = true,
-                                       pi = this.paramInfo;
-
-                               if ( !suppressErrors ) {
-                                       ok = this.getApiValue() !== undefined && !(
-                                               pi.allspecifier !== undefined &&
-                                               this.getValue().length > 1 &&
-                                               this.getValue().indexOf( pi.allspecifier ) !== -1
-                                       );
-                               }
-
-                               this.setIcon( ok ? null : 'alert' );
-                               this.setIconTitle( ok ? '' : mw.message( 'apisandbox-alert-field' ).plain() );
-                               return $.Deferred().resolve( ok ).promise();
-                       },
-                       createTagItemWidget: function ( data, label ) {
-                               var item = OO.ui.TagMultiselectWidget.prototype.createTagItemWidget.call( this, data, label );
-                               if ( this.paramInfo.deprecatedvalues &&
-                                       this.paramInfo.deprecatedvalues.indexOf( data ) >= 0
-                               ) {
-                                       item.$element.addClass( 'apihelp-deprecated-value' );
-                               }
-                               return item;
-                       }
-               },
-
-               optionalWidget: {
-                       getApiValue: function () {
-                               return this.isDisabled() ? undefined : this.widget.getApiValue();
-                       },
-                       setApiValue: function ( v ) {
-                               this.setDisabled( v === undefined );
-                               this.widget.setApiValue( v );
-                       },
-                       apiCheckValid: function () {
-                               if ( this.isDisabled() ) {
-                                       return $.Deferred().resolve( true ).promise();
-                               } else {
-                                       return this.widget.apiCheckValid();
-                               }
-                       }
-               },
-
-               submoduleWidget: {
-                       single: function () {
-                               var v = this.isDisabled() ? this.paramInfo[ 'default' ] : this.getApiValue();
-                               return v === undefined ? [] : [ { value: v, path: this.paramInfo.submodules[ v ] } ];
-                       },
-                       multi: function () {
-                               var map = this.paramInfo.submodules,
-                                       v = this.isDisabled() ? this.paramInfo[ 'default' ] : this.getApiValue();
-                               return v === undefined || v === '' ? [] : String( v ).split( '|' ).map( function ( v ) {
-                                       return { value: v, path: map[ v ] };
-                               } );
-                       }
-               },
-
-               uploadWidget: {
-                       getApiValueForDisplay: function () {
-                               return '...';
-                       },
-                       getApiValue: function () {
-                               return this.getValue();
-                       },
-                       setApiValue: function () {
-                               // Can't, sorry.
-                       },
-                       apiCheckValid: function () {
-                               var ok = this.getValue() !== null || suppressErrors;
-                               this.setIcon( ok ? null : 'alert' );
-                               this.setIconTitle( ok ? '' : mw.message( 'apisandbox-alert-field' ).plain() );
-                               return $.Deferred().resolve( ok ).promise();
-                       }
-               }
-       };
-
-       Validators = {
-               generic: function () {
-                       return !Util.apiBool( this.paramInfo.required ) || this.getApiValue() !== '';
-               }
-       };
-
-       /**
-        * @class mw.special.ApiSandbox.Util
-        * @private
-        */
-       Util = {
-               /**
-                * Fetch API module info
-                *
-                * @param {string} module Module to fetch data for
-                * @return {jQuery.Promise}
-                */
-               fetchModuleInfo: function ( module ) {
-                       var apiPromise,
-                               deferred = $.Deferred();
-
-                       if ( moduleInfoCache.hasOwnProperty( module ) ) {
-                               return deferred
-                                       .resolve( moduleInfoCache[ module ] )
-                                       .promise( { abort: function () {} } );
-                       } else {
-                               apiPromise = api.post( {
-                                       action: 'paraminfo',
-                                       modules: module,
-                                       helpformat: 'html',
-                                       uselang: mw.config.get( 'wgUserLanguage' )
-                               } ).done( function ( data ) {
-                                       var info;
-
-                                       if ( data.warnings && data.warnings.paraminfo ) {
-                                               deferred.reject( '???', data.warnings.paraminfo[ '*' ] );
-                                               return;
-                                       }
-
-                                       info = data.paraminfo.modules;
-                                       if ( !info || info.length !== 1 || info[ 0 ].path !== module ) {
-                                               deferred.reject( '???', 'No module data returned' );
-                                               return;
-                                       }
-
-                                       moduleInfoCache[ module ] = info[ 0 ];
-                                       deferred.resolve( info[ 0 ] );
-                               } ).fail( function ( code, details ) {
-                                       if ( code === 'http' ) {
-                                               details = 'HTTP error: ' + details.exception;
-                                       } else if ( details.error ) {
-                                               details = details.error.info;
-                                       }
-                                       deferred.reject( code, details );
-                               } );
-                               return deferred
-                                       .promise( { abort: apiPromise.abort } );
-                       }
-               },
-
-               /**
-                * Mark all currently-in-use tokens as bad
-                */
-               markTokensBad: function () {
-                       var page, subpages, i,
-                               checkPages = [ pages.main ];
-
-                       while ( checkPages.length ) {
-                               page = checkPages.shift();
-
-                               if ( page.tokenWidget ) {
-                                       api.badToken( page.tokenWidget.paramInfo.tokentype );
-                               }
-
-                               subpages = page.getSubpages();
-                               for ( i = 0; i < subpages.length; i++ ) {
-                                       if ( pages.hasOwnProperty( subpages[ i ].key ) ) {
-                                               checkPages.push( pages[ subpages[ i ].key ] );
-                                       }
-                               }
-                       }
-               },
-
-               /**
-                * Test an API boolean
-                *
-                * @param {Mixed} value
-                * @return {boolean}
-                */
-               apiBool: function ( value ) {
-                       return value !== undefined && value !== false;
-               },
-
-               /**
-                * Create a widget for a parameter.
-                *
-                * @param {Object} pi Parameter info from API
-                * @param {Object} opts Additional options
-                * @return {OO.ui.Widget}
-                */
-               createWidgetForParameter: function ( pi, opts ) {
-                       var widget, innerWidget, finalWidget, items, $content, func,
-                               multiModeButton = null,
-                               multiModeInput = null,
-                               multiModeAllowed = false;
-
-                       opts = opts || {};
-
-                       switch ( pi.type ) {
-                               case 'boolean':
-                                       widget = new OO.ui.ToggleSwitchWidget();
-                                       widget.paramInfo = pi;
-                                       $.extend( widget, WidgetMethods.toggleSwitchWidget );
-                                       pi.required = true; // Avoid wrapping in the non-required widget
-                                       break;
-
-                               case 'string':
-                               case 'user':
-                                       if ( Util.apiBool( pi.multi ) ) {
-                                               widget = new OO.ui.TagMultiselectWidget( {
-                                                       allowArbitrary: true,
-                                                       allowDuplicates: Util.apiBool( pi.allowsduplicates ),
-                                                       $overlay: true
-                                               } );
-                                               widget.paramInfo = pi;
-                                               $.extend( widget, WidgetMethods.tagWidget );
-                                       } else {
-                                               widget = new OO.ui.TextInputWidget( {
-                                                       required: Util.apiBool( pi.required )
-                                               } );
-                                       }
-                                       if ( !Util.apiBool( pi.multi ) ) {
-                                               widget.paramInfo = pi;
-                                               $.extend( widget, WidgetMethods.textInputWidget );
-                                               widget.setValidation( Validators.generic );
-                                       }
-                                       if ( pi.tokentype ) {
-                                               widget.paramInfo = pi;
-                                               $.extend( widget, WidgetMethods.textInputWidget );
-                                               $.extend( widget, WidgetMethods.tokenWidget );
-                                       }
-                                       break;
-
-                               case 'text':
-                                       widget = new OO.ui.MultilineTextInputWidget( {
-                                               required: Util.apiBool( pi.required )
-                                       } );
-                                       widget.paramInfo = pi;
-                                       $.extend( widget, WidgetMethods.textInputWidget );
-                                       widget.setValidation( Validators.generic );
-                                       break;
-
-                               case 'password':
-                                       widget = new OO.ui.TextInputWidget( {
-                                               type: 'password',
-                                               required: Util.apiBool( pi.required )
-                                       } );
-                                       widget.paramInfo = pi;
-                                       $.extend( widget, WidgetMethods.textInputWidget );
-                                       $.extend( widget, WidgetMethods.passwordWidget );
-                                       widget.setValidation( Validators.generic );
-                                       multiModeAllowed = true;
-                                       multiModeInput = widget;
-                                       break;
-
-                               case 'integer':
-                                       widget = new OO.ui.NumberInputWidget( {
-                                               required: Util.apiBool( pi.required ),
-                                               isInteger: true
-                                       } );
-                                       widget.setIcon = widget.input.setIcon.bind( widget.input );
-                                       widget.setIconTitle = widget.input.setIconTitle.bind( widget.input );
-                                       widget.getValidity = widget.input.getValidity.bind( widget.input );
-                                       widget.paramInfo = pi;
-                                       $.extend( widget, WidgetMethods.textInputWidget );
-                                       if ( Util.apiBool( pi.enforcerange ) ) {
-                                               widget.setRange( pi.min || -Infinity, pi.max || Infinity );
-                                       }
-                                       multiModeAllowed = true;
-                                       multiModeInput = widget;
-                                       break;
-
-                               case 'limit':
-                                       widget = new OO.ui.TextInputWidget( {
-                                               required: Util.apiBool( pi.required )
-                                       } );
-                                       widget.setValidation( function ( value ) {
-                                               var n, pi = this.paramInfo;
-
-                                               if ( value === 'max' ) {
-                                                       return true;
-                                               } else {
-                                                       n = +value;
-                                                       return !isNaN( n ) && isFinite( n ) &&
-                                                               Math.floor( n ) === n &&
-                                                               n >= pi.min && n <= pi.apiSandboxMax;
-                                               }
-                                       } );
-                                       pi.min = pi.min || 0;
-                                       pi.apiSandboxMax = mw.config.get( 'apihighlimits' ) ? pi.highmax : pi.max;
-                                       widget.paramInfo = pi;
-                                       $.extend( widget, WidgetMethods.textInputWidget );
-                                       multiModeAllowed = true;
-                                       multiModeInput = widget;
-                                       break;
-
-                               case 'timestamp':
-                                       widget = new mw.widgets.datetime.DateTimeInputWidget( {
-                                               formatter: {
-                                                       format: '${year|0}-${month|0}-${day|0}T${hour|0}:${minute|0}:${second|0}${zone|short}'
-                                               },
-                                               required: Util.apiBool( pi.required ),
-                                               clearable: false
-                                       } );
-                                       widget.paramInfo = pi;
-                                       $.extend( widget, WidgetMethods.textInputWidget );
-                                       $.extend( widget, WidgetMethods.dateTimeInputWidget );
-                                       multiModeAllowed = true;
-                                       break;
-
-                               case 'upload':
-                                       widget = new OO.ui.SelectFileWidget();
-                                       widget.paramInfo = pi;
-                                       $.extend( widget, WidgetMethods.uploadWidget );
-                                       break;
-
-                               case 'namespace':
-                                       items = $.map( mw.config.get( 'wgFormattedNamespaces' ), function ( name, ns ) {
-                                               if ( ns === '0' ) {
-                                                       name = mw.message( 'blanknamespace' ).text();
-                                               }
-                                               return new OO.ui.MenuOptionWidget( { data: ns, label: name } );
-                                       } ).sort( function ( a, b ) {
-                                               return a.data - b.data;
-                                       } );
-                                       if ( Util.apiBool( pi.multi ) ) {
-                                               if ( pi.allspecifier !== undefined ) {
-                                                       items.unshift( new OO.ui.MenuOptionWidget( {
-                                                               data: pi.allspecifier,
-                                                               label: mw.message( 'apisandbox-multivalue-all-namespaces', pi.allspecifier ).text()
-                                                       } ) );
-                                               }
-
-                                               widget = new OO.ui.MenuTagMultiselectWidget( {
-                                                       menu: { items: items },
-                                                       $overlay: true
-                                               } );
-                                               widget.paramInfo = pi;
-                                               $.extend( widget, WidgetMethods.tagWidget );
-                                       } else {
-                                               widget = new OO.ui.DropdownWidget( {
-                                                       menu: { items: items },
-                                                       $overlay: true
-                                               } );
-                                               widget.paramInfo = pi;
-                                               $.extend( widget, WidgetMethods.dropdownWidget );
-                                       }
-                                       break;
-
-                               default:
-                                       if ( !Array.isArray( pi.type ) ) {
-                                               throw new Error( 'Unknown parameter type ' + pi.type );
-                                       }
-
-                                       items = pi.type.map( function ( v ) {
-                                               var config = {
-                                                       data: String( v ),
-                                                       label: String( v ),
-                                                       classes: []
-                                               };
-                                               if ( pi.deprecatedvalues && pi.deprecatedvalues.indexOf( v ) >= 0 ) {
-                                                       config.classes.push( 'apihelp-deprecated-value' );
-                                               }
-                                               return new OO.ui.MenuOptionWidget( config );
-                                       } );
-                                       if ( Util.apiBool( pi.multi ) ) {
-                                               if ( pi.allspecifier !== undefined ) {
-                                                       items.unshift( new OO.ui.MenuOptionWidget( {
-                                                               data: pi.allspecifier,
-                                                               label: mw.message( 'apisandbox-multivalue-all-values', pi.allspecifier ).text()
-                                                       } ) );
-                                               }
-
-                                               widget = new OO.ui.MenuTagMultiselectWidget( {
-                                                       menu: { items: items },
-                                                       $overlay: true
-                                               } );
-                                               widget.paramInfo = pi;
-                                               $.extend( widget, WidgetMethods.tagWidget );
-                                               if ( Util.apiBool( pi.submodules ) ) {
-                                                       widget.getSubmodules = WidgetMethods.submoduleWidget.multi;
-                                                       widget.on( 'change', ApiSandbox.updateUI );
-                                               }
-                                       } else {
-                                               widget = new OO.ui.DropdownWidget( {
-                                                       menu: { items: items },
-                                                       $overlay: true
-                                               } );
-                                               widget.paramInfo = pi;
-                                               $.extend( widget, WidgetMethods.dropdownWidget );
-                                               if ( Util.apiBool( pi.submodules ) ) {
-                                                       widget.getSubmodules = WidgetMethods.submoduleWidget.single;
-                                                       widget.getMenu().on( 'select', ApiSandbox.updateUI );
-                                               }
-                                               if ( pi.deprecatedvalues ) {
-                                                       widget.getMenu().on( 'select', function ( item ) {
-                                                               this.$element.toggleClass(
-                                                                       'apihelp-deprecated-value',
-                                                                       pi.deprecatedvalues.indexOf( item.data ) >= 0
-                                                               );
-                                                       }, [], widget );
-                                               }
-                                       }
-
-                                       break;
-                       }
-
-                       if ( Util.apiBool( pi.multi ) && multiModeAllowed ) {
-                               innerWidget = widget;
-
-                               multiModeButton = new OO.ui.ButtonWidget( {
-                                       label: mw.message( 'apisandbox-add-multi' ).text()
-                               } );
-                               $content = innerWidget.$element.add( multiModeButton.$element );
-
-                               widget = new OO.ui.PopupTagMultiselectWidget( {
-                                       allowArbitrary: true,
-                                       allowDuplicates: Util.apiBool( pi.allowsduplicates ),
-                                       $overlay: true,
-                                       popup: {
-                                               classes: [ 'mw-apisandbox-popup' ],
-                                               padded: true,
-                                               $content: $content
-                                       }
-                               } );
-                               widget.paramInfo = pi;
-                               $.extend( widget, WidgetMethods.tagWidget );
-
-                               func = function () {
-                                       if ( !innerWidget.isDisabled() ) {
-                                               innerWidget.apiCheckValid().done( function ( ok ) {
-                                                       if ( ok ) {
-                                                               widget.addTag( innerWidget.getApiValue() );
-                                                               innerWidget.setApiValue( undefined );
-                                                       }
-                                               } );
-                                               return false;
-                                       }
-                               };
-
-                               if ( multiModeInput ) {
-                                       multiModeInput.on( 'enter', func );
-                               }
-                               multiModeButton.on( 'click', func );
-                       }
-
-                       if ( Util.apiBool( pi.required ) || opts.nooptional ) {
-                               finalWidget = widget;
-                       } else {
-                               finalWidget = new OptionalWidget( widget );
-                               finalWidget.paramInfo = pi;
-                               $.extend( finalWidget, WidgetMethods.optionalWidget );
-                               if ( widget.getSubmodules ) {
-                                       finalWidget.getSubmodules = widget.getSubmodules.bind( widget );
-                                       finalWidget.on( 'disable', function () { setTimeout( ApiSandbox.updateUI ); } );
-                               }
-                               finalWidget.setDisabled( true );
-                       }
-
-                       widget.setApiValue( pi[ 'default' ] );
-
-                       return finalWidget;
-               },
-
-               /**
-                * Parse an HTML string and call Util.fixupHTML()
-                *
-                * @param {string} html HTML to parse
-                * @return {jQuery}
-                */
-               parseHTML: function ( html ) {
-                       var $ret = $( $.parseHTML( html ) );
-                       return Util.fixupHTML( $ret );
-               },
-
-               /**
-                * Parse an i18n message and call Util.fixupHTML()
-                *
-                * @param {string} key Key of message to get
-                * @param {...Mixed} parameters Values for $N replacements
-                * @return {jQuery}
-                */
-               parseMsg: function () {
-                       var $ret = mw.message.apply( mw.message, arguments ).parseDom();
-                       return Util.fixupHTML( $ret );
-               },
-
-               /**
-                * Fix HTML for ApiSandbox display
-                *
-                * Fixes are:
-                * - Add target="_blank" to any links
-                *
-                * @param {jQuery} $html DOM to process
-                * @return {jQuery}
-                */
-               fixupHTML: function ( $html ) {
-                       $html.filter( 'a' ).add( $html.find( 'a' ) )
-                               .filter( '[href]:not([target])' )
-                               .attr( 'target', '_blank' );
-                       return $html;
-               },
-
-               /**
-                * Format a request and return a bunch of menu option widgets
-                *
-                * @param {Object} displayParams Query parameters, sanitized for display.
-                * @param {Object} rawParams Query parameters. You should probably use displayParams instead.
-                * @return {OO.ui.MenuOptionWidget[]} Each item's data should be an OO.ui.FieldLayout
-                */
-               formatRequest: function ( displayParams, rawParams ) {
-                       var jsonInput,
-                               items = [
-                                       new OO.ui.MenuOptionWidget( {
-                                               label: Util.parseMsg( 'apisandbox-request-format-url-label' ),
-                                               data: new OO.ui.FieldLayout(
-                                                       new OO.ui.TextInputWidget( {
-                                                               readOnly: true,
-                                                               value: mw.util.wikiScript( 'api' ) + '?' + $.param( displayParams )
-                                                       } ), {
-                                                               label: Util.parseMsg( 'apisandbox-request-url-label' )
-                                                       }
-                                               )
-                                       } ),
-                                       new OO.ui.MenuOptionWidget( {
-                                               label: Util.parseMsg( 'apisandbox-request-format-json-label' ),
-                                               data: new OO.ui.FieldLayout(
-                                                       jsonInput = new OO.ui.MultilineTextInputWidget( {
-                                                               classes: [ 'mw-apisandbox-textInputCode' ],
-                                                               readOnly: true,
-                                                               autosize: true,
-                                                               maxRows: 6,
-                                                               value: JSON.stringify( displayParams, null, '\t' )
-                                                       } ), {
-                                                               label: Util.parseMsg( 'apisandbox-request-json-label' )
-                                                       }
-                                               ).on( 'toggle', function ( visible ) {
-                                                       if ( visible ) {
-                                                               // Call updatePosition instead of adjustSize
-                                                               // because the latter has weird caching
-                                                               // behavior and the former bypasses it.
-                                                               jsonInput.updatePosition();
-                                                       }
-                                               } )
-                                       } )
-                               ];
-
-                       mw.hook( 'apisandbox.formatRequest' ).fire( items, displayParams, rawParams );
-
-                       return items;
-               },
-
-               /**
-                * Event handler for when formatDropdown's selection changes
-                */
-               onFormatDropdownChange: function () {
-                       var i,
-                               menu = formatDropdown.getMenu(),
-                               items = menu.getItems(),
-                               selectedField = menu.findSelectedItem() ? menu.findSelectedItem().getData() : null;
-
-                       for ( i = 0; i < items.length; i++ ) {
-                               items[ i ].getData().toggle( items[ i ].getData() === selectedField );
-                       }
-               }
-       };
-
-       /**
-       * Interface to ApiSandbox UI
-       *
-       * @class mw.special.ApiSandbox
-       */
-       ApiSandbox = {
-               /**
-                * Initialize the UI
-                *
-                * Automatically called on $.ready()
-                */
-               init: function () {
-                       var $toolbar;
-
-                       $content = $( '#mw-apisandbox' );
-
-                       windowManager = new OO.ui.WindowManager();
-                       $( 'body' ).append( windowManager.$element );
-                       windowManager.addWindows( {
-                               errorAlert: new OO.ui.MessageDialog()
-                       } );
-
-                       $toolbar = $( '<div>' )
-                               .addClass( 'mw-apisandbox-toolbar' )
-                               .append(
-                                       new OO.ui.ButtonWidget( {
-                                               label: mw.message( 'apisandbox-submit' ).text(),
-                                               flags: [ 'primary', 'progressive' ]
-                                       } ).on( 'click', ApiSandbox.sendRequest ).$element,
-                                       new OO.ui.ButtonWidget( {
-                                               label: mw.message( 'apisandbox-reset' ).text(),
-                                               flags: 'destructive'
-                                       } ).on( 'click', ApiSandbox.resetUI ).$element
-                               );
-
-                       booklet = new OO.ui.BookletLayout( {
-                               expanded: false,
-                               outlined: true,
-                               autoFocus: false
-                       } );
-
-                       panel = new OO.ui.PanelLayout( {
-                               classes: [ 'mw-apisandbox-container' ],
-                               content: [ booklet ],
-                               expanded: false,
-                               framed: true
-                       } );
-
-                       pages.main = new ApiSandbox.PageLayout( { key: 'main', path: 'main' } );
-
-                       // Parse the current hash string
-                       if ( !ApiSandbox.loadFromHash() ) {
-                               ApiSandbox.updateUI();
-                       }
-
-                       $( window ).on( 'hashchange', ApiSandbox.loadFromHash );
-
-                       $content
-                               .empty()
-                               .append( $( '<p>' ).append( Util.parseMsg( 'apisandbox-intro' ) ) )
-                               .append(
-                                       $( '<div>' ).attr( 'id', 'mw-apisandbox-ui' )
-                                               .append( $toolbar )
-                                               .append( panel.$element )
-                               );
-               },
-
-               /**
-                * Update the current query when the page hash changes
-                *
-                * @return {boolean} Successful
-                */
-               loadFromHash: function () {
-                       var params, m, re,
-                               hash = location.hash;
-
-                       if ( oldhash === hash ) {
-                               return false;
-                       }
-                       oldhash = hash;
-                       if ( hash === '' ) {
-                               return false;
-                       }
-
-                       // I'm surprised this doesn't seem to exist in jQuery or mw.util.
-                       params = {};
-                       hash = hash.replace( /\+/g, '%20' );
-                       re = /([^&=#]+)=?([^&#]*)/g;
-                       while ( ( m = re.exec( hash ) ) ) {
-                               params[ decodeURIComponent( m[ 1 ] ) ] = decodeURIComponent( m[ 2 ] );
-                       }
-
-                       ApiSandbox.updateUI( params );
-                       return true;
-               },
-
-               /**
-                * Update the pages in the booklet
-                *
-                * @param {Object} [params] Optional query parameters to load
-                */
-               updateUI: function ( params ) {
-                       var i, page, subpages, j, removePages,
-                               addPages = [];
-
-                       if ( !$.isPlainObject( params ) ) {
-                               params = undefined;
-                       }
-
-                       if ( updatingBooklet ) {
-                               return;
-                       }
-                       updatingBooklet = true;
-                       try {
-                               if ( params !== undefined ) {
-                                       pages.main.loadQueryParams( params );
-                               }
-                               addPages.push( pages.main );
-                               if ( resultPage !== null ) {
-                                       addPages.push( resultPage );
-                               }
-                               pages.main.apiCheckValid();
-
-                               i = 0;
-                               while ( addPages.length ) {
-                                       page = addPages.shift();
-                                       if ( bookletPages[ i ] !== page ) {
-                                               for ( j = i; j < bookletPages.length; j++ ) {
-                                                       if ( bookletPages[ j ].getName() === page.getName() ) {
-                                                               bookletPages.splice( j, 1 );
-                                                       }
-                                               }
-                                               bookletPages.splice( i, 0, page );
-                                               booklet.addPages( [ page ], i );
-                                       }
-                                       i++;
-
-                                       if ( page.getSubpages ) {
-                                               subpages = page.getSubpages();
-                                               for ( j = 0; j < subpages.length; j++ ) {
-                                                       if ( !pages.hasOwnProperty( subpages[ j ].key ) ) {
-                                                               subpages[ j ].indentLevel = page.indentLevel + 1;
-                                                               pages[ subpages[ j ].key ] = new ApiSandbox.PageLayout( subpages[ j ] );
-                                                       }
-                                                       if ( params !== undefined ) {
-                                                               pages[ subpages[ j ].key ].loadQueryParams( params );
-                                                       }
-                                                       addPages.splice( j, 0, pages[ subpages[ j ].key ] );
-                                                       pages[ subpages[ j ].key ].apiCheckValid();
-                                               }
-                                       }
-                               }
-
-                               if ( bookletPages.length > i ) {
-                                       removePages = bookletPages.splice( i, bookletPages.length - i );
-                                       booklet.removePages( removePages );
-                               }
-
-                               if ( !booklet.getCurrentPageName() ) {
-                                       booklet.selectFirstSelectablePage();
-                               }
-                       } finally {
-                               updatingBooklet = false;
-                       }
-               },
-
-               /**
-                * Reset button handler
-                */
-               resetUI: function () {
-                       suppressErrors = true;
-                       pages = {
-                               main: new ApiSandbox.PageLayout( { key: 'main', path: 'main' } )
-                       };
-                       resultPage = null;
-                       ApiSandbox.updateUI();
-               },
-
-               /**
-                * Submit button handler
-                *
-                * @param {Object} [params] Use this set of params instead of those in the form fields.
-                *   The form fields will be updated to match.
-                */
-               sendRequest: function ( params ) {
-                       var page, subpages, i, query, $result, $focus,
-                               progress, $progressText, progressLoading,
-                               deferreds = [],
-                               paramsAreForced = !!params,
-                               displayParams = {},
-                               tokenWidgets = [],
-                               checkPages = [ pages.main ];
-
-                       // Blur any focused widget before submit, because
-                       // OO.ui.ButtonWidget doesn't take focus itself (T128054)
-                       $focus = $( '#mw-apisandbox-ui' ).find( document.activeElement );
-                       if ( $focus.length ) {
-                               $focus[ 0 ].blur();
-                       }
-
-                       suppressErrors = false;
-
-                       // save widget state in params (or load from it if we are forced)
-                       if ( paramsAreForced ) {
-                               ApiSandbox.updateUI( params );
-                       }
-                       params = {};
-                       while ( checkPages.length ) {
-                               page = checkPages.shift();
-                               if ( page.tokenWidget ) {
-                                       tokenWidgets.push( page.tokenWidget );
-                               }
-                               deferreds = deferreds.concat( page.apiCheckValid() );
-                               page.getQueryParams( params, displayParams );
-                               subpages = page.getSubpages();
-                               for ( i = 0; i < subpages.length; i++ ) {
-                                       if ( pages.hasOwnProperty( subpages[ i ].key ) ) {
-                                               checkPages.push( pages[ subpages[ i ].key ] );
-                                       }
-                               }
-                       }
-
-                       if ( !paramsAreForced ) {
-                               // forced params means we are continuing a query; the base query should be preserved
-                               baseRequestParams = $.extend( {}, params );
-                       }
-
-                       $.when.apply( $, deferreds ).done( function () {
-                               var formatItems, menu, selectedLabel, deferred, actions, errorCount;
-
-                               // Count how many times `value` occurs in `array`.
-                               function countValues( value, array ) {
-                                       var count, i;
-                                       count = 0;
-                                       for ( i = 0; i < array.length; i++ ) {
-                                               if ( array[ i ] === value ) {
-                                                       count++;
-                                               }
-                                       }
-                                       return count;
-                               }
-
-                               errorCount = countValues( false, arguments );
-                               if ( errorCount > 0 ) {
-                                       actions = [
-                                               {
-                                                       action: 'accept',
-                                                       label: OO.ui.msg( 'ooui-dialog-process-dismiss' ),
-                                                       flags: 'primary'
-                                               }
-                                       ];
-                                       if ( tokenWidgets.length ) {
-                                               // Check all token widgets' validity separately
-                                               deferred = $.when.apply( $, tokenWidgets.map( function ( w ) {
-                                                       return w.apiCheckValid();
-                                               } ) );
-
-                                               deferred.done( function () {
-                                                       // If only the tokens are invalid, offer to fix them
-                                                       var tokenErrorCount = countValues( false, arguments );
-                                                       if ( tokenErrorCount === errorCount ) {
-                                                               delete actions[ 0 ].flags;
-                                                               actions.push( {
-                                                                       action: 'fix',
-                                                                       label: mw.message( 'apisandbox-results-fixtoken' ).text(),
-                                                                       flags: 'primary'
-                                                               } );
-                                                       }
-                                               } );
-                                       } else {
-                                               deferred = $.Deferred().resolve();
-                                       }
-                                       deferred.always( function () {
-                                               windowManager.openWindow( 'errorAlert', {
-                                                       title: Util.parseMsg( 'apisandbox-submit-invalid-fields-title' ),
-                                                       message: Util.parseMsg( 'apisandbox-submit-invalid-fields-message' ),
-                                                       actions: actions
-                                               } ).closed.then( function ( data ) {
-                                                       if ( data && data.action === 'fix' ) {
-                                                               ApiSandbox.fixTokenAndResend();
-                                                       }
-                                               } );
-                                       } );
-                                       return;
-                               }
-
-                               query = $.param( displayParams );
-
-                               formatItems = Util.formatRequest( displayParams, params );
-
-                               // Force a 'fm' format with wrappedhtml=1, if available
-                               if ( params.format !== undefined ) {
-                                       if ( availableFormats.hasOwnProperty( params.format + 'fm' ) ) {
-                                               params.format = params.format + 'fm';
-                                       }
-                                       if ( params.format.substr( -2 ) === 'fm' ) {
-                                               params.wrappedhtml = 1;
-                                       }
-                               }
-
-                               progressLoading = false;
-                               $progressText = $( '<span>' ).text( mw.message( 'apisandbox-sending-request' ).text() );
-                               progress = new OO.ui.ProgressBarWidget( {
-                                       progress: false,
-                                       $content: $progressText
-                               } );
-
-                               $result = $( '<div>' )
-                                       .append( progress.$element );
-
-                               resultPage = page = new OO.ui.PageLayout( '|results|', { expanded: false } );
-                               page.setupOutlineItem = function () {
-                                       this.outlineItem.setLabel( mw.message( 'apisandbox-results' ).text() );
-                               };
-
-                               if ( !formatDropdown ) {
-                                       formatDropdown = new OO.ui.DropdownWidget( {
-                                               menu: { items: [] },
-                                               $overlay: true
-                                       } );
-                                       formatDropdown.getMenu().on( 'select', Util.onFormatDropdownChange );
-                               }
-
-                               menu = formatDropdown.getMenu();
-                               selectedLabel = menu.findSelectedItem() ? menu.findSelectedItem().getLabel() : '';
-                               if ( typeof selectedLabel !== 'string' ) {
-                                       selectedLabel = selectedLabel.text();
-                               }
-                               menu.clearItems().addItems( formatItems );
-                               menu.chooseItem( menu.getItemFromLabel( selectedLabel ) || menu.findFirstSelectableItem() );
-
-                               // Fire the event to update field visibilities
-                               Util.onFormatDropdownChange();
-
-                               page.$element.empty()
-                                       .append(
-                                               new OO.ui.FieldLayout(
-                                                       formatDropdown, {
-                                                               label: Util.parseMsg( 'apisandbox-request-selectformat-label' )
-                                                       }
-                                               ).$element,
-                                               formatItems.map( function ( item ) {
-                                                       return item.getData().$element;
-                                               } ),
-                                               $result
-                                       );
-                               ApiSandbox.updateUI();
-                               booklet.setPage( '|results|' );
-
-                               location.href = oldhash = '#' + query;
-
-                               api.post( params, {
-                                       contentType: 'multipart/form-data',
-                                       dataType: 'text',
-                                       xhr: function () {
-                                               var xhr = new window.XMLHttpRequest();
-                                               xhr.upload.addEventListener( 'progress', function ( e ) {
-                                                       if ( !progressLoading ) {
-                                                               if ( e.lengthComputable ) {
-                                                                       progress.setProgress( e.loaded * 100 / e.total );
-                                                               } else {
-                                                                       progress.setProgress( false );
-                                                               }
-                                                       }
-                                               } );
-                                               xhr.addEventListener( 'progress', function ( e ) {
-                                                       if ( !progressLoading ) {
-                                                               progressLoading = true;
-                                                               $progressText.text( mw.message( 'apisandbox-loading-results' ).text() );
-                                                       }
-                                                       if ( e.lengthComputable ) {
-                                                               progress.setProgress( e.loaded * 100 / e.total );
-                                                       } else {
-                                                               progress.setProgress( false );
-                                                       }
-                                               } );
-                                               return xhr;
-                                       }
-                               } )
-                                       .catch( function ( code, data, result, jqXHR ) {
-                                               var deferred = $.Deferred();
-
-                                               if ( code !== 'http' ) {
-                                                       // Not really an error, work around mw.Api thinking it is.
-                                                       deferred.resolve( result, jqXHR );
-                                               } else {
-                                                       // Just forward it.
-                                                       deferred.reject.apply( deferred, arguments );
-                                               }
-                                               return deferred.promise();
-                                       } )
-                                       .then( function ( data, jqXHR ) {
-                                               var m, loadTime, button, clear,
-                                                       ct = jqXHR.getResponseHeader( 'Content-Type' ),
-                                                       loginSuppressed = jqXHR.getResponseHeader( 'MediaWiki-Login-Suppressed' ) || 'false';
-
-                                               $result.empty();
-                                               if ( loginSuppressed !== 'false' ) {
-                                                       $( '<div>' )
-                                                               .addClass( 'warning' )
-                                                               .append( Util.parseMsg( 'apisandbox-results-login-suppressed' ) )
-                                                               .appendTo( $result );
-                                               }
-                                               if ( /^text\/mediawiki-api-prettyprint-wrapped(?:;|$)/.test( ct ) ) {
-                                                       data = JSON.parse( data );
-                                                       if ( data.modules.length ) {
-                                                               mw.loader.load( data.modules );
-                                                       }
-                                                       if ( data.status && data.status !== 200 ) {
-                                                               $( '<div>' )
-                                                                       .addClass( 'api-pretty-header api-pretty-status' )
-                                                                       .append( Util.parseMsg( 'api-format-prettyprint-status', data.status, data.statustext ) )
-                                                                       .appendTo( $result );
-                                                       }
-                                                       $result.append( Util.parseHTML( data.html ) );
-                                                       loadTime = data.time;
-                                               } else if ( ( m = data.match( /<pre[ >][\s\S]*<\/pre>/ ) ) ) {
-                                                       $result.append( Util.parseHTML( m[ 0 ] ) );
-                                                       if ( ( m = data.match( /"wgBackendResponseTime":\s*(\d+)/ ) ) ) {
-                                                               loadTime = parseInt( m[ 1 ], 10 );
-                                                       }
-                                               } else {
-                                                       $( '<pre>' )
-                                                               .addClass( 'api-pretty-content' )
-                                                               .text( data )
-                                                               .appendTo( $result );
-                                               }
-                                               if ( paramsAreForced || data[ 'continue' ] ) {
-                                                       $result.append(
-                                                               $( '<div>' ).append(
-                                                                       new OO.ui.ButtonWidget( {
-                                                                               label: mw.message( 'apisandbox-continue' ).text()
-                                                                       } ).on( 'click', function () {
-                                                                               ApiSandbox.sendRequest( $.extend( {}, baseRequestParams, data[ 'continue' ] ) );
-                                                                       } ).setDisabled( !data[ 'continue' ] ).$element,
-                                                                       ( clear = new OO.ui.ButtonWidget( {
-                                                                               label: mw.message( 'apisandbox-continue-clear' ).text()
-                                                                       } ).on( 'click', function () {
-                                                                               ApiSandbox.updateUI( baseRequestParams );
-                                                                               clear.setDisabled( true );
-                                                                               booklet.setPage( '|results|' );
-                                                                       } ).setDisabled( !paramsAreForced ) ).$element,
-                                                                       new OO.ui.PopupButtonWidget( {
-                                                                               $overlay: true,
-                                                                               framed: false,
-                                                                               icon: 'info',
-                                                                               popup: {
-                                                                                       $content: $( '<div>' ).append( Util.parseMsg( 'apisandbox-continue-help' ) ),
-                                                                                       padded: true,
-                                                                                       width: 'auto'
-                                                                               }
-                                                                       } ).$element
-                                                               )
-                                                       );
-                                               }
-                                               if ( typeof loadTime === 'number' ) {
-                                                       $result.append(
-                                                               $( '<div>' ).append(
-                                                                       new OO.ui.LabelWidget( {
-                                                                               label: mw.message( 'apisandbox-request-time', loadTime ).text()
-                                                                       } ).$element
-                                                               )
-                                                       );
-                                               }
-
-                                               if ( jqXHR.getResponseHeader( 'MediaWiki-API-Error' ) === 'badtoken' ) {
-                                                       // Flush all saved tokens in case one of them is the bad one.
-                                                       Util.markTokensBad();
-                                                       button = new OO.ui.ButtonWidget( {
-                                                               label: mw.message( 'apisandbox-results-fixtoken' ).text()
-                                                       } );
-                                                       button.on( 'click', ApiSandbox.fixTokenAndResend )
-                                                               .on( 'click', button.setDisabled, [ true ], button )
-                                                               .$element.appendTo( $result );
-                                               }
-                                       }, function ( code, data ) {
-                                               var details = 'HTTP error: ' + data.exception;
-                                               $result.empty()
-                                                       .append(
-                                                               new OO.ui.LabelWidget( {
-                                                                       label: mw.message( 'apisandbox-results-error', details ).text(),
-                                                                       classes: [ 'error' ]
-                                                               } ).$element
-                                                       );
-                                       } );
-                       } );
-               },
-
-               /**
-                * Handler for the "Correct token and resubmit" button
-                *
-                * Used on a 'badtoken' error, it re-fetches token parameters for all
-                * pages and then re-submits the query.
-                */
-               fixTokenAndResend: function () {
-                       var page, subpages, i, k,
-                               ok = true,
-                               tokenWait = { dummy: true },
-                               checkPages = [ pages.main ],
-                               success = function ( k ) {
-                                       delete tokenWait[ k ];
-                                       if ( ok && $.isEmptyObject( tokenWait ) ) {
-                                               ApiSandbox.sendRequest();
-                                       }
-                               },
-                               failure = function ( k ) {
-                                       delete tokenWait[ k ];
-                                       ok = false;
-                               };
-
-                       while ( checkPages.length ) {
-                               page = checkPages.shift();
-
-                               if ( page.tokenWidget ) {
-                                       k = page.apiModule + page.tokenWidget.paramInfo.name;
-                                       tokenWait[ k ] = page.tokenWidget.fetchToken();
-                                       tokenWait[ k ]
-                                               .done( success.bind( page.tokenWidget, k ) )
-                                               .fail( failure.bind( page.tokenWidget, k ) );
-                               }
-
-                               subpages = page.getSubpages();
-                               for ( i = 0; i < subpages.length; i++ ) {
-                                       if ( pages.hasOwnProperty( subpages[ i ].key ) ) {
-                                               checkPages.push( pages[ subpages[ i ].key ] );
-                                       }
-                               }
-                       }
-
-                       success( 'dummy', '' );
-               },
-
-               /**
-                * Reset validity indicators for all widgets
-                */
-               updateValidityIndicators: function () {
-                       var page, subpages, i,
-                               checkPages = [ pages.main ];
-
-                       while ( checkPages.length ) {
-                               page = checkPages.shift();
-                               page.apiCheckValid();
-                               subpages = page.getSubpages();
-                               for ( i = 0; i < subpages.length; i++ ) {
-                                       if ( pages.hasOwnProperty( subpages[ i ].key ) ) {
-                                               checkPages.push( pages[ subpages[ i ].key ] );
-                                       }
-                               }
-                       }
-               }
-       };
-
-       /**
-        * PageLayout for API modules
-        *
-        * @class
-        * @private
-        * @extends OO.ui.PageLayout
-        * @constructor
-        * @param {Object} [config] Configuration options
-        */
-       ApiSandbox.PageLayout = function ( config ) {
-               config = $.extend( { prefix: '', expanded: false }, config );
-               this.displayText = config.key;
-               this.apiModule = config.path;
-               this.prefix = config.prefix;
-               this.paramInfo = null;
-               this.apiIsValid = true;
-               this.loadFromQueryParams = null;
-               this.widgets = {};
-               this.tokenWidget = null;
-               this.indentLevel = config.indentLevel ? config.indentLevel : 0;
-               ApiSandbox.PageLayout[ 'super' ].call( this, config.key, config );
-               this.loadParamInfo();
-       };
-       OO.inheritClass( ApiSandbox.PageLayout, OO.ui.PageLayout );
-       ApiSandbox.PageLayout.prototype.setupOutlineItem = function () {
-               this.outlineItem.setLevel( this.indentLevel );
-               this.outlineItem.setLabel( this.displayText );
-               this.outlineItem.setIcon( this.apiIsValid || suppressErrors ? null : 'alert' );
-               this.outlineItem.setIconTitle(
-                       this.apiIsValid || suppressErrors ? '' : mw.message( 'apisandbox-alert-page' ).plain()
-               );
-       };
-
-       /**
-        * Fetch module information for this page's module, then create UI
-        */
-       ApiSandbox.PageLayout.prototype.loadParamInfo = function () {
-               var dynamicFieldset, dynamicParamNameWidget,
-                       that = this,
-                       removeDynamicParamWidget = function ( name, layout ) {
-                               dynamicFieldset.removeItems( [ layout ] );
-                               delete that.widgets[ name ];
-                       },
-                       addDynamicParamWidget = function () {
-                               var name, layout, widget, button;
-
-                               // Check name is filled in
-                               name = dynamicParamNameWidget.getValue().trim();
-                               if ( name === '' ) {
-                                       dynamicParamNameWidget.focus();
-                                       return;
-                               }
-
-                               if ( that.widgets[ name ] !== undefined ) {
-                                       windowManager.openWindow( 'errorAlert', {
-                                               title: Util.parseMsg( 'apisandbox-dynamic-error-exists', name ),
-                                               actions: [
-                                                       {
-                                                               action: 'accept',
-                                                               label: OO.ui.msg( 'ooui-dialog-process-dismiss' ),
-                                                               flags: 'primary'
-                                                       }
-                                               ]
-                                       } );
-                                       return;
-                               }
-
-                               widget = Util.createWidgetForParameter( {
-                                       name: name,
-                                       type: 'string',
-                                       'default': ''
-                               }, {
-                                       nooptional: true
-                               } );
-                               button = new OO.ui.ButtonWidget( {
-                                       icon: 'trash',
-                                       flags: 'destructive'
-                               } );
-                               layout = new OO.ui.ActionFieldLayout(
-                                       widget,
-                                       button,
-                                       {
-                                               label: name,
-                                               align: 'left'
-                                       }
-                               );
-                               button.on( 'click', removeDynamicParamWidget, [ name, layout ] );
-                               that.widgets[ name ] = widget;
-                               dynamicFieldset.addItems( [ layout ], dynamicFieldset.getItems().length - 1 );
-                               widget.focus();
-
-                               dynamicParamNameWidget.setValue( '' );
-                       };
-
-               this.$element.empty()
-                       .append( new OO.ui.ProgressBarWidget( {
-                               progress: false,
-                               text: mw.message( 'apisandbox-loading', this.displayText ).text()
-                       } ).$element );
-
-               Util.fetchModuleInfo( this.apiModule )
-                       .done( function ( pi ) {
-                               var prefix, i, j, descriptionContainer, widget, layoutConfig, button, widgetField, helpField, tmp, flag, count,
-                                       items = [],
-                                       deprecatedItems = [],
-                                       buttons = [],
-                                       filterFmModules = function ( v ) {
-                                               return v.substr( -2 ) !== 'fm' ||
-                                                       !availableFormats.hasOwnProperty( v.substr( 0, v.length - 2 ) );
-                                       },
-                                       widgetLabelOnClick = function () {
-                                               var f = this.getField();
-                                               if ( $.isFunction( f.setDisabled ) ) {
-                                                       f.setDisabled( false );
-                                               }
-                                               if ( $.isFunction( f.focus ) ) {
-                                                       f.focus();
-                                               }
-                                       };
-
-                               // This is something of a hack. We always want the 'format' and
-                               // 'action' parameters from the main module to be specified,
-                               // and for 'format' we also want to simplify the dropdown since
-                               // we always send the 'fm' variant.
-                               if ( that.apiModule === 'main' ) {
-                                       for ( i = 0; i < pi.parameters.length; i++ ) {
-                                               if ( pi.parameters[ i ].name === 'action' ) {
-                                                       pi.parameters[ i ].required = true;
-                                                       delete pi.parameters[ i ][ 'default' ];
-                                               }
-                                               if ( pi.parameters[ i ].name === 'format' ) {
-                                                       tmp = pi.parameters[ i ].type;
-                                                       for ( j = 0; j < tmp.length; j++ ) {
-                                                               availableFormats[ tmp[ j ] ] = true;
-                                                       }
-                                                       pi.parameters[ i ].type = tmp.filter( filterFmModules );
-                                                       pi.parameters[ i ][ 'default' ] = 'json';
-                                                       pi.parameters[ i ].required = true;
-                                               }
-                                       }
-                               }
-
-                               // Hide the 'wrappedhtml' parameter on format modules
-                               if ( pi.group === 'format' ) {
-                                       pi.parameters = pi.parameters.filter( function ( p ) {
-                                               return p.name !== 'wrappedhtml';
-                                       } );
-                               }
-
-                               that.paramInfo = pi;
-
-                               items.push( new OO.ui.FieldLayout(
-                                       new OO.ui.Widget( {} ).toggle( false ), {
-                                               align: 'top',
-                                               label: Util.parseHTML( pi.description )
-                                       }
-                               ) );
-
-                               if ( pi.helpurls.length ) {
-                                       buttons.push( new OO.ui.PopupButtonWidget( {
-                                               $overlay: true,
-                                               label: mw.message( 'apisandbox-helpurls' ).text(),
-                                               icon: 'help',
-                                               popup: {
-                                                       width: 'auto',
-                                                       padded: true,
-                                                       $content: $( '<ul>' ).append( pi.helpurls.map( function ( link ) {
-                                                               return $( '<li>' ).append( $( '<a>' )
-                                                                       .attr( { href: link, target: '_blank' } )
-                                                                       .text( link )
-                                                               );
-                                                       } ) )
-                                               }
-                                       } ) );
-                               }
-
-                               if ( pi.examples.length ) {
-                                       buttons.push( new OO.ui.PopupButtonWidget( {
-                                               $overlay: true,
-                                               label: mw.message( 'apisandbox-examples' ).text(),
-                                               icon: 'code',
-                                               popup: {
-                                                       width: 'auto',
-                                                       padded: true,
-                                                       $content: $( '<ul>' ).append( pi.examples.map( function ( example ) {
-                                                               var a = $( '<a>' )
-                                                                       .attr( 'href', '#' + example.query )
-                                                                       .html( example.description );
-                                                               a.find( 'a' ).contents().unwrap(); // Can't nest links
-                                                               return $( '<li>' ).append( a );
-                                                       } ) )
-                                               }
-                                       } ) );
-                               }
-
-                               if ( buttons.length ) {
-                                       items.push( new OO.ui.FieldLayout(
-                                               new OO.ui.ButtonGroupWidget( {
-                                                       items: buttons
-                                               } ), { align: 'top' }
-                                       ) );
-                               }
-
-                               if ( pi.parameters.length ) {
-                                       prefix = that.prefix + pi.prefix;
-                                       for ( i = 0; i < pi.parameters.length; i++ ) {
-                                               widget = Util.createWidgetForParameter( pi.parameters[ i ] );
-                                               that.widgets[ prefix + pi.parameters[ i ].name ] = widget;
-                                               if ( pi.parameters[ i ].tokentype ) {
-                                                       that.tokenWidget = widget;
-                                               }
-
-                                               descriptionContainer = $( '<div>' );
-
-                                               tmp = Util.parseHTML( pi.parameters[ i ].description );
-                                               tmp.filter( 'dl' ).makeCollapsible( {
-                                                       collapsed: true
-                                               } ).children( '.mw-collapsible-toggle' ).each( function () {
-                                                       var $this = $( this );
-                                                       $this.parent().prev( 'p' ).append( $this );
-                                               } );
-                                               descriptionContainer.append( $( '<div>' ).addClass( 'description' ).append( tmp ) );
-
-                                               if ( pi.parameters[ i ].info && pi.parameters[ i ].info.length ) {
-                                                       for ( j = 0; j < pi.parameters[ i ].info.length; j++ ) {
-                                                               descriptionContainer.append( $( '<div>' )
-                                                                       .addClass( 'info' )
-                                                                       .append( Util.parseHTML( pi.parameters[ i ].info[ j ] ) )
-                                                               );
-                                                       }
-                                               }
-                                               flag = true;
-                                               count = 1e100;
-                                               switch ( pi.parameters[ i ].type ) {
-                                                       case 'namespace':
-                                                               flag = false;
-                                                               count = mw.config.get( 'wgFormattedNamespaces' ).length;
-                                                               break;
-
-                                                       case 'limit':
-                                                               if ( pi.parameters[ i ].highmax !== undefined ) {
-                                                                       descriptionContainer.append( $( '<div>' )
-                                                                               .addClass( 'info' )
-                                                                               .append(
-                                                                                       Util.parseMsg(
-                                                                                               'api-help-param-limit2', pi.parameters[ i ].max, pi.parameters[ i ].highmax
-                                                                                       ),
-                                                                                       ' ',
-                                                                                       Util.parseMsg( 'apisandbox-param-limit' )
-                                                                               )
-                                                                       );
-                                                               } else {
-                                                                       descriptionContainer.append( $( '<div>' )
-                                                                               .addClass( 'info' )
-                                                                               .append(
-                                                                                       Util.parseMsg( 'api-help-param-limit', pi.parameters[ i ].max ),
-                                                                                       ' ',
-                                                                                       Util.parseMsg( 'apisandbox-param-limit' )
-                                                                               )
-                                                                       );
-                                                               }
-                                                               break;
-
-                                                       case 'integer':
-                                                               tmp = '';
-                                                               if ( pi.parameters[ i ].min !== undefined ) {
-                                                                       tmp += 'min';
-                                                               }
-                                                               if ( pi.parameters[ i ].max !== undefined ) {
-                                                                       tmp += 'max';
-                                                               }
-                                                               if ( tmp !== '' ) {
-                                                                       descriptionContainer.append( $( '<div>' )
-                                                                               .addClass( 'info' )
-                                                                               .append( Util.parseMsg(
-                                                                                       'api-help-param-integer-' + tmp,
-                                                                                       Util.apiBool( pi.parameters[ i ].multi ) ? 2 : 1,
-                                                                                       pi.parameters[ i ].min, pi.parameters[ i ].max
-                                                                               ) )
-                                                                       );
-                                                               }
-                                                               break;
-
-                                                       default:
-                                                               if ( Array.isArray( pi.parameters[ i ].type ) ) {
-                                                                       flag = false;
-                                                                       count = pi.parameters[ i ].type.length;
-                                                               }
-                                                               break;
-                                               }
-                                               if ( Util.apiBool( pi.parameters[ i ].multi ) ) {
-                                                       tmp = [];
-                                                       if ( flag && !( widget instanceof OO.ui.TagMultiselectWidget ) &&
-                                                               !(
-                                                                       widget instanceof OptionalWidget &&
-                                                                       widget.widget instanceof OO.ui.TagMultiselectWidget
-                                                               )
-                                                       ) {
-                                                               tmp.push( mw.message( 'api-help-param-multi-separate' ).parse() );
-                                                       }
-                                                       if ( count > pi.parameters[ i ].lowlimit ) {
-                                                               tmp.push(
-                                                                       mw.message( 'api-help-param-multi-max',
-                                                                               pi.parameters[ i ].lowlimit, pi.parameters[ i ].highlimit
-                                                                       ).parse()
-                                                               );
-                                                       }
-                                                       if ( tmp.length ) {
-                                                               descriptionContainer.append( $( '<div>' )
-                                                                       .addClass( 'info' )
-                                                                       .append( Util.parseHTML( tmp.join( ' ' ) ) )
-                                                               );
-                                                       }
-                                               }
-                                               if ( 'maxbytes' in pi.parameters[ i ] ) {
-                                                       descriptionContainer.append( $( '<div>' )
-                                                               .addClass( 'info' )
-                                                               .append( Util.parseMsg( 'api-help-param-maxbytes', pi.parameters[ i ].maxbytes ) )
-                                                       );
-                                               }
-                                               if ( 'maxchars' in pi.parameters[ i ] ) {
-                                                       descriptionContainer.append( $( '<div>' )
-                                                               .addClass( 'info' )
-                                                               .append( Util.parseMsg( 'api-help-param-maxchars', pi.parameters[ i ].maxchars ) )
-                                                       );
-                                               }
-                                               helpField = new OO.ui.FieldLayout(
-                                                       new OO.ui.Widget( {
-                                                               $content: '\xa0',
-                                                               classes: [ 'mw-apisandbox-spacer' ]
-                                                       } ), {
-                                                               align: 'inline',
-                                                               classes: [ 'mw-apisandbox-help-field' ],
-                                                               label: descriptionContainer
-                                                       }
-                                               );
-
-                                               layoutConfig = {
-                                                       align: 'left',
-                                                       classes: [ 'mw-apisandbox-widget-field' ],
-                                                       label: prefix + pi.parameters[ i ].name
-                                               };
-
-                                               if ( pi.parameters[ i ].tokentype ) {
-                                                       button = new OO.ui.ButtonWidget( {
-                                                               label: mw.message( 'apisandbox-fetch-token' ).text()
-                                                       } );
-                                                       button.on( 'click', widget.fetchToken, [], widget );
-
-                                                       widgetField = new OO.ui.ActionFieldLayout( widget, button, layoutConfig );
-                                               } else {
-                                                       widgetField = new OO.ui.FieldLayout( widget, layoutConfig );
-                                               }
-
-                                               // We need our own click handler on the widget label to
-                                               // turn off the disablement.
-                                               widgetField.$label.on( 'click', widgetLabelOnClick.bind( widgetField ) );
-
-                                               // Don't grey out the label when the field is disabled,
-                                               // it makes it too hard to read and our "disabled"
-                                               // isn't really disabled.
-                                               widgetField.onFieldDisable( false );
-                                               widgetField.onFieldDisable = $.noop;
-
-                                               if ( Util.apiBool( pi.parameters[ i ].deprecated ) ) {
-                                                       deprecatedItems.push( widgetField, helpField );
-                                               } else {
-                                                       items.push( widgetField, helpField );
-                                               }
-                                       }
-                               }
-
-                               if ( !pi.parameters.length && !Util.apiBool( pi.dynamicparameters ) ) {
-                                       items.push( new OO.ui.FieldLayout(
-                                               new OO.ui.Widget( {} ).toggle( false ), {
-                                                       align: 'top',
-                                                       label: Util.parseMsg( 'apisandbox-no-parameters' )
-                                               }
-                                       ) );
-                               }
-
-                               that.$element.empty();
-
-                               new OO.ui.FieldsetLayout( {
-                                       label: that.displayText
-                               } ).addItems( items )
-                                       .$element.appendTo( that.$element );
-
-                               if ( Util.apiBool( pi.dynamicparameters ) ) {
-                                       dynamicFieldset = new OO.ui.FieldsetLayout();
-                                       dynamicParamNameWidget = new OO.ui.TextInputWidget( {
-                                               placeholder: mw.message( 'apisandbox-dynamic-parameters-add-placeholder' ).text()
-                                       } ).on( 'enter', addDynamicParamWidget );
-                                       dynamicFieldset.addItems( [
-                                               new OO.ui.FieldLayout(
-                                                       new OO.ui.Widget( {} ).toggle( false ), {
-                                                               align: 'top',
-                                                               label: Util.parseHTML( pi.dynamicparameters )
-                                                       }
-                                               ),
-                                               new OO.ui.ActionFieldLayout(
-                                                       dynamicParamNameWidget,
-                                                       new OO.ui.ButtonWidget( {
-                                                               icon: 'add',
-                                                               flags: 'progressive'
-                                                       } ).on( 'click', addDynamicParamWidget ),
-                                                       {
-                                                               label: mw.message( 'apisandbox-dynamic-parameters-add-label' ).text(),
-                                                               align: 'left'
-                                                       }
-                                               )
-                                       ] );
-                                       $( '<fieldset>' )
-                                               .append(
-                                                       $( '<legend>' ).text( mw.message( 'apisandbox-dynamic-parameters' ).text() ),
-                                                       dynamicFieldset.$element
-                                               )
-                                               .appendTo( that.$element );
-                               }
-
-                               if ( deprecatedItems.length ) {
-                                       tmp = new OO.ui.FieldsetLayout().addItems( deprecatedItems ).toggle( false );
-                                       $( '<fieldset>' )
-                                               .append(
-                                                       $( '<legend>' ).append(
-                                                               new OO.ui.ToggleButtonWidget( {
-                                                                       label: mw.message( 'apisandbox-deprecated-parameters' ).text()
-                                                               } ).on( 'change', tmp.toggle, [], tmp ).$element
-                                                       ),
-                                                       tmp.$element
-                                               )
-                                               .appendTo( that.$element );
-                               }
-
-                               // Load stored params, if any, then update the booklet if we
-                               // have subpages (or else just update our valid-indicator).
-                               tmp = that.loadFromQueryParams;
-                               that.loadFromQueryParams = null;
-                               if ( $.isPlainObject( tmp ) ) {
-                                       that.loadQueryParams( tmp );
-                               }
-                               if ( that.getSubpages().length > 0 ) {
-                                       ApiSandbox.updateUI( tmp );
-                               } else {
-                                       that.apiCheckValid();
-                               }
-                       } ).fail( function ( code, detail ) {
-                               that.$element.empty()
-                                       .append(
-                                               new OO.ui.LabelWidget( {
-                                                       label: mw.message( 'apisandbox-load-error', that.apiModule, detail ).text(),
-                                                       classes: [ 'error' ]
-                                               } ).$element,
-                                               new OO.ui.ButtonWidget( {
-                                                       label: mw.message( 'apisandbox-retry' ).text()
-                                               } ).on( 'click', that.loadParamInfo, [], that ).$element
-                                       );
-                       } );
-       };
-
-       /**
-        * Check that all widgets on the page are in a valid state.
-        *
-        * @return {jQuery.Promise[]} One promise for each widget, resolved with `false` if invalid
-        */
-       ApiSandbox.PageLayout.prototype.apiCheckValid = function () {
-               var promises, that = this;
-
-               if ( this.paramInfo === null ) {
-                       return [];
-               } else {
-                       promises = $.map( this.widgets, function ( widget ) {
-                               return widget.apiCheckValid();
-                       } );
-                       $.when.apply( $, promises ).then( function () {
-                               that.apiIsValid = $.inArray( false, arguments ) === -1;
-                               if ( that.getOutlineItem() ) {
-                                       that.getOutlineItem().setIcon( that.apiIsValid || suppressErrors ? null : 'alert' );
-                                       that.getOutlineItem().setIconTitle(
-                                               that.apiIsValid || suppressErrors ? '' : mw.message( 'apisandbox-alert-page' ).plain()
-                                       );
-                               }
-                       } );
-                       return promises;
-               }
-       };
-
-       /**
-        * Load form fields from query parameters
-        *
-        * @param {Object} params
-        */
-       ApiSandbox.PageLayout.prototype.loadQueryParams = function ( params ) {
-               if ( this.paramInfo === null ) {
-                       this.loadFromQueryParams = params;
-               } else {
-                       $.each( this.widgets, function ( name, widget ) {
-                               var v = params.hasOwnProperty( name ) ? params[ name ] : undefined;
-                               widget.setApiValue( v );
-                       } );
-               }
-       };
-
-       /**
-        * Load query params from form fields
-        *
-        * @param {Object} params Write query parameters into this object
-        * @param {Object} displayParams Write query parameters for display into this object
-        */
-       ApiSandbox.PageLayout.prototype.getQueryParams = function ( params, displayParams ) {
-               $.each( this.widgets, function ( name, widget ) {
-                       var value = widget.getApiValue();
-                       if ( value !== undefined ) {
-                               params[ name ] = value;
-                               if ( $.isFunction( widget.getApiValueForDisplay ) ) {
-                                       value = widget.getApiValueForDisplay();
-                               }
-                               displayParams[ name ] = value;
-                       }
-               } );
-       };
-
-       /**
-        * Fetch a list of subpage names loaded by this page
-        *
-        * @return {Array}
-        */
-       ApiSandbox.PageLayout.prototype.getSubpages = function () {
-               var ret = [];
-               $.each( this.widgets, function ( name, widget ) {
-                       var submodules, i;
-                       if ( $.isFunction( widget.getSubmodules ) ) {
-                               submodules = widget.getSubmodules();
-                               for ( i = 0; i < submodules.length; i++ ) {
-                                       ret.push( {
-                                               key: name + '=' + submodules[ i ].value,
-                                               path: submodules[ i ].path,
-                                               prefix: widget.paramInfo.submoduleparamprefix || ''
-                                       } );
-                               }
-                       }
-               } );
-               return ret;
-       };
-
-       $( ApiSandbox.init );
-
-       module.exports = ApiSandbox;
-
-}( jQuery, mediaWiki, OO ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.apisandbox.top.css b/resources/src/mediawiki.special/mediawiki.special.apisandbox.top.css
deleted file mode 100644 (file)
index 4dc4c27..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-.client-js .mw-apisandbox-nojs {
-       display: none;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.block.js b/resources/src/mediawiki.special/mediawiki.special.block.js
deleted file mode 100644 (file)
index 180f040..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*!
- * JavaScript for Special:Block
- */
-( function ( mw, $ ) {
-       // Like OO.ui.infuse(), but if the element doesn't exist, return null instead of throwing an exception.
-       function infuseOrNull( elem ) {
-               try {
-                       return OO.ui.infuse( elem );
-               } catch ( er ) {
-                       return null;
-               }
-       }
-
-       $( function () {
-               // This code is also loaded on the "block succeeded" page where there is no form,
-               // so username and expiry fields might also be missing.
-               var blockTargetWidget = infuseOrNull( 'mw-bi-target' ),
-                       anonOnlyField = infuseOrNull( $( '#mw-input-wpHardBlock' ).closest( '.oo-ui-fieldLayout' ) ),
-                       enableAutoblockField = infuseOrNull( $( '#mw-input-wpAutoBlock' ).closest( '.oo-ui-fieldLayout' ) ),
-                       hideUserField = infuseOrNull( $( '#mw-input-wpHideUser' ).closest( '.oo-ui-fieldLayout' ) ),
-                       watchUserField = infuseOrNull( $( '#mw-input-wpWatch' ).closest( '.oo-ui-fieldLayout' ) ),
-                       expiryWidget = infuseOrNull( 'mw-input-wpExpiry' );
-
-               function updateBlockOptions() {
-                       var blocktarget = blockTargetWidget.getValue().trim(),
-                               isEmpty = blocktarget === '',
-                               isIp = mw.util.isIPAddress( blocktarget, true ),
-                               isIpRange = isIp && blocktarget.match( /\/\d+$/ ),
-                               isNonEmptyIp = isIp && !isEmpty,
-                               expiryValue = expiryWidget.getValue(),
-                               // infinityValues  are the values the SpecialBlock class accepts as infinity (sf. wfIsInfinity)
-                               infinityValues = [ 'infinite', 'indefinite', 'infinity', 'never' ],
-                               isIndefinite = infinityValues.indexOf( expiryValue ) !== -1;
-
-                       if ( enableAutoblockField ) {
-                               enableAutoblockField.toggle( !( isNonEmptyIp ) );
-                       }
-                       if ( hideUserField ) {
-                               hideUserField.toggle( !( isNonEmptyIp || !isIndefinite ) );
-                       }
-                       if ( anonOnlyField ) {
-                               anonOnlyField.toggle( !( !isIp && !isEmpty ) );
-                       }
-                       if ( watchUserField ) {
-                               watchUserField.toggle( !( isIpRange && !isEmpty ) );
-                       }
-               }
-
-               if ( blockTargetWidget ) {
-                       // Bind functions so they're checked whenever stuff changes
-                       blockTargetWidget.on( 'change', updateBlockOptions );
-                       expiryWidget.on( 'change', updateBlockOptions );
-
-                       // Call them now to set initial state (ie. Special:Block/Foobar?wpBlockExpiry=2+hours)
-                       updateBlockOptions();
-               }
-       } );
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.changecredentials.js b/resources/src/mediawiki.special/mediawiki.special.changecredentials.js
deleted file mode 100644 (file)
index ad8a4f4..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*!
- * JavaScript for change credentials form.
- */
-( function ( mw, $, OO ) {
-       mw.hook( 'htmlform.enhance' ).add( function ( $root ) {
-               var api = new mw.Api();
-
-               $root.find( '.mw-changecredentials-validate-password.oo-ui-fieldLayout' ).each( function () {
-                       var currentApiPromise,
-                               self = OO.ui.FieldLayout.static.infuse( $( this ) );
-
-                       self.getField().setValidation( function ( password ) {
-                               var d;
-
-                               if ( currentApiPromise ) {
-                                       currentApiPromise.abort();
-                                       currentApiPromise = undefined;
-                               }
-
-                               password = password.trim();
-
-                               if ( password === '' ) {
-                                       self.setErrors( [] );
-                                       return true;
-                               }
-
-                               d = $.Deferred();
-                               currentApiPromise = api.post( {
-                                       action: 'validatepassword',
-                                       password: password,
-                                       formatversion: 2,
-                                       errorformat: 'html',
-                                       errorsuselocal: true,
-                                       uselang: mw.config.get( 'wgUserLanguage' )
-                               } ).done( function ( resp ) {
-                                       var pwinfo = resp.validatepassword,
-                                               good = pwinfo.validity === 'Good',
-                                               errors = [];
-
-                                       currentApiPromise = undefined;
-
-                                       if ( !good ) {
-                                               pwinfo.validitymessages.map( function ( m ) {
-                                                       errors.push( new OO.ui.HtmlSnippet( m.html ) );
-                                               } );
-                                       }
-                                       self.setErrors( errors );
-                                       d.resolve( good );
-                               } ).fail( d.reject );
-
-                               return d.promise( { abort: currentApiPromise.abort } );
-                       } );
-               } );
-       } );
-}( mediaWiki, jQuery, OO ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.changeslist.css b/resources/src/mediawiki.special/mediawiki.special.changeslist.css
deleted file mode 100644 (file)
index 65860ea..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*!
- * Styling for Special:Watchlist and Special:RecentChanges
- */
-
-.mw-changeslist-line-watched .mw-title {
-       font-weight: bold;
-}
-
-/*
- * Titles, including username links, and also tag names
- * are prone to getting jumbled up
- * with other titles, usernames, etc. in mixed RTL-LTR environment.
- */
-.mw-changeslist .mw-tag-marker,
-.mw-changeslist .mw-title {
-       unicode-bidi: embed;
-}
-
-/* Colored watchlist and recent changes numbers */
-.mw-plusminus-pos {
-       color: #006400; /* dark green */
-}
-
-.mw-plusminus-neg {
-       color: #8b0000; /* dark red */
-}
-
-.mw-plusminus-null {
-       color: #a2a9b1; /* gray */
-}
-
-/*
- * Bidi-isolate these numbers.
- * See https://phabricator.wikimedia.org/T93484
- */
-.mw-plusminus-pos,
-.mw-plusminus-neg,
-.mw-plusminus-null {
-       unicode-bidi: -moz-isolate;
-       unicode-bidi: isolate;
-}
-
-/* Prevent FOUC if legend is initially collapsed */
-.mw-changeslist-legend.mw-collapsed .mw-collapsible-content {
-       display: none;
-}
-
-.mw-changeslist-legend.mw-collapsed {
-       margin-bottom: 0;
-}
-
-/* Prevent pushing down the content if legend is collapsed */
-.mw-changeslist-legend.mw-collapsed ~ ul:first-of-type > li:first-child,
-.mw-changeslist-legend.mw-collapsed + h4 + div > table.mw-changeslist-line:first-child {
-       clear: right;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.changeslist.enhanced.css b/resources/src/mediawiki.special/mediawiki.special.changeslist.enhanced.css
deleted file mode 100644 (file)
index cb11332..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*!
- * Styling for Special:Watchlist and Special:RecentChanges when preference 'usenewrc'
- * a.k.a. Enhanced Recent Changes is enabled.
- */
-
-table.mw-enhanced-rc {
-       border: 0;
-       border-spacing: 0;
-}
-
-table.mw-enhanced-rc th,
-table.mw-enhanced-rc td {
-       padding: 0;
-       vertical-align: top;
-}
-
-td.mw-enhanced-rc {
-       white-space: nowrap;
-       font-family: monospace, monospace;
-}
-
-.mw-enhanced-rc-time {
-       font-family: monospace, monospace;
-}
-
-table.mw-enhanced-rc td.mw-enhanced-rc-nested {
-       padding-left: 1em;
-}
-
-/* Show/hide arrows in enhanced changeslist */
-.mw-enhanced-rc .collapsible-expander {
-       float: none;
-}
-
-/* If JS is disabled, the arrows or the placeholder space shouldn't be shown */
-.client-nojs .mw-enhancedchanges-arrow-space {
-       display: none;
-}
-
-/*
- * And if it's enabled, let's optimize the collapsing a little: hide the rows
- * that would be hidden by jquery.makeCollapsible with CSS to save us some
- * reflows and repaints. This doesn't work on browsers that don't fully support
- * CSS2 (IE6), but it's okay, this will be done in JavaScript with old degraded
- * performance instead.
- */
-.client-js table.mw-enhanced-rc.mw-collapsed tr + tr {
-       display: none;
-}
-
-.mw-enhancedchanges-arrow {
-       padding-top: 2px;
-}
-
-.mw-enhancedchanges-arrow-space {
-       display: inline-block;
-       *display: inline; /* IE7 and below */
-       zoom: 1;
-       width: 15px;
-       height: 15px;
-}
-
-.mw-enhanced-watched .mw-enhanced-rc-time {
-       font-weight: bold;
-}
-
-span.changedby {
-       font-size: 95%;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.changeslist.legend.css b/resources/src/mediawiki.special/mediawiki.special.changeslist.legend.css
deleted file mode 100644 (file)
index 14f6aee..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*!
- * Styling for changes list legend
- */
-
-.mw-changeslist-legend {
-       float: right;
-       margin-left: 1em;
-       margin-bottom: 0.5em;
-       clear: right;
-       font-size: 85%;
-       line-height: 1.2em;
-       padding: 0.5em;
-       border: 1px solid #ddd;
-}
-
-.mw-changeslist-legend dl {
-       /* Parent element defines sufficient padding */
-       margin-bottom: 0;
-}
-
-.mw-changeslist-legend dt {
-       float: left;
-       margin: 0 0.5em 0 0;
-}
-
-.mw-changeslist-legend dd {
-       margin-left: 1.5em;
-}
-
-.mw-changeslist-legend dt,
-.mw-changeslist-legend dd {
-       line-height: 1.3em;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.changeslist.legend.js b/resources/src/mediawiki.special/mediawiki.special.changeslist.legend.js
deleted file mode 100644 (file)
index 0792762..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*!
- * Script for changes list legend
- */
-
-/* Remember the collapse state of the legend on recent changes and watchlist pages. */
-( function ( mw ) {
-       var
-               cookieName = 'changeslist-state',
-               // Expanded by default
-               doCollapsibleLegend = function ( $container ) {
-                       $container.find( '.mw-changeslist-legend' )
-                               .makeCollapsible( {
-                                       collapsed: mw.cookie.get( cookieName ) === 'collapsed'
-                               } )
-                               .on( 'beforeExpand.mw-collapsible', function () {
-                                       mw.cookie.set( cookieName, 'expanded' );
-                               } )
-                               .on( 'beforeCollapse.mw-collapsible', function () {
-                                       mw.cookie.set( cookieName, 'collapsed' );
-                               } );
-               };
-
-       mw.hook( 'wikipage.content' ).add( doCollapsibleLegend );
-}( mediaWiki ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.changeslist.visitedstatus.js b/resources/src/mediawiki.special/mediawiki.special.changeslist.visitedstatus.js
deleted file mode 100644 (file)
index 6b25327..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/*!
- * JavaScript for Special:Watchlist
- */
-( function ( $ ) {
-       $( function () {
-               $( '.mw-changeslist-line-watched .mw-title a' ).on( 'click', function () {
-                       $( this )
-                               .closest( '.mw-changeslist-line-watched' )
-                               .removeClass( 'mw-changeslist-line-watched' );
-               } );
-       } );
-}( jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.comparepages.styles.less b/resources/src/mediawiki.special/mediawiki.special.comparepages.styles.less
deleted file mode 100644 (file)
index 87b7a8b..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-@import 'mediawiki.mixins';
-
-.mw-special-ComparePages .mw-htmlform-ooui-wrapper {
-       width: 100%;
-}
-
-.mw-special-ComparePages .oo-ui-layout.oo-ui-panelLayout.oo-ui-panelLayout-padded.oo-ui-panelLayout-framed {
-       float: left;
-       width: 49%;
-       .box-sizing( border-box );
-}
-
-.mw-special-ComparePages .oo-ui-layout.oo-ui-panelLayout.oo-ui-panelLayout-padded.oo-ui-panelLayout-framed:nth-of-type( 2 ) {
-       margin-left: 2%;
-}
-
-.mw-special-ComparePages .mw-htmlform-submit-buttons {
-       clear: both;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.contributions.js b/resources/src/mediawiki.special/mediawiki.special.contributions.js
deleted file mode 100644 (file)
index f65a257..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-( function ( mw, $ ) {
-       $( function () {
-               var startInput = mw.widgets.DateInputWidget.static.infuse( 'mw-date-start' ),
-                       endInput = mw.widgets.DateInputWidget.static.infuse( 'mw-date-end' );
-
-               startInput.on( 'deactivate', function ( userSelected ) {
-                       if ( userSelected ) {
-                               endInput.focus();
-                       }
-               } );
-       } );
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.css b/resources/src/mediawiki.special/mediawiki.special.css
deleted file mode 100644 (file)
index 0676bfc..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Special:AllMessages */
-#mw-allmessagestable .allmessages-customised .am_default {
-       background-color: #fcffc4;
-}
-
-#mw-allmessagestable .allmessages-customised:hover .am_default {
-       background-color: #faff90;
-}
-
-#mw-allmessagestable .am_actual {
-       background-color: #e2ffe2;
-}
-
-#mw-allmessagestable .allmessages-customised:hover + .allmessages-customised .am_actual {
-       background-color: #b1ffb1;
-}
-
-/* Common for Special:Allpages and Special:PrefixIndex */
-.mw-allpages-body,
-.mw-prefixindex-body {
-       columns: 22em 3;
-       -moz-columns: 22em 3;
-       -webkit-columns: 22em 3;
-       break-inside: avoid-column;
-       page-break-inside: avoid;
-       -webkit-column-break-inside: avoid;
-}
-
-.mw-allpages-chunk,
-.mw-prefixindex-list {
-       margin-top: 0;
-       margin-bottom: 0;
-}
-
-.allpagesredirect {
-       font-style: italic;
-}
-
-/* Special:Block */
-.mw-ipb-conveniencelinks {
-       font-size: 90%;
-       text-align: right;
-}
-
-.mw-block-hideuser,
-.mw-block-confirm {
-       font-weight: bold;
-}
-
-#mw-input-wpReason .oo-ui-dropdownInputWidget,
-#mw-input-wpReason .oo-ui-textInputWidget {
-       display: block;
-       max-width: 50em;
-}
-
-#mw-input-wpReason .oo-ui-textInputWidget {
-       margin-top: 0.5em;
-}
-
-/* Special:BlockList */
-.mw-blocklist .mw-usertoollinks,
-.mw-blocklist-actions {
-       white-space: nowrap;
-       font-size: 90%;
-}
-
-/* Special:Contributions */
-.mw-uctop {
-       font-weight: bold;
-}
-.mw-contributions-form select {
-       vertical-align: middle;
-}
-
-/* Special:EditWatchlist */
-.watchlistredir {
-       font-style: italic;
-}
-
-/* Special:EmailUser */
-#mw-emailuser-sender,
-#mw-emailuser-recipient {
-       font-weight: bold;
-}
-
-/* Special:FileDuplicateSearch */
-#mw-fileduplicatesearch-icon {
-       float: right;
-}
-
-/* Special:ListGroupRights */
-.mw-listgrouprights-table tr {
-       vertical-align: top;
-}
-.listgrouprights-revoked {
-       text-decoration: line-through;
-}
-
-/* Special:RevisionDelete */
-.mw-revdel-editreasons {
-       font-size: 90%;
-       text-align: right;
-}
-
-/* Special:Specialpages */
-.mw-specialpagerestricted {
-       font-weight: bold;
-}
-
-.mw-specialpages-list {
-       -webkit-columns: 16em 2;
-       -moz-columns: 16em 2;
-       columns: 16em 2;
-}
-
-.mw-specialpages-list ul {
-       margin-top: 0;
-       margin-bottom: 0;
-}
-
-/* Special:Statistics */
-.mw-statistics-numbers {
-       text-align: right;
-}
-
-/* Special:ProtectedPages */
-.mw-protectedpages .mw-usertoollinks,
-.mw-protectedpages-length,
-.mw-protectedpages-actions {
-       white-space: nowrap;
-       font-size: 90%;
-}
-.mw-protectedpages-unknown {
-       color: #72777d;
-       font-size: 90%;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.edittags.css b/resources/src/mediawiki.special/mediawiki.special.edittags.css
deleted file mode 100644 (file)
index 204009c..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*!
- * Styling for Special:EditTags and action=editchangetags
- */
-#mw-edittags-tags-selector td {
-       vertical-align: top;
-}
-
-#mw-edittags-tags-selector-multi td {
-       vertical-align: top;
-       padding-right: 1.5em;
-}
-
-#mw-edittags-tag-list {
-       min-width: 20em;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.edittags.js b/resources/src/mediawiki.special/mediawiki.special.edittags.js
deleted file mode 100644 (file)
index 4f51e9b..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*!
- * JavaScript for Special:EditTags
- */
-( function ( mw, $ ) {
-       $( function () {
-               var summaryCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
-                       summaryByteLimit = mw.config.get( 'wgCommentByteLimit' ),
-                       $wpReason = $( '#wpReason' ),
-                       $tagList = $( '#mw-edittags-tag-list' );
-
-               if ( $tagList.length ) {
-                       $tagList.chosen( {
-                               /* eslint-disable camelcase */
-                               placeholder_text_multiple: mw.msg( 'tags-edit-chosen-placeholder' ),
-                               no_results_text: mw.msg( 'tags-edit-chosen-no-results' )
-                               /* eslint-enable camelcase */
-                       } );
-               }
-
-               $( '#mw-edittags-remove-all' ).on( 'change', function ( e ) {
-                       $( '.mw-edittags-remove-checkbox' ).prop( 'checked', e.target.checked );
-               } );
-               $( '.mw-edittags-remove-checkbox' ).on( 'change', function ( e ) {
-                       if ( !e.target.checked ) {
-                               $( '#mw-edittags-remove-all' ).prop( 'checked', false );
-                       }
-               } );
-
-               // Limit to bytes or UTF-8 codepoints, depending on MediaWiki's configuration
-               // use maxLength because it's leaving room for log entry text.
-               if ( summaryCodePointLimit ) {
-                       $wpReason.codePointLimit();
-               } else if ( summaryByteLimit ) {
-                       $wpReason.byteLimit();
-               }
-       } );
-
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.import.js b/resources/src/mediawiki.special/mediawiki.special.import.js
deleted file mode 100644 (file)
index 2cb96af..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*!
- * JavaScript for Special:Import
- */
-( function ( $ ) {
-       var subprojectListAlreadyShown;
-       function updateImportSubprojectList() {
-               var $projectField = $( '#mw-import-table-interwiki #interwiki' ),
-                       $subprojectField = $projectField.parent().find( '#subproject' ),
-                       $selected = $projectField.find( ':selected' ),
-                       oldValue = $subprojectField.val(),
-                       option, options;
-
-               if ( $selected.attr( 'data-subprojects' ) ) {
-                       options = $selected.attr( 'data-subprojects' ).split( ' ' ).map( function ( el ) {
-                               option = document.createElement( 'option' );
-                               option.appendChild( document.createTextNode( el ) );
-                               option.setAttribute( 'value', el );
-                               if ( oldValue === el && subprojectListAlreadyShown === true ) {
-                                       option.setAttribute( 'selected', 'selected' );
-                               }
-                               return option;
-                       } );
-                       $subprojectField.show().empty().append( options );
-                       subprojectListAlreadyShown = true;
-               } else {
-                       $subprojectField.hide();
-               }
-       }
-
-       $( function () {
-               var $projectField = $( '#mw-import-table-interwiki #interwiki' );
-               if ( $projectField.length ) {
-                       $projectField.change( updateImportSubprojectList );
-                       updateImportSubprojectList();
-               }
-       } );
-}( jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.movePage.css b/resources/src/mediawiki.special/mediawiki.special.movePage.css
deleted file mode 100644 (file)
index 9428fed..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/*!
- * Styles for Special:MovePage
- */
-
-.movepage-wrapper {
-       width: 50em;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.movePage.js b/resources/src/mediawiki.special/mediawiki.special.movePage.js
deleted file mode 100644 (file)
index d828396..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*!
- * JavaScript for Special:MovePage
- */
-( function ( mw, $ ) {
-       $( function () {
-               var summaryCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
-                       summaryByteLimit = mw.config.get( 'wgCommentByteLimit' ),
-                       wpReason = OO.ui.infuse( $( '#wpReason' ) );
-
-               // Infuse for pretty dropdown
-               OO.ui.infuse( $( '#wpNewTitle' ) );
-               // Limit to bytes or UTF-8 codepoints, depending on MediaWiki's configuration
-               if ( summaryCodePointLimit ) {
-                       mw.widgets.visibleCodePointLimit( wpReason, summaryCodePointLimit );
-               } else if ( summaryByteLimit ) {
-                       mw.widgets.visibleByteLimit( wpReason, summaryByteLimit );
-               }
-               // Infuse for nicer "help" popup
-               if ( $( '#wpMovetalk-field' ).length ) {
-                       OO.ui.infuse( $( '#wpMovetalk-field' ) );
-               }
-       } );
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.pageLanguage.js b/resources/src/mediawiki.special/mediawiki.special.pageLanguage.js
deleted file mode 100644 (file)
index edfbe1e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/*!
- * JavaScript module used on Special:PageLanguage
- */
-( function ( $, OO ) {
-       $( function () {
-               // Select the 'Language select' option if user is trying to select language
-               OO.ui.infuse( 'mw-pl-languageselector' ).on( 'change', function () {
-                       OO.ui.infuse( 'mw-pl-options' ).setValue( '2' );
-               } );
-       } );
-}( jQuery, OO ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.pagesWithProp.css b/resources/src/mediawiki.special/mediawiki.special.pagesWithProp.css
deleted file mode 100644 (file)
index 7ef75d0..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-/* Distinguish actual data from information about it being hidden visually */
-.prop-value-hidden {
-       font-style: italic;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.preferences.confirmClose.js b/resources/src/mediawiki.special/mediawiki.special.preferences.confirmClose.js
deleted file mode 100644 (file)
index 244154b..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*!
- * JavaScript for Special:Preferences: Enable save button and prevent the window being accidentally
- * closed when any form field is changed.
- */
-( function ( mw, $ ) {
-       $( function () {
-               var allowCloseWindow, saveButton, restoreButton,
-                       oouiEnabled = $( '#mw-prefs-form' ).hasClass( 'mw-htmlform-ooui' );
-
-               // Check if all of the form values are unchanged.
-               // (This function could be changed to infuse and check OOUI widgets, but that would only make it
-               // slower and more complicated. It works fine to treat them as HTML elements.)
-               function isPrefsChanged() {
-                       var inputs = $( '#mw-prefs-form :input[name]' ),
-                               input, $input, inputType,
-                               index, optIndex,
-                               opt;
-
-                       for ( index = 0; index < inputs.length; index++ ) {
-                               input = inputs[ index ];
-                               $input = $( input );
-
-                               // Different types of inputs have different methods for accessing defaults
-                               if ( $input.is( 'select' ) ) {
-                                       // <select> has the property defaultSelected for each option
-                                       for ( optIndex = 0; optIndex < input.options.length; optIndex++ ) {
-                                               opt = input.options[ optIndex ];
-                                               if ( opt.selected !== opt.defaultSelected ) {
-                                                       return true;
-                                               }
-                                       }
-                               } else if ( $input.is( 'input' ) || $input.is( 'textarea' ) ) {
-                                       // <input> has defaultValue or defaultChecked
-                                       inputType = input.type;
-                                       if ( inputType === 'radio' || inputType === 'checkbox' ) {
-                                               if ( input.checked !== input.defaultChecked ) {
-                                                       return true;
-                                               }
-                                       } else if ( input.value !== input.defaultValue ) {
-                                               return true;
-                                       }
-                               }
-                       }
-
-                       return false;
-               }
-
-               if ( oouiEnabled ) {
-                       saveButton = OO.ui.infuse( $( '#prefcontrol' ) );
-                       restoreButton = OO.ui.infuse( $( '#mw-prefs-restoreprefs' ) );
-
-                       // Disable the button to save preferences unless preferences have changed
-                       // Check if preferences have been changed before JS has finished loading
-                       saveButton.setDisabled( !isPrefsChanged() );
-                       $( '#preferences .oo-ui-fieldsetLayout' ).on( 'change keyup mouseup', function () {
-                               saveButton.setDisabled( !isPrefsChanged() );
-                       } );
-               } else {
-                       // Disable the button to save preferences unless preferences have changed
-                       // Check if preferences have been changed before JS has finished loading
-                       $( '#prefcontrol' ).prop( 'disabled', !isPrefsChanged() );
-                       $( '#preferences > fieldset' ).on( 'change keyup mouseup', function () {
-                               $( '#prefcontrol' ).prop( 'disabled', !isPrefsChanged() );
-                       } );
-               }
-
-               // Set up a message to notify users if they try to leave the page without
-               // saving.
-               allowCloseWindow = mw.confirmCloseWindow( {
-                       test: isPrefsChanged,
-                       message: mw.msg( 'prefswarning-warning', mw.msg( 'saveprefs' ) ),
-                       namespace: 'prefswarning'
-               } );
-               $( '#mw-prefs-form' ).on( 'submit', $.proxy( allowCloseWindow, 'release' ) );
-               if ( oouiEnabled ) {
-                       restoreButton.on( 'click', function () {
-                               allowCloseWindow.release();
-                               // The default behavior of events in OOUI is always prevented. Follow the link manually.
-                               // Note that middle-click etc. still works, as it doesn't emit a OOUI 'click' event.
-                               location.href = restoreButton.getHref();
-                       } );
-               } else {
-                       $( '#mw-prefs-restoreprefs' ).on( 'click', $.proxy( allowCloseWindow, 'release' ) );
-               }
-       } );
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.preferences.convertmessagebox.js b/resources/src/mediawiki.special/mediawiki.special.preferences.convertmessagebox.js
deleted file mode 100644 (file)
index e6b7432..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/*!
- * JavaScript for Special:Preferences: Check for successbox to replace with notifications.
- */
-( function ( $ ) {
-       $( function () {
-               var convertmessagebox = require( 'mediawiki.notification.convertmessagebox' );
-               convertmessagebox();
-       } );
-}( jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.preferences.editfont.js b/resources/src/mediawiki.special/mediawiki.special.preferences.editfont.js
deleted file mode 100644 (file)
index fe48886..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*!
- * JavaScript for Special:Preferences: editfont field enhancements.
- */
-( function ( mw, $ ) {
-       $( function () {
-               var widget, lastValue;
-
-               try {
-                       widget = OO.ui.infuse( $( '#mw-input-wpeditfont' ) );
-               } catch ( err ) {
-                       // This preference could theoretically be disabled ($wgHiddenPrefs)
-                       return;
-               }
-
-               // Style options
-               widget.dropdownWidget.menu.items.forEach( function ( item ) {
-                       item.$label.addClass( 'mw-editfont-' + item.getData() );
-               } );
-
-               function updateLabel( value ) {
-                       // Style selected item label
-                       widget.dropdownWidget.$label
-                               .removeClass( 'mw-editfont-' + lastValue )
-                               .addClass( 'mw-editfont-' + value );
-                       lastValue = value;
-               }
-
-               widget.on( 'change', updateLabel );
-               updateLabel( widget.getValue() );
-
-       } );
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.preferences.personalEmail.js b/resources/src/mediawiki.special/mediawiki.special.preferences.personalEmail.js
deleted file mode 100644 (file)
index f934d59..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*!
- * JavaScript for Special:Preferences: Email preferences better UX
- */
-( function ( $ ) {
-       $( function () {
-               var allowEmail, allowEmailFromNewUsers;
-
-               allowEmail = $( '#wpAllowEmail' );
-               allowEmailFromNewUsers = $( '#wpAllowEmailFromNewUsers' );
-
-               function toggleDisabled() {
-                       if ( allowEmail.is( ':checked' ) && allowEmail.is( ':enabled' ) ) {
-                               allowEmailFromNewUsers.prop( 'disabled', false );
-                       } else {
-                               allowEmailFromNewUsers.prop( 'disabled', true );
-                       }
-               }
-
-               if ( allowEmail ) {
-                       allowEmail.on( 'change', toggleDisabled );
-                       toggleDisabled();
-               }
-       } );
-}( jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.preferences.styles.css b/resources/src/mediawiki.special/mediawiki.special.preferences.styles.css
deleted file mode 100644 (file)
index 8810318..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Reuses colors from mediawiki.legacy/shared.css */
-.mw-email-not-authenticated .oo-ui-labelWidget,
-.mw-email-none .oo-ui-labelWidget {
-       border: 1px solid #fde29b;
-       background-color: #fdf1d1;
-       color: #000;
-       padding: 0.5em;
-}
-/* Authenticated email field has its own class too. Unstyled by default */
-/*
-.mw-email-authenticated .oo-ui-labelWidget { }
-*/
-
-/* This is needed because add extra buttons in a weird way */
-.mw-prefs-buttons .mw-htmlform-submit-buttons {
-       margin: 0;
-       display: inline;
-}
-
-.mw-prefs-buttons {
-       margin-top: 1em;
-}
-
-#prefcontrol {
-       margin-right: 0.5em;
-}
-
-/*
- * Hide, but keep accessible for screen-readers.
- * Like .mw-jump, #jump-to-nav from shared.css
- */
-.client-js .mw-navigation-hint {
-       overflow: hidden;
-       height: 0;
-       zoom: 1;
-}
-
-/* Override OOUI styles so that dropdowns near the bottom of the form don't get clipped,
- * e.g.'Appearance' / 'Threshold for stub link formatting'. This is hacky and bad, it would be
- * better solved by setting overlays for the widgets, but we can't do it from PHP... */
-#preferences .oo-ui-panelLayout {
-       position: static;
-       overflow: visible;
-       -webkit-transform: none;
-       transform: none;
-}
-
-#preferences .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed {
-       border-color: #c8ccd1;
-       border-width: 1px 0 0;
-       border-radius: 0;
-       padding-left: 0;
-       padding-right: 0;
-       box-shadow: none;
-}
-
-/* Tweak the margins to reduce the shifting of form contents
- * after JS code loads and rearranges the page */
-.client-js #preferences > .oo-ui-panelLayout {
-       margin: 1em 0;
-}
-
-.client-js #preferences .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed {
-       margin-left: 0.25em;
-}
-
-.client-js #preferences .oo-ui-tabPanelLayout {
-       padding-top: 0.5em;
-       padding-bottom: 0.5em;
-}
-
-.client-js #preferences .oo-ui-tabPanelLayout .oo-ui-panelLayout-framed {
-       margin-left: 0;
-       margin-bottom: 0;
-       border: 0;
-       padding-top: 0;
-}
-
-.client-js #preferences > .oo-ui-panelLayout > .oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-header {
-       margin-bottom: 1em;
-}
-
-/* Make the "Basic information" section more compact */
-/* OOUI's `align: 'left'` for FieldLayouts sucks, so we do our own */
-#mw-htmlform-info > .oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header {
-       width: 20%;
-       display: inline-block;
-       vertical-align: middle;
-       padding: 0;
-}
-
-#mw-htmlform-info > .oo-ui-fieldLayout-align-top .oo-ui-fieldLayout-help {
-       margin-right: 0;
-}
-
-#mw-htmlform-info > .oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
-       width: 80%;
-       display: inline-block;
-       vertical-align: middle;
-}
-
-/* Expand the dropdown and textfield of "Time zone" field to the */
-/* usual maximum width and display them on separate lines. */
-#wpTimeCorrection .oo-ui-dropdownInputWidget,
-#wpTimeCorrection .oo-ui-textInputWidget {
-       display: block;
-       max-width: 50em;
-}
-
-#wpTimeCorrection .oo-ui-textInputWidget {
-       margin-top: 0.5em;
-}
-
-/* HACK: expand width of gadget descriptions.
- * This should be moved to the Gadgets extension */
-#mw-htmlform-gadgets .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body {
-       max-width: none;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.preferences.styles.legacy.css b/resources/src/mediawiki.special/mediawiki.special.preferences.styles.legacy.css
deleted file mode 100644 (file)
index 33b630a..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Reuses colors from mediawiki.legacy/shared.css */
-.mw-email-not-authenticated .mw-input,
-.mw-email-none .mw-input {
-       border: 1px solid #fde29b;
-       background-color: #fdf1d1;
-       color: #000;
-}
-/* Authenticated email field has its own class too. Unstyled by default */
-/*
-.mw-email-authenticated .mw-input { }
-*/
-/* This breaks due to nolabel styling */
-#preferences > fieldset td.mw-label {
-       width: 20%;
-}
-
-#preferences > fieldset table {
-       width: 100%;
-}
-#preferences > fieldset table.mw-htmlform-matrix {
-       width: auto;
-}
-
-/* The CSS below is also for JS enabled version, because we want to prevent FOUC */
-
-/*
- * Hide, but keep accessible for screen-readers.
- * Like .mw-jump, #jump-to-nav from shared.css
- */
-.client-js .mw-navigation-hint {
-       overflow: hidden;
-       height: 0;
-       zoom: 1;
-}
-
-.client-nojs #preftoc {
-       display: none;
-}
-
-.client-js #preferences > fieldset {
-       display: none;
-}
-
-/* Only the 1st tab is shown by default in JS mode */
-.client-js #preferences #mw-prefsection-personal {
-       display: block;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.preferences.tabs.js b/resources/src/mediawiki.special/mediawiki.special.preferences.tabs.js
deleted file mode 100644 (file)
index c948ff0..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/*!
- * JavaScript for Special:Preferences: Tab navigation.
- */
-( function ( mw, $ ) {
-       $( function () {
-               var $preferences, tabs, wrapper, previousTab;
-
-               $preferences = $( '#preferences' );
-
-               // Make sure the accessibility tip is selectable so that screen reader users take notice,
-               // but hide it per default to reduce interface clutter. Also make sure it becomes visible
-               // when selected. Similar to jquery.mw-jump
-               $( '<div>' ).addClass( 'mw-navigation-hint' )
-                       .text( mw.msg( 'prefs-tabs-navigation-hint' ) )
-                       .attr( 'tabIndex', 0 )
-                       .on( 'focus blur', function ( e ) {
-                               if ( e.type === 'blur' || e.type === 'focusout' ) {
-                                       $( this ).css( 'height', '0' );
-                               } else {
-                                       $( this ).css( 'height', 'auto' );
-                               }
-                       } ).prependTo( '#mw-content-text' );
-
-               tabs = new OO.ui.IndexLayout( {
-                       expanded: false,
-                       // Do not remove focus from the tabs menu after choosing a tab
-                       autoFocus: false
-               } );
-
-               mw.config.get( 'wgPreferencesTabs' ).forEach( function ( tabConfig ) {
-                       var panel, $panelContents;
-
-                       panel = new OO.ui.TabPanelLayout( tabConfig.name, {
-                               expanded: false,
-                               label: tabConfig.label
-                       } );
-                       $panelContents = $( '#mw-prefsection-' + tabConfig.name );
-
-                       // Hide the unnecessary PHP PanelLayouts
-                       // (Do not use .remove(), as that would remove event handlers for everything inside them)
-                       $panelContents.parent().detach();
-
-                       panel.$element.append( $panelContents );
-                       tabs.addTabPanels( [ panel ] );
-
-                       // Remove duplicate labels
-                       // (This must be after .addTabPanels(), otherwise the tab item doesn't exist yet)
-                       $panelContents.children( 'legend' ).remove();
-                       $panelContents.attr( 'aria-labelledby', panel.getTabItem().getElementId() );
-               } );
-
-               wrapper = new OO.ui.PanelLayout( {
-                       expanded: false,
-                       padded: false,
-                       framed: true
-               } );
-               wrapper.$element.append( tabs.$element );
-               $preferences.prepend( wrapper.$element );
-
-               function updateHash( panel ) {
-                       var scrollTop, active;
-                       // Handle hash manually to prevent jumping,
-                       // therefore save and restore scrollTop to prevent jumping.
-                       scrollTop = $( window ).scrollTop();
-                       // Changing the hash apparently causes keyboard focus to be lost?
-                       // Save and restore it. This makes no sense though.
-                       active = document.activeElement;
-                       location.hash = '#mw-prefsection-' + panel.getName();
-                       if ( active ) {
-                               active.focus();
-                       }
-                       $( window ).scrollTop( scrollTop );
-               }
-
-               tabs.on( 'set', updateHash );
-
-               /**
-                * @ignore
-                * @param {string} name the name of a tab without the prefix ("mw-prefsection-")
-                * @param {string} [mode] A hash will be set according to the current
-                *  open section. Set mode 'noHash' to supress this.
-                */
-               function switchPrefTab( name, mode ) {
-                       if ( mode === 'noHash' ) {
-                               tabs.off( 'set', updateHash );
-                       }
-                       tabs.setTabPanel( name );
-                       if ( mode === 'noHash' ) {
-                               tabs.on( 'set', updateHash );
-                       }
-               }
-
-               // Jump to correct section as indicated by the hash.
-               // This function is called onload and onhashchange.
-               function detectHash() {
-                       var hash = location.hash,
-                               matchedElement, parentSection;
-                       if ( hash.match( /^#mw-prefsection-[\w]+$/ ) ) {
-                               mw.storage.session.remove( 'mwpreferences-prevTab' );
-                               switchPrefTab( hash.replace( '#mw-prefsection-', '' ) );
-                       } else if ( hash.match( /^#mw-[\w-]+$/ ) ) {
-                               matchedElement = document.getElementById( hash.slice( 1 ) );
-                               parentSection = $( matchedElement ).parent().closest( '[id^="mw-prefsection-"]' );
-                               if ( parentSection.length ) {
-                                       mw.storage.session.remove( 'mwpreferences-prevTab' );
-                                       // Switch to proper tab and scroll to selected item.
-                                       switchPrefTab( parentSection.attr( 'id' ).replace( 'mw-prefsection-', '' ), 'noHash' );
-                                       matchedElement.scrollIntoView();
-                               }
-                       }
-               }
-
-               $( window ).on( 'hashchange', function () {
-                       var hash = location.hash;
-                       if ( hash.match( /^#mw-[\w-]+/ ) ) {
-                               detectHash();
-                       } else if ( hash === '' ) {
-                               switchPrefTab( 'personal', 'noHash' );
-                       }
-               } )
-                       // Run the function immediately to select the proper tab on startup.
-                       .trigger( 'hashchange' );
-
-               // Restore the active tab after saving the preferences
-               previousTab = mw.storage.session.get( 'mwpreferences-prevTab' );
-               if ( previousTab ) {
-                       switchPrefTab( previousTab, 'noHash' );
-                       // Deleting the key, the tab states should be reset until we press Save
-                       mw.storage.session.remove( 'mwpreferences-prevTab' );
-               }
-
-               $( '#mw-prefs-form' ).on( 'submit', function () {
-                       var value = tabs.getCurrentTabPanelName();
-                       mw.storage.session.set( 'mwpreferences-prevTab', value );
-               } );
-
-       } );
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.preferences.tabs.legacy.js b/resources/src/mediawiki.special/mediawiki.special.preferences.tabs.legacy.js
deleted file mode 100644 (file)
index 0d97d68..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*!
- * JavaScript for Special:Preferences: Tab navigation.
- */
-( function ( mw, $ ) {
-       $( function () {
-               var $preftoc, $preferences, $fieldsets, labelFunc, previousTab;
-
-               labelFunc = function () {
-                       return this.id.replace( /^mw-prefsection/g, 'preftab' );
-               };
-
-               $preftoc = $( '#preftoc' );
-               $preferences = $( '#preferences' );
-
-               $fieldsets = $preferences.children( 'fieldset' )
-                       .attr( {
-                               role: 'tabpanel',
-                               'aria-labelledby': labelFunc
-                       } );
-               $fieldsets.not( '#mw-prefsection-personal' )
-                       .hide()
-                       .attr( 'aria-hidden', 'true' );
-
-               // T115692: The following is kept for backwards compatibility with older skins
-               $preferences.addClass( 'jsprefs' );
-               $fieldsets.addClass( 'prefsection' );
-               $fieldsets.children( 'legend' ).addClass( 'mainLegend' );
-
-               // Make sure the accessibility tip is selectable so that screen reader users take notice,
-               // but hide it per default to reduce interface clutter. Also make sure it becomes visible
-               // when selected. Similar to jquery.mw-jump
-               $( '<div>' ).addClass( 'mw-navigation-hint' )
-                       .text( mw.msg( 'prefs-tabs-navigation-hint' ) )
-                       .attr( 'tabIndex', 0 )
-                       .on( 'focus blur', function ( e ) {
-                               if ( e.type === 'blur' || e.type === 'focusout' ) {
-                                       $( this ).css( 'height', '0' );
-                               } else {
-                                       $( this ).css( 'height', 'auto' );
-                               }
-                       } ).insertBefore( $preftoc );
-
-               /**
-                * It uses document.getElementById for security reasons (HTML injections in $()).
-                *
-                * @ignore
-                * @param {string} name the name of a tab without the prefix ("mw-prefsection-")
-                * @param {string} [mode] A hash will be set according to the current
-                *  open section. Set mode 'noHash' to surpress this.
-                */
-               function switchPrefTab( name, mode ) {
-                       var $tab, scrollTop;
-                       // Handle hash manually to prevent jumping,
-                       // therefore save and restore scrollTop to prevent jumping.
-                       scrollTop = $( window ).scrollTop();
-                       if ( mode !== 'noHash' ) {
-                               location.hash = '#mw-prefsection-' + name;
-                       }
-                       $( window ).scrollTop( scrollTop );
-
-                       $preftoc.find( 'li' ).removeClass( 'selected' )
-                               .find( 'a' ).attr( {
-                                       tabIndex: -1,
-                                       'aria-selected': 'false'
-                               } );
-
-                       $tab = $( document.getElementById( 'preftab-' + name ) );
-                       if ( $tab.length ) {
-                               $tab.attr( {
-                                       tabIndex: 0,
-                                       'aria-selected': 'true'
-                               } ).focus()
-                                       .parent().addClass( 'selected' );
-
-                               $preferences.children( 'fieldset' ).hide().attr( 'aria-hidden', 'true' );
-                               $( document.getElementById( 'mw-prefsection-' + name ) ).show().attr( 'aria-hidden', 'false' );
-                       }
-               }
-
-               // Enable keyboard users to use left and right keys to switch tabs
-               $preftoc.on( 'keydown', function ( event ) {
-                       var keyLeft = 37,
-                               keyRight = 39,
-                               $el;
-
-                       if ( event.keyCode === keyLeft ) {
-                               $el = $( '#preftoc li.selected' ).prev().find( 'a' );
-                       } else if ( event.keyCode === keyRight ) {
-                               $el = $( '#preftoc li.selected' ).next().find( 'a' );
-                       } else {
-                               return;
-                       }
-                       if ( $el.length > 0 ) {
-                               switchPrefTab( $el.attr( 'href' ).replace( '#mw-prefsection-', '' ) );
-                       }
-               } );
-
-               // Jump to correct section as indicated by the hash.
-               // This function is called onload and onhashchange.
-               function detectHash() {
-                       var hash = location.hash,
-                               matchedElement, parentSection;
-                       if ( hash.match( /^#mw-prefsection-[\w]+$/ ) ) {
-                               mw.storage.session.remove( 'mwpreferences-prevTab' );
-                               switchPrefTab( hash.replace( '#mw-prefsection-', '' ) );
-                       } else if ( hash.match( /^#mw-[\w-]+$/ ) ) {
-                               matchedElement = document.getElementById( hash.slice( 1 ) );
-                               parentSection = $( matchedElement ).parent().closest( '[id^="mw-prefsection-"]' );
-                               if ( parentSection.length ) {
-                                       mw.storage.session.remove( 'mwpreferences-prevTab' );
-                                       // Switch to proper tab and scroll to selected item.
-                                       switchPrefTab( parentSection.attr( 'id' ).replace( 'mw-prefsection-', '' ), 'noHash' );
-                                       matchedElement.scrollIntoView();
-                               }
-                       }
-               }
-
-               $( window ).on( 'hashchange', function () {
-                       var hash = location.hash;
-                       if ( hash.match( /^#mw-[\w-]+/ ) ) {
-                               detectHash();
-                       } else if ( hash === '' ) {
-                               switchPrefTab( 'personal', 'noHash' );
-                       }
-               } )
-                       // Run the function immediately to select the proper tab on startup.
-                       .trigger( 'hashchange' );
-
-               // Restore the active tab after saving the preferences
-               previousTab = mw.storage.session.get( 'mwpreferences-prevTab' );
-               if ( previousTab ) {
-                       switchPrefTab( previousTab, 'noHash' );
-                       // Deleting the key, the tab states should be reset until we press Save
-                       mw.storage.session.remove( 'mwpreferences-prevTab' );
-               }
-
-               $( '#mw-prefs-form' ).on( 'submit', function () {
-                       var value = $( $preftoc ).find( 'li.selected a' ).attr( 'id' ).replace( 'preftab-', '' );
-                       mw.storage.session.set( 'mwpreferences-prevTab', value );
-               } );
-
-       } );
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.preferences.timezone.js b/resources/src/mediawiki.special/mediawiki.special.preferences.timezone.js
deleted file mode 100644 (file)
index a6ffae9..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*!
- * JavaScript for Special:Preferences: Timezone field enhancements.
- */
-( function ( mw, $ ) {
-       $( function () {
-               var $tzSelect, $tzTextbox, timezoneWidget, $localtimeHolder, servertime,
-                       oouiEnabled = $( '#mw-prefs-form' ).hasClass( 'mw-htmlform-ooui' );
-
-               // Timezone functions.
-               // Guesses Timezone from browser and updates fields onchange.
-
-               if ( oouiEnabled ) {
-                       // This is identical to OO.ui.infuse( ... ), but it makes the class name of the result known.
-                       try {
-                               timezoneWidget = mw.widgets.SelectWithInputWidget.static.infuse( $( '#wpTimeCorrection' ) );
-                       } catch ( err ) {
-                               // This preference could theoretically be disabled ($wgHiddenPrefs)
-                               timezoneWidget = null;
-                       }
-               } else {
-                       $tzSelect = $( '#mw-input-wptimecorrection' );
-                       $tzTextbox = $( '#mw-input-wptimecorrection-other' );
-               }
-
-               $localtimeHolder = $( '#wpLocalTime' );
-               servertime = parseInt( $( 'input[name="wpServerTime"]' ).val(), 10 );
-
-               function minutesToHours( min ) {
-                       var tzHour = Math.floor( Math.abs( min ) / 60 ),
-                               tzMin = Math.abs( min ) % 60,
-                               tzString = ( ( min >= 0 ) ? '' : '-' ) + ( ( tzHour < 10 ) ? '0' : '' ) + tzHour +
-                                       ':' + ( ( tzMin < 10 ) ? '0' : '' ) + tzMin;
-                       return tzString;
-               }
-
-               function hoursToMinutes( hour ) {
-                       var minutes,
-                               arr = hour.split( ':' );
-
-                       arr[ 0 ] = parseInt( arr[ 0 ], 10 );
-
-                       if ( arr.length === 1 ) {
-                               // Specification is of the form [-]XX
-                               minutes = arr[ 0 ] * 60;
-                       } else {
-                               // Specification is of the form [-]XX:XX
-                               minutes = Math.abs( arr[ 0 ] ) * 60 + parseInt( arr[ 1 ], 10 );
-                               if ( arr[ 0 ] < 0 ) {
-                                       minutes *= -1;
-                               }
-                       }
-                       // Gracefully handle non-numbers.
-                       if ( isNaN( minutes ) ) {
-                               return 0;
-                       } else {
-                               return minutes;
-                       }
-               }
-
-               function updateTimezoneSelection() {
-                       var minuteDiff, localTime,
-                               type = oouiEnabled ? timezoneWidget.dropdowninput.getValue() : $tzSelect.val(),
-                               val = oouiEnabled ? timezoneWidget.textinput.getValue() : $tzTextbox.val();
-
-                       if ( type === 'other' ) {
-                               // User specified time zone manually in <input>
-                               // Grab data from the textbox, parse it.
-                               minuteDiff = hoursToMinutes( val );
-                       } else {
-                               // Time zone not manually specified by user
-                               if ( type === 'guess' ) {
-                                       // Get browser timezone & fill it in
-                                       minuteDiff = -( new Date().getTimezoneOffset() );
-                                       if ( oouiEnabled ) {
-                                               timezoneWidget.textinput.setValue( minutesToHours( minuteDiff ) );
-                                               timezoneWidget.dropdowninput.setValue( 'other' );
-                                       } else {
-                                               $tzTextbox.val( minutesToHours( minuteDiff ) );
-                                               $tzSelect.val( 'other' );
-                                       }
-                               } else {
-                                       // Grab data from the dropdown value
-                                       minuteDiff = parseInt( type.split( '|' )[ 1 ], 10 ) || 0;
-                               }
-                       }
-
-                       // Determine local time from server time and minutes difference, for display.
-                       localTime = servertime + minuteDiff;
-
-                       // Bring time within the [0,1440) range.
-                       localTime = ( ( localTime % 1440 ) + 1440 ) % 1440;
-
-                       $localtimeHolder.text( mw.language.convertNumber( minutesToHours( localTime ) ) );
-               }
-
-               if ( oouiEnabled ) {
-                       if ( timezoneWidget ) {
-                               timezoneWidget.dropdowninput.on( 'change', updateTimezoneSelection );
-                               timezoneWidget.textinput.on( 'change', updateTimezoneSelection );
-                               updateTimezoneSelection();
-                       }
-               } else {
-                       if ( $tzSelect.length && $tzTextbox.length ) {
-                               $tzSelect.change( updateTimezoneSelection );
-                               $tzTextbox.blur( updateTimezoneSelection );
-                               updateTimezoneSelection();
-                       }
-               }
-
-       } );
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.recentchanges.js b/resources/src/mediawiki.special/mediawiki.special.recentchanges.js
deleted file mode 100644 (file)
index 29c0fea..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*!
- * JavaScript for Special:RecentChanges
- */
-( function ( mw, $ ) {
-       var rc, $checkboxes, $select;
-
-       /**
-        * @class mw.special.recentchanges
-        * @singleton
-        */
-       rc = {
-               /**
-                * Handler to disable/enable the namespace selector checkboxes when the
-                * special 'all' namespace is selected/unselected respectively.
-                */
-               updateCheckboxes: function () {
-                       // The option element for the 'all' namespace has an empty value
-                       var isAllNS = $select.val() === '';
-
-                       // Iterates over checkboxes and propagate the selected option
-                       $checkboxes.prop( 'disabled', isAllNS );
-               },
-
-               init: function () {
-                       $select = $( '#namespace' );
-                       $checkboxes = $( '#nsassociated, #nsinvert' );
-
-                       // Bind to change event, and trigger once to set the initial state of the checkboxes.
-                       rc.updateCheckboxes();
-                       $select.change( rc.updateCheckboxes );
-               }
-       };
-
-       $( rc.init );
-
-       module.exports = rc;
-
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.revisionDelete.js b/resources/src/mediawiki.special/mediawiki.special.revisionDelete.js
deleted file mode 100644 (file)
index cad9db0..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*!
- * JavaScript for Special:RevisionDelete
- */
-( function ( mw, $ ) {
-       var colonSeparator = mw.message( 'colon-separator' ).text(),
-               summaryCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
-               summaryByteLimit = mw.config.get( 'wgCommentByteLimit' ),
-               $wpRevDeleteReasonList = $( '#wpRevDeleteReasonList' ),
-               $wpReason = $( '#wpReason' ),
-               filterFn = function ( input ) {
-                       // Should be built the same as in SpecialRevisionDelete::submit()
-                       var comment = $wpRevDeleteReasonList.val();
-                       if ( comment === 'other' ) {
-                               comment = input;
-                       } else if ( input !== '' ) {
-                               // Entry from drop down menu + additional comment
-                               comment += colonSeparator + input;
-                       }
-                       return comment;
-               };
-
-       // Limit to bytes or UTF-8 codepoints, depending on MediaWiki's configuration
-       if ( summaryCodePointLimit ) {
-               $wpReason.codePointLimit( summaryCodePointLimit, filterFn );
-       } else if ( summaryByteLimit ) {
-               $wpReason.byteLimit( summaryByteLimit, filterFn );
-       }
-
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.search.commonsInterwikiWidget.js b/resources/src/mediawiki.special/mediawiki.special.search.commonsInterwikiWidget.js
deleted file mode 100644 (file)
index 648bf67..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-( function ( mw, $ ) {
-
-       var api = new mw.Api(),
-               pageUrl = new mw.Uri(),
-               imagesText = new mw.Message( mw.messages, 'searchprofile-images' ),
-               moreResultsText = new mw.Message( mw.messages, 'search-interwiki-more-results' );
-
-       function itemTemplate( results ) {
-
-               var resultOutput = '', i, result, imageCaption, imageThumbnailSrc;
-
-               for ( i = 0; i < results.length; i++ ) {
-                       result = results[ i ];
-                       imageCaption = mw.html.element( 'span', { 'class': 'iw-result__mini-gallery__caption' }, result.title );
-                       imageThumbnailSrc = ( result.thumbnail ) ? result.thumbnail.source : '';
-                       resultOutput += '<div class="iw-result__mini-gallery">' +
-                                               /* escaping response content */
-                                               mw.html.element( 'a', {
-                                                       href: '/wiki/' + result.title,
-                                                       'class': 'iw-result__mini-gallery__image',
-                                                       style: 'background-image: url(' + imageThumbnailSrc + ');'
-                                               }, new mw.html.Raw( imageCaption ) ) +
-                                       '</div>';
-               }
-
-               return resultOutput;
-       }
-
-       function itemWrapperTemplate( pageQuery, itemTemplateOutput ) {
-
-               return '<li class="iw-resultset iw-resultset--image" data-iw-resultset-pos="0">' +
-                               '<div class="iw-result__header">' +
-                                       '<strong>' + imagesText.escaped() + '</strong>' +
-                               '</div>' +
-                               '<div class="iw-result__content">' +
-                               /* template output has been sanitized by mw.html.element */
-                               itemTemplateOutput +
-                               '</div>' +
-                               '<div class="iw-result__footer">' +
-                                       '<a href="/w/index.php?title=Special:Search&search=' + encodeURIComponent( pageQuery ) + '&fulltext=1&profile=images">' +
-                                               moreResultsText.escaped() +
-                                       '</a>' +
-                               '</div>' +
-                       '</li>';
-
-       }
-
-       api.get( {
-               action: 'query',
-               generator: 'search',
-               gsrsearch: pageUrl.query.search,
-               gsrnamespace: mw.config.get( 'wgNamespaceIds' ).file,
-               gsrlimit: 3,
-               prop: 'pageimages',
-               pilimit: 3,
-               piprop: 'thumbnail',
-               pithumbsize: 300,
-               formatversion: 2
-       } ).done( function ( resp ) {
-               var results = ( resp.query && resp.query.pages ) ? resp.query.pages : false,
-                       multimediaWidgetTemplate;
-
-               if ( !results ) {
-                       return;
-               }
-
-               results.sort( function ( a, b ) {
-                       return a.index - b.index;
-               } );
-
-               multimediaWidgetTemplate = itemWrapperTemplate( pageUrl.query.search, itemTemplate( results ) );
-               /* we really only need to wait for document ready for DOM manipulation */
-               $( function () {
-                       $( '.iw-results' ).append( multimediaWidgetTemplate );
-               } );
-       } );
-
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.search.css b/resources/src/mediawiki.special/mediawiki.special.search.css
deleted file mode 100644 (file)
index aad784e..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#mw-search-togglebox {
-       float: right;
-}
-#mw-search-togglebox label {
-       margin-right: 0.25em;
-}
-#mw-search-togglebox input {
-       margin-left: 0.25em;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.search.interwikiwidget.styles.less b/resources/src/mediawiki.special/mediawiki.special.search.interwikiwidget.styles.less
deleted file mode 100644 (file)
index 8ec2735..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/* interwiki search results */
-/*==========================*/
-
-@import 'mediawiki.ui/variables.less';
-@import 'mediawiki.mixins';
-
-.mw-searchresults-has-iw {
-
-       .iw-headline {
-               font-weight: bold;
-       }
-
-       .iw-results {
-               list-style: none;
-               margin: 0;
-       }
-
-       .iw-resultset {
-               .box-sizing(border-box);
-               padding: 0.5em;
-               vertical-align: top;
-               width: 100%;
-               float: left;
-               background-color: @colorGray15;
-               margin-bottom: 1em;
-               word-break: break-word;
-       }
-
-       .iw-result__title {
-               font-size: 108%; /* matching regular search title */
-       }
-
-       .iw-result:after,
-       .iw-result__content:after { /* clearfix */
-               visibility: hidden;
-               display: block;
-               font-size: 0;
-               content: ' ';
-               clear: both;
-               height: 0;
-       }
-
-       .iw-result__footer {
-               float: right;
-               font-size: 97%; /* matching main search result font-size */
-               margin-top: 0.5em;
-       }
-       .iw-result__footer a {
-               vertical-align: middle;
-               font-style: italic;
-       }
-
-       .oo-ui-icon-favicon {
-               padding-right: 1em;
-       }
-
-       /* image search result */
-       .iw-result__mini-gallery {
-               position: relative;
-               float: left;
-               width: 100%;
-               height: 200px;
-               .box-sizing(border-box);
-               padding: 0.25rem;
-       }
-
-       /* second and third images are small */
-       .iw-result__mini-gallery:nth-child( 2 ),
-       .iw-result__mini-gallery:nth-child( 3 ) { /* stylelint-disable-line indentation */
-               width: 50%;
-               height: 100px;
-       }
-
-       .iw-result__mini-gallery__image {
-               display: block;
-               position: relative;
-               width: 100%;
-               height: 100%;
-               background-size: 100% auto;
-               background-size: cover;
-               background-repeat: no-repeat;
-               background-position: center center;
-       }
-
-       /* image gallery text */
-       .iw-result__mini-gallery__image > .iw-result__mini-gallery__caption {
-               visibility: hidden;
-               position: absolute;
-               bottom: 0;
-               left: 0;
-               text-align: center;
-               color: #fff;
-               font-size: 0.8em;
-               padding: 0.5em;
-               background-color: rgba( 0, 0, 0, 0.5 );
-       }
-
-       .iw-result__mini-gallery__image:hover > .iw-result__mini-gallery__caption {
-               visibility: visible;
-       }
-
-       /* tablet and up */
-
-       @media only screen and ( min-width: @deviceWidthTablet ) {
-
-               #mw-interwiki-results {
-                       width: 30%;
-                       display: inline-block; /* used to align interwiki sidebar with the top of the main search results */
-                       margin-left: 8%; /* since inline-block causes whitespace issues, this is 8 instead of 10% */
-               }
-               .mw-search-createlink,
-               .mw-search-nonefound,
-               .mw-search-results,
-               .mw-search-interwiki-header {
-                       float: left;
-                       width: 60%;
-                       clear: left;
-                       max-width: 60%;
-               }
-       }
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.search.js b/resources/src/mediawiki.special/mediawiki.special.search.js
deleted file mode 100644 (file)
index e809f2e..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*!
- * JavaScript for Special:Search
- */
-( function ( mw, $ ) {
-       $( function () {
-               var $checkboxes, $headerLinks, updateHeaderLinks, searchWidget;
-
-               // Emulate HTML5 autofocus behavior in non HTML5 compliant browsers
-               if ( !( 'autofocus' in document.createElement( 'input' ) ) ) {
-                       $( 'input[autofocus]' ).eq( 0 ).focus();
-               }
-
-               // Create check all/none button
-               $checkboxes = $( '#powersearch input[id^=mw-search-ns]' );
-               $( '#mw-search-togglebox' ).append(
-                       $( '<label>' )
-                               .text( mw.msg( 'powersearch-togglelabel' ) )
-               ).append(
-                       $( '<input>' ).attr( 'type', 'button' )
-                               .attr( 'id', 'mw-search-toggleall' )
-                               .prop( 'value', mw.msg( 'powersearch-toggleall' ) )
-                               .click( function () {
-                                       $checkboxes.prop( 'checked', true );
-                               } )
-               ).append(
-                       $( '<input>' ).attr( 'type', 'button' )
-                               .attr( 'id', 'mw-search-togglenone' )
-                               .prop( 'value', mw.msg( 'powersearch-togglenone' ) )
-                               .click( function () {
-                                       $checkboxes.prop( 'checked', false );
-                               } )
-               );
-
-               // Change the header search links to what user entered
-               $headerLinks = $( '.search-types a' );
-               searchWidget = OO.ui.infuse( 'searchText' );
-               updateHeaderLinks = function ( value ) {
-                       $headerLinks.each( function () {
-                               var parts = $( this ).attr( 'href' ).split( 'search=' ),
-                                       lastpart = '',
-                                       prefix = 'search=';
-                               if ( parts.length > 1 && parts[ 1 ].indexOf( '&' ) !== -1 ) {
-                                       lastpart = parts[ 1 ].slice( parts[ 1 ].indexOf( '&' ) );
-                               } else {
-                                       prefix = '&search=';
-                               }
-                               this.href = parts[ 0 ] + prefix + encodeURIComponent( value ) + lastpart;
-                       } );
-               };
-               searchWidget.on( 'change', updateHeaderLinks );
-               updateHeaderLinks( searchWidget.getValue() );
-
-               // When saving settings, use the proper request method (POST instead of GET).
-               $( '#mw-search-powersearch-remember' ).change( function () {
-                       this.form.method = this.checked ? 'post' : 'get';
-               } ).trigger( 'change' );
-
-       } );
-
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.search.styles.css b/resources/src/mediawiki.special/mediawiki.special.search.styles.css
deleted file mode 100644 (file)
index ea9b987..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/* Special:Search */
-
-/*
- * Fixes sister projects box moving down the extract
- * of the first result (bug #16886).
- * It only happens when the window is small and
- * This changes slightly the layout for big screens
- * where there was space for the extracts and the
- * sister projects and thus it showed like in any
- * other browser.
- *
- * This will only affect IE 7 and lower
- */
-.searchresult {
-       display: inline !ie;
-}
-.searchresults {
-       margin: 1em 0 1em 0.4em;
-}
-/* needs extra specificity to override `.mw-body p` selector */
-.mw-body .mw-search-nonefound {
-       margin: 0;
-}
-
-.searchdidyoumean em,
-.searchmatch {
-       font-weight: bold;
-}
-
-.mw-search-results {
-       margin: 0;
-       max-width: 38em;
-}
-
-.mw-search-visualclear {
-       clear: both;
-}
-.mw-search-results li {
-       padding-bottom: 1.2em;
-       list-style: none;
-       list-style-image: none;
-}
-.mw-search-results li a {
-       font-size: 108%;
-}
-.mw-search-result-data {
-       color: #008000;
-       font-size: 97%;
-}
-.mw-search-profile-tabs {
-       background-color: #f8f9fa;
-       margin-top: 1em;
-       border: 1px solid #c8ccd1;
-       border-radius: 2px;
-}
-.search-types {
-       float: left;
-       padding-left: 0.25em;
-}
-.search-types ul {
-       margin: 0;
-       padding: 0;
-       list-style: none;
-}
-.search-types li {
-       float: left;
-       margin: 0;
-       padding: 0;
-}
-.search-types a {
-       display: block;
-       padding: 0.5em;
-}
-.search-types .current a {
-       color: #222;
-       cursor: default;
-}
-.search-types .current a:hover {
-       text-decoration: none;
-}
-.results-info {
-       float: right;
-       padding: 0.5em;
-       padding-right: 0.75em;
-       color: #54595d;
-       font-size: 95%;
-}
-#mw-search-top-table div.oo-ui-actionFieldLayout {
-       float: left;
-       width: 100%;
-}
-
-/* Advanced options menu */
-/*==========================*/
-
-#mw-searchoptions {
-       /* Support: Firefox, needs `clear: both` on `fieldset` when zoom level > 100%, see T176499 */
-       clear: both;
-       padding: 0.5em 0.75em 0.75em 0.75em;
-       background-color: #f8f9fa;
-       margin: -1px 0 0;
-       border: 1px solid #c8ccd1;
-       border-radius: 0 0 2px 2px;
-}
-#mw-searchoptions legend {
-       display: none;
-}
-#mw-searchoptions h4 {
-       padding: 0;
-       margin: 0;
-       float: left;
-}
-#mw-searchoptions table {
-       float: left;
-       margin-right: 3em;
-       border-collapse: collapse;
-}
-#mw-searchoptions table td {
-       padding: 0 1em 0 0;
-       white-space: nowrap;
-}
-#mw-searchoptions .divider {
-       clear: both;
-       border-bottom: 1px solid #eaecf0;
-       padding-top: 0.5em;
-       margin-bottom: 0.5em;
-}
-#mw-search-menu {
-       padding-left: 6em;
-       font-size: 85%;
-}
-
-#mw-search-interwiki {
-       float: right;
-       width: 18em;
-       border: 1px solid #a2a9b1;
-       margin-top: 2ex;
-}
-
-.searchalttitle,
-#mw-search-interwiki li {
-       font-size: 95%;
-}
-.mw-search-interwiki-more {
-       float: right;
-       font-size: 90%;
-}
-#mw-search-interwiki-caption {
-       text-align: center;
-       font-weight: bold;
-       font-size: 95%;
-}
-.mw-search-interwiki-project {
-       font-size: 97%;
-       text-align: left;
-       padding: 0.15em 0.15em 0.2em 0.2em;
-       background-color: #eaecf0;
-       border-top: 1px solid #c8ccd1;
-}
-
-.searchdidyoumean {
-       font-size: 127%;
-       margin-top: 0.8em;
-       /* Note that this color won't affect the link, as desired. */
-       color: #d33;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.undelete.js b/resources/src/mediawiki.special/mediawiki.special.undelete.js
deleted file mode 100644 (file)
index e3cf598..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*!
- * JavaScript for Special:Undelete
- */
-( function ( mw, $ ) {
-       $( function () {
-               var summaryCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
-                       summaryByteLimit = mw.config.get( 'wgCommentByteLimit' ),
-                       wpComment = OO.ui.infuse( $( '#wpComment' ).closest( '.oo-ui-widget' ) );
-
-               $( '#mw-undelete-invert' ).click( function () {
-                       $( '.mw-undelete-revlist input[type="checkbox"]' ).prop( 'checked', function ( i, val ) {
-                               return !val;
-                       } );
-               } );
-
-               // Limit to bytes or UTF-8 codepoints, depending on MediaWiki's configuration
-               if ( summaryCodePointLimit ) {
-                       mw.widgets.visibleCodePointLimit( wpComment, summaryCodePointLimit );
-               } else if ( summaryByteLimit ) {
-                       mw.widgets.visibleByteLimit( wpComment, summaryByteLimit );
-               }
-       } );
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.unwatchedPages.css b/resources/src/mediawiki.special/mediawiki.special.unwatchedPages.css
deleted file mode 100644 (file)
index 69fec08..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-.mw-watched-item {
-       text-decoration: line-through;
-}
-
-.mw-watch-link-disabled {
-       pointer-events: none;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.unwatchedPages.js b/resources/src/mediawiki.special/mediawiki.special.unwatchedPages.js
deleted file mode 100644 (file)
index 0886f8c..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*!
- * JavaScript for Special:UnwatchedPages
- */
-( function ( mw, $ ) {
-       $( function () {
-               $( 'a.mw-watch-link' ).click( function ( e ) {
-                       var promise,
-                               api = new mw.Api(),
-                               $link = $( this ),
-                               $subjectLink = $link.closest( 'li' ).children( 'a' ).eq( 0 ),
-                               title = mw.util.getParamValue( 'title', $link.attr( 'href' ) );
-                       // nice format
-                       title = mw.Title.newFromText( title ).toText();
-                       $link.addClass( 'mw-watch-link-disabled' );
-
-                       // Preload the notification module for mw.notify
-                       mw.loader.load( 'mediawiki.notification' );
-
-                       // Use the class to determine whether to watch or unwatch
-                       if ( !$subjectLink.hasClass( 'mw-watched-item' ) ) {
-                               $link.text( mw.msg( 'watching' ) );
-                               promise = api.watch( title ).done( function () {
-                                       $subjectLink.addClass( 'mw-watched-item' );
-                                       $link.text( mw.msg( 'unwatch' ) );
-                                       mw.notify( mw.msg( 'addedwatchtext-short', title ) );
-                               } ).fail( function () {
-                                       $link.text( mw.msg( 'watch' ) );
-                                       mw.notify( mw.msg( 'watcherrortext', title ), { type: 'error' } );
-                               } );
-                       } else {
-                               $link.text( mw.msg( 'unwatching' ) );
-                               promise = api.unwatch( title ).done( function () {
-                                       $subjectLink.removeClass( 'mw-watched-item' );
-                                       $link.text( mw.msg( 'watch' ) );
-                                       mw.notify( mw.msg( 'removedwatchtext-short', title ) );
-                               } ).fail( function () {
-                                       $link.text( mw.msg( 'unwatch' ) );
-                                       mw.notify( mw.msg( 'watcherrortext', title ), { type: 'error' } );
-                               } );
-                       }
-
-                       promise.always( function () {
-                               $link.removeClass( 'mw-watch-link-disabled' );
-                       } );
-
-                       e.preventDefault();
-               } );
-       } );
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.upload.js b/resources/src/mediawiki.special/mediawiki.special.upload.js
deleted file mode 100644 (file)
index 144659a..0000000
+++ /dev/null
@@ -1,654 +0,0 @@
-/**
- * JavaScript for Special:Upload
- *
- * @private
- * @class mw.special.upload
- * @singleton
- */
-
-/* global Uint8Array */
-
-( function ( mw, $ ) {
-       var uploadWarning, uploadTemplatePreview,
-               ajaxUploadDestCheck = mw.config.get( 'wgAjaxUploadDestCheck' ),
-               $license = $( '#wpLicense' );
-
-       window.wgUploadWarningObj = uploadWarning = {
-               responseCache: { '': '&nbsp;' },
-               nameToCheck: '',
-               typing: false,
-               delay: 500, // ms
-               timeoutID: false,
-
-               keypress: function () {
-                       if ( !ajaxUploadDestCheck ) {
-                               return;
-                       }
-
-                       // Find file to upload
-                       if ( !$( '#wpDestFile' ).length || !$( '#wpDestFile-warning' ).length ) {
-                               return;
-                       }
-
-                       this.nameToCheck = $( '#wpDestFile' ).val();
-
-                       // Clear timer
-                       if ( this.timeoutID ) {
-                               clearTimeout( this.timeoutID );
-                       }
-                       // Check response cache
-                       if ( this.responseCache.hasOwnProperty( this.nameToCheck ) ) {
-                               this.setWarning( this.responseCache[ this.nameToCheck ] );
-                               return;
-                       }
-
-                       this.timeoutID = setTimeout( function () {
-                               uploadWarning.timeout();
-                       }, this.delay );
-               },
-
-               checkNow: function ( fname ) {
-                       if ( !ajaxUploadDestCheck ) {
-                               return;
-                       }
-                       if ( this.timeoutID ) {
-                               clearTimeout( this.timeoutID );
-                       }
-                       this.nameToCheck = fname;
-                       this.timeout();
-               },
-
-               timeout: function () {
-                       var $spinnerDestCheck, title;
-                       if ( !ajaxUploadDestCheck || this.nameToCheck.trim() === '' ) {
-                               return;
-                       }
-                       $spinnerDestCheck = $.createSpinner().insertAfter( '#wpDestFile' );
-                       title = mw.Title.newFromText( this.nameToCheck, mw.config.get( 'wgNamespaceIds' ).file );
-
-                       ( new mw.Api() ).get( {
-                               formatversion: 2,
-                               action: 'query',
-                               // If title is empty, user input is invalid, the API call will produce details about why
-                               titles: [ title ? title.getPrefixedText() : this.nameToCheck ],
-                               prop: 'imageinfo',
-                               iiprop: 'uploadwarning',
-                               errorformat: 'html',
-                               errorlang: mw.config.get( 'wgUserLanguage' )
-                       } ).done( function ( result ) {
-                               var
-                                       resultOut = '',
-                                       page = result.query.pages[ 0 ];
-                               if ( page.imageinfo ) {
-                                       resultOut = page.imageinfo[ 0 ].html;
-                               } else if ( page.invalidreason ) {
-                                       resultOut = page.invalidreason.html;
-                               }
-                               uploadWarning.processResult( resultOut, uploadWarning.nameToCheck );
-                       } ).always( function () {
-                               $spinnerDestCheck.remove();
-                       } );
-               },
-
-               processResult: function ( result, fileName ) {
-                       this.setWarning( result );
-                       this.responseCache[ fileName ] = result;
-               },
-
-               setWarning: function ( warning ) {
-                       var $warningBox = $( '#wpDestFile-warning' ),
-                               $warning = $( $.parseHTML( warning ) );
-                       mw.hook( 'wikipage.content' ).fire( $warning );
-                       $warningBox.empty().append( $warning );
-
-                       // Set a value in the form indicating that the warning is acknowledged and
-                       // doesn't need to be redisplayed post-upload
-                       if ( !warning ) {
-                               $( '#wpDestFileWarningAck' ).val( '' );
-                               $warningBox.removeAttr( 'class' );
-                       } else {
-                               $( '#wpDestFileWarningAck' ).val( '1' );
-                               $warningBox.attr( 'class', 'mw-destfile-warning' );
-                       }
-
-               }
-       };
-
-       window.wgUploadTemplatePreviewObj = uploadTemplatePreview = {
-
-               responseCache: { '': '' },
-
-               /**
-                * @param {jQuery} $element The element whose .val() will be previewed
-                * @param {jQuery} $previewContainer The container to display the preview in
-                */
-               getPreview: function ( $element, $previewContainer ) {
-                       var template = $element.val(),
-                               $spinner;
-
-                       if ( this.responseCache.hasOwnProperty( template ) ) {
-                               this.showPreview( this.responseCache[ template ], $previewContainer );
-                               return;
-                       }
-
-                       $spinner = $.createSpinner().insertAfter( $element );
-
-                       ( new mw.Api() ).parse( '{{' + template + '}}', {
-                               title: $( '#wpDestFile' ).val() || 'File:Sample.jpg',
-                               prop: 'text',
-                               pst: true,
-                               uselang: mw.config.get( 'wgUserLanguage' )
-                       } ).done( function ( result ) {
-                               uploadTemplatePreview.processResult( result, template, $previewContainer );
-                       } ).always( function () {
-                               $spinner.remove();
-                       } );
-               },
-
-               processResult: function ( result, template, $previewContainer ) {
-                       this.responseCache[ template ] = result;
-                       this.showPreview( this.responseCache[ template ], $previewContainer );
-               },
-
-               showPreview: function ( preview, $previewContainer ) {
-                       $previewContainer.html( preview );
-               }
-
-       };
-
-       $( function () {
-               // AJAX wpDestFile warnings
-               if ( ajaxUploadDestCheck ) {
-                       // Insert an event handler that fetches upload warnings when wpDestFile
-                       // has been changed
-                       $( '#wpDestFile' ).change( function () {
-                               uploadWarning.checkNow( $( this ).val() );
-                       } );
-                       // Insert a row where the warnings will be displayed just below the
-                       // wpDestFile row
-                       $( '#mw-htmlform-description tbody' ).append(
-                               $( '<tr>' ).append(
-                                       $( '<td>' )
-                                               .attr( 'id', 'wpDestFile-warning' )
-                                               .attr( 'colspan', 2 )
-                               )
-                       );
-               }
-
-               if ( mw.config.get( 'wgAjaxLicensePreview' ) && $license.length ) {
-                       // License selector check
-                       $license.change( function () {
-                               // We might show a preview
-                               uploadTemplatePreview.getPreview( $license, $( '#mw-license-preview' ) );
-                       } );
-
-                       // License selector table row
-                       $license.closest( 'tr' ).after(
-                               $( '<tr>' ).append(
-                                       $( '<td>' ),
-                                       $( '<td>' ).attr( 'id', 'mw-license-preview' )
-                               )
-                       );
-               }
-
-               // fillDestFile setup
-               mw.config.get( 'wgUploadSourceIds' ).forEach( function ( sourceId ) {
-                       $( '#' + sourceId ).change( function () {
-                               var path, slash, backslash, fname;
-                               if ( !mw.config.get( 'wgUploadAutoFill' ) ) {
-                                       return;
-                               }
-                               // Remove any previously flagged errors
-                               $( '#mw-upload-permitted' ).attr( 'class', '' );
-                               $( '#mw-upload-prohibited' ).attr( 'class', '' );
-
-                               path = $( this ).val();
-                               // Find trailing part
-                               slash = path.lastIndexOf( '/' );
-                               backslash = path.lastIndexOf( '\\' );
-                               if ( slash === -1 && backslash === -1 ) {
-                                       fname = path;
-                               } else if ( slash > backslash ) {
-                                       fname = path.slice( slash + 1 );
-                               } else {
-                                       fname = path.slice( backslash + 1 );
-                               }
-
-                               // Clear the filename if it does not have a valid extension.
-                               // URLs are less likely to have a useful extension, so don't include them in the
-                               // extension check.
-                               if (
-                                       mw.config.get( 'wgCheckFileExtensions' ) &&
-                                       mw.config.get( 'wgStrictFileExtensions' ) &&
-                                       Array.isArray( mw.config.get( 'wgFileExtensions' ) ) &&
-                                       $( this ).attr( 'id' ) !== 'wpUploadFileURL'
-                               ) {
-                                       if (
-                                               fname.lastIndexOf( '.' ) === -1 ||
-                                               mw.config.get( 'wgFileExtensions' ).map( function ( element ) {
-                                                       return element.toLowerCase();
-                                               } ).indexOf( fname.slice( fname.lastIndexOf( '.' ) + 1 ).toLowerCase() ) === -1
-                                       ) {
-                                               // Not a valid extension
-                                               // Clear the upload and set mw-upload-permitted to error
-                                               $( this ).val( '' );
-                                               $( '#mw-upload-permitted' ).attr( 'class', 'error' );
-                                               $( '#mw-upload-prohibited' ).attr( 'class', 'error' );
-                                               // Clear wpDestFile as well
-                                               $( '#wpDestFile' ).val( '' );
-
-                                               return false;
-                                       }
-                               }
-
-                               // Replace spaces by underscores
-                               fname = fname.replace( / /g, '_' );
-                               // Capitalise first letter if needed
-                               if ( mw.config.get( 'wgCapitalizeUploads' ) ) {
-                                       fname = fname[ 0 ].toUpperCase() + fname.slice( 1 );
-                               }
-
-                               // Output result
-                               if ( $( '#wpDestFile' ).length ) {
-                                       // Call decodeURIComponent function to remove possible URL-encoded characters
-                                       // from the file name (T32390). Especially likely with upload-form-url.
-                                       // decodeURIComponent can throw an exception if input is invalid utf-8
-                                       try {
-                                               $( '#wpDestFile' ).val( decodeURIComponent( fname ) );
-                                       } catch ( err ) {
-                                               $( '#wpDestFile' ).val( fname );
-                                       }
-                                       uploadWarning.checkNow( fname );
-                               }
-                       } );
-               } );
-       } );
-
-       // Add a preview to the upload form
-       $( function () {
-               /**
-                * Is the FileAPI available with sufficient functionality?
-                *
-                * @return {boolean}
-                */
-               function hasFileAPI() {
-                       return window.FileReader !== undefined;
-               }
-
-               /**
-                * Check if this is a recognizable image type...
-                * Also excludes files over 10M to avoid going insane on memory usage.
-                *
-                * TODO: Is there a way we can ask the browser what's supported in `<img>`s?
-                *
-                * TODO: Put SVG back after working around Firefox 7 bug <https://phabricator.wikimedia.org/T33643>
-                *
-                * @param {File} file
-                * @return {boolean}
-                */
-               function fileIsPreviewable( file ) {
-                       var known = [ 'image/png', 'image/gif', 'image/jpeg', 'image/svg+xml' ],
-                               tooHuge = 10 * 1024 * 1024;
-                       return ( known.indexOf( file.type ) !== -1 ) && file.size > 0 && file.size < tooHuge;
-               }
-
-               /**
-                * Format a file size attractively.
-                *
-                * TODO: Match numeric formatting
-                *
-                * @param {number} s
-                * @return {string}
-                */
-               function prettySize( s ) {
-                       var sizeMsgs = [ 'size-bytes', 'size-kilobytes', 'size-megabytes', 'size-gigabytes' ];
-                       while ( s >= 1024 && sizeMsgs.length > 1 ) {
-                               s /= 1024;
-                               sizeMsgs = sizeMsgs.slice( 1 );
-                       }
-                       return mw.msg( sizeMsgs[ 0 ], Math.round( s ) );
-               }
-
-               /**
-                * Start loading a file into memory; when complete, pass it as a
-                * data URL to the callback function. If the callbackBinary is set it will
-                * first be read as binary and afterwards as data URL. Useful if you want
-                * to do preprocessing on the binary data first.
-                *
-                * @param {File} file
-                * @param {Function} callback
-                * @param {Function} callbackBinary
-                */
-               function fetchPreview( file, callback, callbackBinary ) {
-                       var reader = new FileReader();
-                       if ( callbackBinary && 'readAsBinaryString' in reader ) {
-                               // To fetch JPEG metadata we need a binary string; start there.
-                               // TODO
-                               reader.onload = function () {
-                                       callbackBinary( reader.result );
-
-                                       // Now run back through the regular code path.
-                                       fetchPreview( file, callback );
-                               };
-                               reader.readAsBinaryString( file );
-                       } else if ( callbackBinary && 'readAsArrayBuffer' in reader ) {
-                               // readAsArrayBuffer replaces readAsBinaryString
-                               // However, our JPEG metadata library wants a string.
-                               // So, this is going to be an ugly conversion.
-                               reader.onload = function () {
-                                       var i,
-                                               buffer = new Uint8Array( reader.result ),
-                                               string = '';
-                                       for ( i = 0; i < buffer.byteLength; i++ ) {
-                                               string += String.fromCharCode( buffer[ i ] );
-                                       }
-                                       callbackBinary( string );
-
-                                       // Now run back through the regular code path.
-                                       fetchPreview( file, callback );
-                               };
-                               reader.readAsArrayBuffer( file );
-                       } else if ( 'URL' in window && 'createObjectURL' in window.URL ) {
-                               // Supported in Firefox 4.0 and above <https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL>
-                               // WebKit has it in a namespace for now but that's ok. ;)
-                               //
-                               // Lifetime of this URL is until document close, which is fine
-                               // for Special:Upload -- if this code gets used on longer-running
-                               // pages, add a revokeObjectURL() when it's no longer needed.
-                               //
-                               // Prefer this over readAsDataURL for Firefox 7 due to bug reading
-                               // some SVG files from data URIs <https://bugzilla.mozilla.org/show_bug.cgi?id=694165>
-                               callback( window.URL.createObjectURL( file ) );
-                       } else {
-                               // This ends up decoding the file to base-64 and back again, which
-                               // feels horribly inefficient.
-                               reader.onload = function () {
-                                       callback( reader.result );
-                               };
-                               reader.readAsDataURL( file );
-                       }
-               }
-
-               /**
-                * Clear the file upload preview area.
-                */
-               function clearPreview() {
-                       $( '#mw-upload-thumbnail' ).remove();
-               }
-
-               /**
-                * Show a thumbnail preview of PNG, JPEG, GIF, and SVG files prior to upload
-                * in browsers supporting HTML5 FileAPI.
-                *
-                * As of this writing, known good:
-                *
-                * - Firefox 3.6+
-                * - Chrome 7.something
-                *
-                * TODO: Check file size limits and warn of likely failures
-                *
-                * @param {File} file
-                */
-               function showPreview( file ) {
-                       var $canvas,
-                               ctx,
-                               meta,
-                               previewSize = 180,
-                               $spinner = $.createSpinner( { size: 'small', type: 'block' } )
-                                       .css( { width: previewSize, height: previewSize } ),
-                               thumb = mw.template.get( 'mediawiki.special.upload', 'thumbnail.html' ).render();
-
-                       thumb
-                               .find( '.filename' ).text( file.name ).end()
-                               .find( '.fileinfo' ).text( prettySize( file.size ) ).end()
-                               .find( '.thumbinner' ).prepend( $spinner ).end();
-
-                       $canvas = $( '<canvas>' ).attr( { width: previewSize, height: previewSize } );
-                       ctx = $canvas[ 0 ].getContext( '2d' );
-                       $( '#mw-htmlform-source' ).parent().prepend( thumb );
-
-                       fetchPreview( file, function ( dataURL ) {
-                               var img = new Image(),
-                                       rotation = 0;
-
-                               if ( meta && meta.tiff && meta.tiff.Orientation ) {
-                                       rotation = ( 360 - ( function () {
-                                               // See BitmapHandler class in PHP
-                                               switch ( meta.tiff.Orientation.value ) {
-                                                       case 8:
-                                                               return 90;
-                                                       case 3:
-                                                               return 180;
-                                                       case 6:
-                                                               return 270;
-                                                       default:
-                                                               return 0;
-                                               }
-                                       }() ) ) % 360;
-                               }
-
-                               img.onload = function () {
-                                       var info, width, height, x, y, dx, dy, logicalWidth, logicalHeight;
-
-                                       // Fit the image within the previewSizexpreviewSize box
-                                       if ( img.width > img.height ) {
-                                               width = previewSize;
-                                               height = img.height / img.width * previewSize;
-                                       } else {
-                                               height = previewSize;
-                                               width = img.width / img.height * previewSize;
-                                       }
-                                       // Determine the offset required to center the image
-                                       dx = ( 180 - width ) / 2;
-                                       dy = ( 180 - height ) / 2;
-                                       switch ( rotation ) {
-                                               // If a rotation is applied, the direction of the axis
-                                               // changes as well. You can derive the values below by
-                                               // drawing on paper an axis system, rotate it and see
-                                               // where the positive axis direction is
-                                               case 0:
-                                                       x = dx;
-                                                       y = dy;
-                                                       logicalWidth = img.width;
-                                                       logicalHeight = img.height;
-                                                       break;
-                                               case 90:
-
-                                                       x = dx;
-                                                       y = dy - previewSize;
-                                                       logicalWidth = img.height;
-                                                       logicalHeight = img.width;
-                                                       break;
-                                               case 180:
-                                                       x = dx - previewSize;
-                                                       y = dy - previewSize;
-                                                       logicalWidth = img.width;
-                                                       logicalHeight = img.height;
-                                                       break;
-                                               case 270:
-                                                       x = dx - previewSize;
-                                                       y = dy;
-                                                       logicalWidth = img.height;
-                                                       logicalHeight = img.width;
-                                                       break;
-                                       }
-
-                                       ctx.clearRect( 0, 0, 180, 180 );
-                                       ctx.rotate( rotation / 180 * Math.PI );
-                                       ctx.drawImage( img, x, y, width, height );
-                                       $spinner.replaceWith( $canvas );
-
-                                       // Image size
-                                       info = mw.msg( 'widthheight', logicalWidth, logicalHeight ) +
-                                               ', ' + prettySize( file.size );
-
-                                       $( '#mw-upload-thumbnail .fileinfo' ).text( info );
-                               };
-                               img.onerror = function () {
-                                       // Can happen for example for invalid SVG files
-                                       clearPreview();
-                               };
-                               img.src = dataURL;
-                       }, mw.config.get( 'wgFileCanRotate' ) ? function ( data ) {
-                               var jpegmeta = mw.loader.require( 'mediawiki.libs.jpegmeta' );
-                               try {
-                                       meta = jpegmeta( data, file.fileName );
-                                       // eslint-disable-next-line no-underscore-dangle, camelcase
-                                       meta._binary_data = null;
-                               } catch ( e ) {
-                                       meta = null;
-                               }
-                       } : null );
-               }
-
-               /**
-                * Check if the file does not exceed the maximum size
-                *
-                * @param {File} file
-                * @return {boolean}
-                */
-               function checkMaxUploadSize( file ) {
-                       var maxSize, $error;
-
-                       function getMaxUploadSize( type ) {
-                               var sizes = mw.config.get( 'wgMaxUploadSize' );
-
-                               if ( sizes[ type ] !== undefined ) {
-                                       return sizes[ type ];
-                               }
-                               return sizes[ '*' ];
-                       }
-
-                       $( '.mw-upload-source-error' ).remove();
-
-                       maxSize = getMaxUploadSize( 'file' );
-                       if ( file.size > maxSize ) {
-                               $error = $( '<p class="error mw-upload-source-error" id="wpSourceTypeFile-error">' +
-                                       mw.message( 'largefileserver', file.size, maxSize ).escaped() + '</p>' );
-
-                               $( '#wpUploadFile' ).after( $error );
-
-                               return false;
-                       }
-
-                       return true;
-               }
-
-               /* Initialization */
-               if ( hasFileAPI() ) {
-                       // Update thumbnail when the file selection control is updated.
-                       $( '#wpUploadFile' ).change( function () {
-                               var file;
-                               clearPreview();
-                               if ( this.files && this.files.length ) {
-                                       // Note: would need to be updated to handle multiple files.
-                                       file = this.files[ 0 ];
-
-                                       if ( !checkMaxUploadSize( file ) ) {
-                                               return;
-                                       }
-
-                                       if ( fileIsPreviewable( file ) ) {
-                                               showPreview( file );
-                                       }
-                               }
-                       } );
-               }
-       } );
-
-       // Disable all upload source fields except the selected one
-       $( function () {
-               var $rows = $( '.mw-htmlform-field-UploadSourceField' );
-
-               $rows.on( 'change', 'input[type="radio"]', function ( e ) {
-                       var currentRow = e.delegateTarget;
-
-                       if ( !this.checked ) {
-                               return;
-                       }
-
-                       $( '.mw-upload-source-error' ).remove();
-
-                       // Enable selected upload method
-                       $( currentRow ).find( 'input' ).prop( 'disabled', false );
-
-                       // Disable inputs of other upload methods
-                       // (except for the radio button to re-enable it)
-                       $rows
-                               .not( currentRow )
-                               .find( 'input[type!="radio"]' )
-                               .prop( 'disabled', true );
-               } );
-
-               // Set initial state
-               if ( !$( '#wpSourceTypeurl' ).prop( 'checked' ) ) {
-                       $( '#wpUploadFileURL' ).prop( 'disabled', true );
-               }
-       } );
-
-       $( function () {
-               // Prevent losing work
-               var allowCloseWindow,
-                       $uploadForm = $( '#mw-upload-form' );
-
-               if ( !mw.user.options.get( 'useeditwarning' ) ) {
-                       // If the user doesn't want edit warnings, don't set things up.
-                       return;
-               }
-
-               $uploadForm.data( 'origtext', $uploadForm.serialize() );
-
-               allowCloseWindow = mw.confirmCloseWindow( {
-                       test: function () {
-                               return $( '#wpUploadFile' ).get( 0 ).files.length !== 0 ||
-                                       $uploadForm.data( 'origtext' ) !== $uploadForm.serialize();
-                       },
-
-                       message: mw.msg( 'editwarning-warning' ),
-                       namespace: 'uploadwarning'
-               } );
-
-               $uploadForm.submit( function () {
-                       allowCloseWindow.release();
-               } );
-       } );
-
-       // Add tabindex to mw-editTools
-       $( function () {
-               // Function to change tabindex for all links within mw-editTools
-               function setEditTabindex( $val ) {
-                       $( '.mw-editTools' ).find( 'a' ).each( function () {
-                               $( this ).attr( 'tabindex', $val );
-                       } );
-               }
-
-               // Change tabindex to 0 if user pressed spaced or enter while focused
-               $( '.mw-editTools' ).on( 'keypress', function ( e ) {
-                       // Don't continue if pressed key was not enter or spacebar
-                       if ( e.which !== 13 && e.which !== 32 ) {
-                               return;
-                       }
-
-                       // Change tabindex only when main div has focus
-                       if ( $( this ).is( ':focus' ) ) {
-                               $( this ).find( 'a' ).first().focus();
-                               setEditTabindex( '0' );
-                       }
-               } );
-
-               // Reset tabindex for elements when user focused out mw-editTools
-               $( '.mw-editTools' ).on( 'focusout', function ( e ) {
-                       // Don't continue if relatedTarget is within mw-editTools
-                       if ( e.relatedTarget !== null && $( e.relatedTarget ).closest( '.mw-editTools' ).length > 0 ) {
-                               return;
-                       }
-
-                       // Reset tabindex back to -1
-                       setEditTabindex( '-1' );
-               } );
-
-               // Set initial tabindex for mw-editTools to 0 and to -1 for all links
-               $( '.mw-editTools' ).attr( 'tabindex', '0' );
-               setEditTabindex( '-1' );
-       } );
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.upload.styles.css b/resources/src/mediawiki.special/mediawiki.special.upload.styles.css
deleted file mode 100644 (file)
index 626a7e8..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*!
- * Styling for Special:Upload
- */
-.mw-destfile-warning {
-       border: 1px solid #fde29b;
-       padding: 0.5em 1em;
-       margin-bottom: 1em;
-       color: #705000;
-       background-color: #fdf1d1;
-}
-
-p.mw-upload-editlicenses {
-       font-size: 90%;
-       text-align: right;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.userlogin.common.css b/resources/src/mediawiki.special/mediawiki.special.userlogin.common.css
deleted file mode 100644 (file)
index 2366249..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/* User login and signup forms */
-.mw-ui-vform .mw-form-related-link-container {
-       margin-bottom: 0.5em;
-       text-align: center;
-}
-
-.mw-ui-vform .mw-secure {
-       /* @embed */
-       background: url( images/icon-lock.png ) no-repeat left center;
-       margin: 0 0 0 1px;
-       padding: 0 0 0 11px;
-}
-
-/*
- * When inside the VForm style, disable the border that Vector and other skins
- * put on the div surrounding the login/create account form.
- * Also disable the margin and padding that Vector puts around the form.
- */
-.mw-ui-container #userloginForm,
-.mw-ui-container #userlogin {
-       border: 0;
-       margin: 0;
-       padding: 0;
-}
-
-/* Reposition and resize language links, which appear on a per-wiki basis */
-.mw-ui-container #languagelinks {
-       margin-bottom: 2em;
-       font-size: 0.8em;
-}
-
-/* Put some space under template's header, which may contain CAPTCHA HTML. */
-section.mw-form-header {
-       margin-bottom: 10px;
-}
-
-/* shuffled CAPTCHA */
-#wpCaptchaWord {
-       margin-top: 6px;
-}
-
-.fancycaptcha-captcha-container {
-       background-color: #f8f9fa;
-       margin-bottom: 15px;
-       border: 1px solid #c8ccd1;
-       border-radius: 2px;
-       padding: 8px;
-       text-align: center;
-}
-
-.mw-createacct-captcha-assisted {
-       display: block;
-       margin-top: 0.5em;
-}
-
-/* Put a border around the fancycaptcha-image-container. */
-.fancycaptcha-captcha-and-reload {
-       border: 1px solid #c8ccd1;
-       border-radius: 2px 2px 0 0;
-       /* Other display formats end up too wide */
-       display: table-cell;
-       width: 270px;
-       background-color: #fff;
-}
-
-.fancycaptcha-captcha-container .mw-ui-input {
-       margin-top: -1px;
-       border-color: #c8ccd1;
-       border-radius: 0 0 2px 2px;
-}
-
-/* Make the fancycaptcha-image-container full-width within its parent. */
-.fancycaptcha-image-container {
-       width: 100%;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.userlogin.login.css b/resources/src/mediawiki.special/mediawiki.special.userlogin.login.css
deleted file mode 100644 (file)
index fe013bc..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* The login form invites users to create an account */
-#mw-createaccount-cta {
-       width: 20em;
-       /* @embed */
-       background: url( images/glyph-people-large.png ) no-repeat 50%;
-       margin: 0 auto;
-       padding-top: 7.8em;
-       font-weight: bold;
-}
-
-/* Login Button, following 'ButtonWidget (progressive)' from OOUI */
-#mw-createaccount-join {
-       background-color: #f8f9fa;
-       color: #36c;
-}
-#mw-createaccount-join:hover {
-       background-color: #fff;
-       border-color: #859ecc;
-       box-shadow: none;
-}
-#mw-createaccount-join:active {
-       background-color: #eff3fa;
-       color: #2a4b8d;
-       border-color: #2a4b8d;
-}
-#mw-createaccount-join:focus {
-       border-color: #36c;
-       box-shadow: inset 0 0 0 1px #36c;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.userlogin.signup.css b/resources/src/mediawiki.special/mediawiki.special.userlogin.signup.css
deleted file mode 100644 (file)
index 3cfa5a8..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Disable the underline that Vector puts on h2 headings, and bold them. */
-.mw-ui-container h2 {
-       border: 0;
-       font-weight: bold;
-}
-
-/* Benefits column CSS to the right (if it fits) of the form. */
-.mw-ui-container #userloginForm {
-       float: left;
-       /* Override the right margin of the form to give space in case a benefits
-        * column appears to the side. */
-       margin-right: 100px;
-       /* Override `.mw-body-content` to ensure useful, readable paragraphs */
-       line-height: 1.4;
-}
-
-.mw-createacct-benefits-container {
-       /* Keeps this column compact and close to the form, but tends to squish contents. */
-       float: left;
-}
-
-.mw-createacct-benefits-container h2 {
-       margin-bottom: 30px;
-}
-
-.mw-number-text.icon-edits {
-       /* @embed */
-       background: url( images/icon-edits.png ) no-repeat left center;
-}
-
-.mw-number-text.icon-pages {
-       /* @embed */
-       background: url( images/icon-pages.png ) no-repeat left center;
-}
-
-.mw-number-text.icon-contributors {
-       /* @embed */
-       background: url( images/icon-contributors.png ) no-repeat left center;
-}
-
-/*
- * Special font for numbers in benefits, same as Vector's `@content-heading-font-family`.
- * Needs an ID so that it's more specific than Vector's div#content h3.
- */
-#bodyContent .mw-number-text h3 {
-       color: #222;
-       margin: 0;
-       padding: 0;
-       font-family: 'Linux Libertine', 'Georgia', 'Times', serif;
-       font-weight: normal;
-       font-size: 2.2em;
-       line-height: 1.2;
-       text-align: center;
-}
-
-/* Contains a “headlined” number and explanatory text, with space for an icon */
-.mw-number-text {
-       display: block;
-       font-size: 1.2em;
-       color: #444;
-       margin-top: 1em;
-       /* 80px wide icon plus "margin" */
-       padding: 0 0 0 95px;
-       /* Matches max icon height, ensures icon emblem is visible */
-       min-height: 75px;
-       text-align: center;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.userlogin.signup.js b/resources/src/mediawiki.special/mediawiki.special.userlogin.signup.js
deleted file mode 100644 (file)
index 8a61afb..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*!
- * JavaScript for signup form.
- */
-( function ( mw, $ ) {
-       // When sending password by email, hide the password input fields.
-       $( function () {
-               // Always required if checked, otherwise it depends, so we use the original
-               var $emailLabel = $( 'label[for="wpEmail"]' ),
-                       originalText = $emailLabel.text(),
-                       requiredText = mw.message( 'createacct-emailrequired' ).text(),
-                       $createByMailCheckbox = $( '#wpCreateaccountMail' ),
-                       $beforePwds = $( '.mw-row-password:first' ).prev(),
-                       $pwds;
-
-               function updateForCheckbox() {
-                       var checked = $createByMailCheckbox.prop( 'checked' );
-                       if ( checked ) {
-                               $pwds = $( '.mw-row-password' ).detach();
-                               $emailLabel.text( requiredText );
-                       } else {
-                               if ( $pwds ) {
-                                       $beforePwds.after( $pwds );
-                                       $pwds = null;
-                               }
-                               $emailLabel.text( originalText );
-                       }
-               }
-
-               $createByMailCheckbox.on( 'change', updateForCheckbox );
-               updateForCheckbox();
-       } );
-
-       // Check if the username is invalid or already taken
-       mw.hook( 'htmlform.enhance' ).add( function ( $root ) {
-               var $usernameInput = $root.find( '#wpName2' ),
-                       $passwordInput = $root.find( '#wpPassword2' ),
-                       $emailInput = $root.find( '#wpEmail' ),
-                       $realNameInput = $root.find( '#wpRealName' ),
-                       api = new mw.Api(),
-                       usernameChecker, passwordChecker;
-
-               function checkUsername( username ) {
-                       // We could just use .then() if we didn't have to pass on .abort()…
-                       var d, apiPromise;
-
-                       d = $.Deferred();
-                       apiPromise = api.get( {
-                               action: 'query',
-                               list: 'users',
-                               ususers: username,
-                               usprop: 'cancreate',
-                               formatversion: 2,
-                               errorformat: 'html',
-                               errorsuselocal: true,
-                               uselang: mw.config.get( 'wgUserLanguage' )
-                       } )
-                               .done( function ( resp ) {
-                                       var userinfo = resp.query.users[ 0 ];
-
-                                       if ( resp.query.users.length !== 1 || userinfo.invalid ) {
-                                               d.resolve( { valid: false, messages: [ mw.message( 'noname' ).parseDom() ] } );
-                                       } else if ( userinfo.userid !== undefined ) {
-                                               d.resolve( { valid: false, messages: [ mw.message( 'userexists' ).parseDom() ] } );
-                                       } else if ( !userinfo.cancreate ) {
-                                               d.resolve( {
-                                                       valid: false,
-                                                       messages: userinfo.cancreateerror ? userinfo.cancreateerror.map( function ( m ) {
-                                                               return m.html;
-                                                       } ) : []
-                                               } );
-                                       } else {
-                                               d.resolve( { valid: true, messages: [] } );
-                                       }
-                               } )
-                               .fail( d.reject );
-
-                       return d.promise( { abort: apiPromise.abort } );
-               }
-
-               function checkPassword() {
-                       // We could just use .then() if we didn't have to pass on .abort()…
-                       var apiPromise,
-                               d = $.Deferred();
-
-                       if ( $usernameInput.val().trim() === '' ) {
-                               d.resolve( { valid: true, messages: [] } );
-                               return d.promise();
-                       }
-
-                       apiPromise = api.post( {
-                               action: 'validatepassword',
-                               user: $usernameInput.val(),
-                               password: $passwordInput.val(),
-                               email: $emailInput.val() || '',
-                               realname: $realNameInput.val() || '',
-                               formatversion: 2,
-                               errorformat: 'html',
-                               errorsuselocal: true,
-                               uselang: mw.config.get( 'wgUserLanguage' )
-                       } )
-                               .done( function ( resp ) {
-                                       var pwinfo = resp.validatepassword || {};
-
-                                       d.resolve( {
-                                               valid: pwinfo.validity === 'Good',
-                                               messages: pwinfo.validitymessages ? pwinfo.validitymessages.map( function ( m ) {
-                                                       return m.html;
-                                               } ) : []
-                                       } );
-                               } )
-                               .fail( d.reject );
-
-                       return d.promise( { abort: apiPromise.abort } );
-               }
-
-               usernameChecker = new mw.htmlform.Checker( $usernameInput, checkUsername );
-               usernameChecker.attach();
-
-               passwordChecker = new mw.htmlform.Checker( $passwordInput, checkPassword );
-               passwordChecker.attach( $usernameInput.add( $emailInput ).add( $realNameInput ) );
-       } );
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.userrights.css b/resources/src/mediawiki.special/mediawiki.special.userrights.css
deleted file mode 100644 (file)
index 1ffdf70..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*!
- * Styling for Special:UserRights
- */
-.mw-userrights-nested {
-       margin-left: 1.2em;
-}
-
-.mw-userrights-nested span {
-       margin-left: 0.3em;
-       display: inline-block;
-       vertical-align: middle;
-}
-
-.mw-userrights-disabled {
-       color: #72777d;
-}
-.mw-userrights-groups * td,
-.mw-userrights-groups * th {
-       padding-right: 1.5em;
-}
-
-.mw-userrights-groups * th {
-       text-align: left;
-}
-
-/* Dynamically show/hide the expiry selection underneath each checkbox */
-input.mw-userrights-groupcheckbox:not( :checked ) ~ .mw-userrights-nested {
-       display: none;
-}
-
-/* Initial hide the expiry fields to prevent a FOUC on loading */
-/* The input fields gets unhidden by JavaScript when needed */
-.client-js .mw-userrights-expiryfield {
-       display: none;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.userrights.js b/resources/src/mediawiki.special/mediawiki.special.userrights.js
deleted file mode 100644 (file)
index 487e63a..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*!
- * JavaScript for Special:UserRights
- */
-( function ( mw, $ ) {
-       var convertmessagebox = require( 'mediawiki.notification.convertmessagebox' ),
-               summaryCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
-               summaryByteLimit = mw.config.get( 'wgCommentByteLimit' ),
-               $wpReason = $( '#wpReason' );
-
-       // Replace successbox with notifications
-       convertmessagebox();
-
-       // Dynamically show/hide the "other time" input under each dropdown
-       $( '.mw-userrights-nested select' ).on( 'change', function ( e ) {
-               $( e.target.parentNode ).find( 'input' ).toggle( $( e.target ).val() === 'other' );
-       } );
-
-       // Limit to bytes or UTF-8 codepoints, depending on MediaWiki's configuration
-       if ( summaryCodePointLimit ) {
-               $wpReason.codePointLimit( summaryCodePointLimit );
-       } else if ( summaryByteLimit ) {
-               $wpReason.byteLimit( summaryByteLimit );
-       }
-
-}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.version.css b/resources/src/mediawiki.special/mediawiki.special.version.css
deleted file mode 100644 (file)
index 1b8581a..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*!
- * Styling for Special:Version
- */
-.mw-version-ext-name,
-.mw-version-library-name {
-       font-weight: bold;
-}
-
-.mw-version-ext-license,
-.mw-version-ext-vcs-timestamp {
-       white-space: nowrap;
-}
-
-th.mw-version-ext-col-label {
-       font-size: 0.9em;
-}
-
-.mw-version-ext-vcs-version {
-       unicode-bidi: embed;
-}
-
-.mw-version-credits {
-       column-width: 18em;
-       -moz-column-width: 18em;
-       -webkit-column-width: 18em;
-}
-
-.mw-version-credits ul {
-       margin-top: 0;
-       margin-bottom: 0;
-}
-
-.mw-version-license-info strong {
-       font-weight: normal;
-}
-
-.mw-version-license-info em {
-       font-style: normal;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.watchlist.css b/resources/src/mediawiki.special/mediawiki.special.watchlist.css
deleted file mode 100644 (file)
index c9861c2..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*!
- * Styling for elements generated by JavaScript on Special:Watchlist
- */
-.mw-changelist-line-inner-unwatched {
-       text-decoration: line-through;
-       opacity: 0.5;
-}
-
-span.mw-changeslist-line-prefix {
-       display: inline-block;
-}
-/* This can be either a span or a table cell */
-.mw-changeslist-line-prefix {
-       width: 1.25em;
-}
diff --git a/resources/src/mediawiki.special/mediawiki.special.watchlist.js b/resources/src/mediawiki.special/mediawiki.special.watchlist.js
deleted file mode 100644 (file)
index 565ed2c..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/*!
- * JavaScript for Special:Watchlist
- */
-( function ( mw, $, OO ) {
-       $( function () {
-               var api = new mw.Api(), $progressBar, $resetForm = $( '#mw-watchlist-resetbutton' );
-
-               // If the user wants to reset their watchlist, use an API call to do so (no reload required)
-               // Adapted from a user script by User:NQ of English Wikipedia
-               // (User:NQ/WatchlistResetConfirm.js)
-               $resetForm.submit( function ( event ) {
-                       var $button = $resetForm.find( 'input[name=mw-watchlist-reset-submit]' );
-
-                       event.preventDefault();
-
-                       // Disable reset button to prevent multiple concurrent requests
-                       $button.prop( 'disabled', true );
-
-                       if ( !$progressBar ) {
-                               $progressBar = new OO.ui.ProgressBarWidget( { progress: false } ).$element;
-                               $progressBar.css( {
-                                       position: 'absolute', width: '100%'
-                               } );
-                       }
-                       // Show progress bar
-                       $resetForm.append( $progressBar );
-
-                       // Use action=setnotificationtimestamp to mark all as visited,
-                       // then set all watchlist lines accordingly
-                       api.postWithToken( 'csrf', {
-                               formatversion: 2, action: 'setnotificationtimestamp', entirewatchlist: true
-                       } ).done( function () {
-                               // Enable button again
-                               $button.prop( 'disabled', false );
-                               // Hide the button because further clicks can not generate any visual changes
-                               $button.css( 'visibility', 'hidden' );
-                               $progressBar.detach();
-                               $( '.mw-changeslist-line-watched' )
-                                       .removeClass( 'mw-changeslist-line-watched' )
-                                       .addClass( 'mw-changeslist-line-not-watched' );
-                       } ).fail( function () {
-                               // On error, fall back to server-side reset
-                               // First remove this submit listener and then re-submit the form
-                               $resetForm.off( 'submit' ).submit();
-                       } );
-               } );
-
-               // if the user wishes to reload the watchlist whenever a filter changes
-               if ( mw.user.options.get( 'watchlistreloadautomatically' ) ) {
-                       // add a listener on all form elements in the header form
-                       $( '#mw-watchlist-form input, #mw-watchlist-form select' ).on( 'change', function () {
-                               // submit the form when one of the input fields is modified
-                               $( '#mw-watchlist-form' ).submit();
-                       } );
-               }
-
-               if ( mw.user.options.get( 'watchlistunwatchlinks' ) ) {
-                       // Watch/unwatch toggle link:
-                       // If a page is on the watchlist, a '×' is shown which, when clicked, removes the page from the watchlist.
-                       // After unwatching a page, the '×' becomes a '+', which if clicked re-watches the page.
-                       // Unwatched page entries are struck through and have lowered opacity.
-                       $( '.mw-changeslist' ).on( 'click', '.mw-unwatch-link, .mw-watch-link', function ( event ) {
-                               var $unwatchLink = $( this ), // EnhancedChangesList uses <table> for each row, while OldChangesList uses <li> for each row
-                                       $watchlistLine = $unwatchLink.closest( 'li, table' )
-                                               .find( '[data-target-page]' ),
-                                       pageTitle = $watchlistLine.data( 'targetPage' ),
-                                       isTalk = mw.Title.newFromText( pageTitle ).getNamespaceId() % 2 === 1;
-
-                               // Utility function for looping through each watchlist line that matches
-                               // a certain page or its associated page (e.g. Talk)
-                               function forEachMatchingTitle( title, callback ) {
-
-                                       var titleObj = mw.Title.newFromText( title ),
-                                               pageNamespaceId = titleObj.getNamespaceId(),
-                                               isTalk = pageNamespaceId % 2 === 1,
-                                               associatedTitle = mw.Title.makeTitle( isTalk ? pageNamespaceId - 1 : pageNamespaceId + 1,
-                                                       titleObj.getMainText() ).getPrefixedText();
-                                       $( '.mw-changeslist-line' ).each( function () {
-                                               var $this = $( this ), $row, $unwatchLink;
-
-                                               $this.find( '[data-target-page]' ).each( function () {
-                                                       var $this = $( this ), rowTitle = $this.data( 'targetPage' );
-                                                       if ( rowTitle === title || rowTitle === associatedTitle ) {
-
-                                                               // EnhancedChangesList groups log entries by performer rather than target page. Therefore...
-                                                               // * If using OldChangesList, use the <li>
-                                                               // * If using EnhancedChangesList and $this is part of a grouped log entry, use the <td> sub-entry
-                                                               // * If using EnhancedChangesList and $this is not part of a grouped log entry, use the <table> grouped entry
-                                                               $row =
-                                                                       $this.closest(
-                                                                               'li, table.mw-collapsible.mw-changeslist-log td[data-target-page], table' );
-                                                               $unwatchLink = $row.find( '.mw-unwatch-link, .mw-watch-link' );
-
-                                                               callback( rowTitle, $row, $unwatchLink );
-                                                       }
-                                               } );
-                                       } );
-                               }
-
-                               // Preload the notification module for mw.notify
-                               mw.loader.load( 'mediawiki.notification' );
-
-                               // Depending on whether we are watching or unwatching, for each entry of the page (and its associated page i.e. Talk),
-                               // change the text, tooltip, and non-JS href of the (un)watch button, and update the styling of the watchlist entry.
-                               if ( $unwatchLink.hasClass( 'mw-unwatch-link' ) ) {
-                                       api.unwatch( pageTitle )
-                                               .done( function () {
-                                                       forEachMatchingTitle( pageTitle,
-                                                               function ( rowPageTitle, $row, $rowUnwatchLink ) {
-                                                                       $rowUnwatchLink
-                                                                               .text( mw.msg( 'watchlist-unwatch-undo' ) )
-                                                                               .attr( 'title', mw.msg( 'tooltip-ca-watch' ) )
-                                                                               .attr( 'href',
-                                                                                       mw.util.getUrl( rowPageTitle, { action: 'watch' } ) )
-                                                                               .removeClass( 'mw-unwatch-link loading' )
-                                                                               .addClass( 'mw-watch-link' );
-                                                                       $row.find(
-                                                                               '.mw-changeslist-line-inner, .mw-enhanced-rc-nested' )
-                                                                               .addBack( '.mw-enhanced-rc-nested' ) // For matching log sub-entry
-                                                                               .addClass( 'mw-changelist-line-inner-unwatched' );
-                                                               } );
-
-                                                       mw.notify(
-                                                               mw.message( isTalk ? 'removedwatchtext-talk' : 'removedwatchtext',
-                                                                       pageTitle ), { tag: 'watch-self' } );
-                                               } );
-                               } else {
-                                       api.watch( pageTitle )
-                                               .then( function () {
-                                                       forEachMatchingTitle( pageTitle,
-                                                               function ( rowPageTitle, $row, $rowUnwatchLink ) {
-                                                                       $rowUnwatchLink
-                                                                               .text( mw.msg( 'watchlist-unwatch' ) )
-                                                                               .attr( 'title', mw.msg( 'tooltip-ca-unwatch' ) )
-                                                                               .attr( 'href',
-                                                                                       mw.util.getUrl( rowPageTitle, { action: 'unwatch' } ) )
-                                                                               .removeClass( 'mw-watch-link loading' )
-                                                                               .addClass( 'mw-unwatch-link' );
-                                                                       $row.find( '.mw-changelist-line-inner-unwatched' )
-                                                                               .addBack( '.mw-enhanced-rc-nested' )
-                                                                               .removeClass( 'mw-changelist-line-inner-unwatched' );
-                                                               } );
-
-                                                       mw.notify(
-                                                               mw.message( isTalk ? 'addedwatchtext-talk' : 'addedwatchtext',
-                                                                       pageTitle ), { tag: 'watch-self' } );
-                                               } );
-                               }
-
-                               event.preventDefault();
-                               event.stopPropagation();
-                               $unwatchLink.blur();
-                       } );
-               }
-       } );
-
-}( mediaWiki, jQuery, OO )
-);
diff --git a/resources/src/mediawiki.special/movePage.css b/resources/src/mediawiki.special/movePage.css
new file mode 100644 (file)
index 0000000..9428fed
--- /dev/null
@@ -0,0 +1,7 @@
+/*!
+ * Styles for Special:MovePage
+ */
+
+.movepage-wrapper {
+       width: 50em;
+}
diff --git a/resources/src/mediawiki.special/pagesWithProp.css b/resources/src/mediawiki.special/pagesWithProp.css
new file mode 100644 (file)
index 0000000..7ef75d0
--- /dev/null
@@ -0,0 +1,4 @@
+/* Distinguish actual data from information about it being hidden visually */
+.prop-value-hidden {
+       font-style: italic;
+}
diff --git a/resources/src/mediawiki.special/special.css b/resources/src/mediawiki.special/special.css
new file mode 100644 (file)
index 0000000..0404c45
--- /dev/null
@@ -0,0 +1,141 @@
+/* Special:AllMessages */
+#mw-allmessagestable .allmessages-customised .am_default {
+       background-color: #fcffc4;
+}
+
+#mw-allmessagestable .allmessages-customised:hover .am_default {
+       background-color: #faff90;
+}
+
+#mw-allmessagestable .am_actual {
+       background-color: #e2ffe2;
+}
+
+#mw-allmessagestable .allmessages-customised:hover + .allmessages-customised .am_actual {
+       background-color: #b1ffb1;
+}
+
+/* Common for Special:Allpages and Special:PrefixIndex */
+.mw-allpages-body,
+.mw-prefixindex-body {
+       columns: 22em 3;
+       -moz-columns: 22em 3;
+       -webkit-columns: 22em 3;
+       break-inside: avoid-column;
+       page-break-inside: avoid;
+       -webkit-column-break-inside: avoid;
+}
+
+.mw-allpages-chunk,
+.mw-prefixindex-list {
+       margin-top: 0;
+       margin-bottom: 0;
+}
+
+.allpagesredirect {
+       font-style: italic;
+}
+
+/* Special:Block */
+.mw-ipb-conveniencelinks {
+       font-size: 90%;
+       text-align: right;
+}
+
+.mw-block-hideuser,
+.mw-block-confirm {
+       font-weight: bold;
+}
+
+#mw-input-wpReason .oo-ui-dropdownInputWidget,
+#mw-input-wpReason .oo-ui-textInputWidget {
+       display: block;
+       max-width: 50em;
+}
+
+#mw-input-wpReason .oo-ui-textInputWidget {
+       margin-top: 0.5em;
+}
+
+/* Special:BlockList */
+.mw-blocklist .mw-usertoollinks,
+.mw-blocklist-actions {
+       white-space: nowrap;
+       font-size: 90%;
+}
+
+/* Special:Contributions */
+.mw-uctop {
+       font-weight: bold;
+}
+.mw-contributions-form select {
+       vertical-align: middle;
+}
+
+/* Special:EditWatchlist */
+.watchlistredir {
+       font-style: italic;
+}
+
+/* Special:EmailUser */
+#mw-emailuser-sender,
+#mw-emailuser-recipient {
+       font-weight: bold;
+}
+
+/* Special:FileDuplicateSearch */
+#mw-fileduplicatesearch-icon {
+       float: right;
+}
+
+/* Special:ListGroupRights */
+.mw-listgrouprights-table tr {
+       vertical-align: top;
+}
+.listgrouprights-revoked {
+       text-decoration: line-through;
+}
+
+/* Special:RevisionDelete */
+.mw-revdel-editreasons {
+       font-size: 90%;
+       text-align: right;
+}
+
+/* Special:Specialpages */
+.mw-specialpagerestricted {
+       font-weight: bold;
+}
+
+.mw-specialpages-list {
+       -webkit-columns: 16em 2;
+       -moz-columns: 16em 2;
+       columns: 16em 2;
+}
+
+.mw-specialpages-list ul {
+       margin-top: 0;
+       margin-bottom: 0;
+}
+
+/* Special:Statistics */
+.mw-statistics-numbers {
+       text-align: right;
+}
+
+/* Special:ProtectedPages */
+.mw-protectedpages .mw-usertoollinks,
+.mw-protectedpages-length,
+.mw-protectedpages-actions {
+       white-space: nowrap;
+       font-size: 90%;
+}
+.mw-protectedpages-unknown {
+       color: #72777d;
+       font-size: 90%;
+}
+
+/* Special:PasswordPolicies */
+.mw-passwordpolicies-table tr {
+       vertical-align: top;
+}
diff --git a/resources/src/mediawiki.special/templates/thumbnail.html b/resources/src/mediawiki.special/templates/thumbnail.html
deleted file mode 100644 (file)
index bf0e701..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<div id="mw-upload-thumbnail" class="thumb tright">
-       <div class="thumbinner">
-               <div class="thumbcaption">
-                       <div class="filename"></div>
-                       <div class="fileinfo"></div>
-               </div>
-       </div>
-</div>
diff --git a/resources/src/mediawiki.special/upload.css b/resources/src/mediawiki.special/upload.css
new file mode 100644 (file)
index 0000000..626a7e8
--- /dev/null
@@ -0,0 +1,15 @@
+/*!
+ * Styling for Special:Upload
+ */
+.mw-destfile-warning {
+       border: 1px solid #fde29b;
+       padding: 0.5em 1em;
+       margin-bottom: 1em;
+       color: #705000;
+       background-color: #fdf1d1;
+}
+
+p.mw-upload-editlicenses {
+       font-size: 90%;
+       text-align: right;
+}
diff --git a/resources/src/mediawiki.special/userrights.css b/resources/src/mediawiki.special/userrights.css
new file mode 100644 (file)
index 0000000..1ffdf70
--- /dev/null
@@ -0,0 +1,35 @@
+/*!
+ * Styling for Special:UserRights
+ */
+.mw-userrights-nested {
+       margin-left: 1.2em;
+}
+
+.mw-userrights-nested span {
+       margin-left: 0.3em;
+       display: inline-block;
+       vertical-align: middle;
+}
+
+.mw-userrights-disabled {
+       color: #72777d;
+}
+.mw-userrights-groups * td,
+.mw-userrights-groups * th {
+       padding-right: 1.5em;
+}
+
+.mw-userrights-groups * th {
+       text-align: left;
+}
+
+/* Dynamically show/hide the expiry selection underneath each checkbox */
+input.mw-userrights-groupcheckbox:not( :checked ) ~ .mw-userrights-nested {
+       display: none;
+}
+
+/* Initial hide the expiry fields to prevent a FOUC on loading */
+/* The input fields gets unhidden by JavaScript when needed */
+.client-js .mw-userrights-expiryfield {
+       display: none;
+}
diff --git a/resources/src/mediawiki.special/watchlist.css b/resources/src/mediawiki.special/watchlist.css
new file mode 100644 (file)
index 0000000..c9861c2
--- /dev/null
@@ -0,0 +1,15 @@
+/*!
+ * Styling for elements generated by JavaScript on Special:Watchlist
+ */
+.mw-changelist-line-inner-unwatched {
+       text-decoration: line-through;
+       opacity: 0.5;
+}
+
+span.mw-changeslist-line-prefix {
+       display: inline-block;
+}
+/* This can be either a span or a table cell */
+.mw-changeslist-line-prefix {
+       width: 1.25em;
+}
index 05180fd..17f1fb4 100644 (file)
                                sz = ( spec.size * 1.15 ) + 'ch';
                        } else {
                                // Add a little for padding
-                               sz = ( spec.size * 1.15 ) + 'ch';
+                               sz = ( spec.size * 1.25 ) + 'ch';
                        }
                        if ( spec.editable && spec.type !== 'static' ) {
                                if ( spec.type === 'boolean' || spec.type === 'toggleLocal' ) {
index b1e1da3..2d3f6ad 100644 (file)
@@ -9,7 +9,6 @@
  */
 
 /* global mwNow */
-/* eslint-disable no-use-before-define */
 
 ( function ( $ ) {
        'use strict';
                }() );
        }
 
+       /**
+        * Alias property to the global object.
+        *
+        * @private
+        * @static
+        * @member mw.Map
+        * @param {mw.Map} map
+        * @param {string} key
+        * @param {Mixed} value
+        */
+       function setGlobalMapValue( map, key, value ) {
+               map.values[ key ] = value;
+               log.deprecate(
+                       window,
+                       key,
+                       value,
+                       // Deprecation notice for mw.config globals (T58550, T72470)
+                       map === mw.config && 'Use mw.config instead.'
+               );
+       }
+
        /**
         * Create an object that can be read from or written to via methods that allow
         * interaction both with single and multiple properties at once.
                        // Override #set to also set the global variable
                        this.set = function ( selection, value ) {
                                var s;
-
-                               if ( $.isPlainObject( selection ) ) {
-                                       for ( s in selection ) {
-                                               setGlobalMapValue( this, s, selection[ s ] );
+                               if ( arguments.length > 1 ) {
+                                       if ( typeof selection !== 'string' ) {
+                                               return false;
                                        }
+                                       setGlobalMapValue( this, selection, value );
                                        return true;
                                }
-                               if ( typeof selection === 'string' && arguments.length ) {
-                                       setGlobalMapValue( this, selection, value );
+                               if ( typeof selection === 'object' ) {
+                                       for ( s in selection ) {
+                                               setGlobalMapValue( this, s, selection[ s ] );
+                                       }
                                        return true;
                                }
                                return false;
                }
        }
 
-       /**
-        * Alias property to the global object.
-        *
-        * @private
-        * @static
-        * @param {mw.Map} map
-        * @param {string} key
-        * @param {Mixed} value
-        */
-       function setGlobalMapValue( map, key, value ) {
-               map.values[ key ] = value;
-               log.deprecate(
-                       window,
-                       key,
-                       value,
-                       // Deprecation notice for mw.config globals (T58550, T72470)
-                       map === mw.config && 'Use mw.config instead.'
-               );
-       }
-
        Map.prototype = {
                constructor: Map,
 
                 */
                set: function ( selection, value ) {
                        var s;
-
-                       if ( $.isPlainObject( selection ) ) {
-                               for ( s in selection ) {
-                                       this.values[ s ] = selection[ s ];
+                       // Use `arguments.length` because `undefined` is also a valid value.
+                       if ( arguments.length > 1 ) {
+                               if ( typeof selection !== 'string' ) {
+                                       return false;
                                }
+                               this.values[ selection ] = value;
                                return true;
                        }
-                       if ( typeof selection === 'string' && arguments.length > 1 ) {
-                               this.values[ selection ] = value;
+                       if ( typeof selection === 'object' ) {
+                               for ( s in selection ) {
+                                       this.values[ s ] = selection[ s ];
+                               }
                                return true;
                        }
                        return false;
                                        mw.loader.store.set( module, registry[ module ] );
                                        for ( m in registry ) {
                                                if ( registry[ m ].state === 'loaded' && allReady( registry[ m ].dependencies ) ) {
+                                                       // eslint-disable-next-line no-use-before-define
                                                        execute( m );
                                                }
                                        }
                                }
                        }
 
+                       /**
+                        * @private
+                        * @param {string} code JavaScript code
+                        */
+                       function domEval( code ) {
+                               var script = document.createElement( 'script' );
+                               script.text = code;
+                               document.head.appendChild( script );
+                               script.parentNode.removeChild( script );
+                       }
+
                        /**
                         * Executes a loaded module, making it ready to use
                         *
                                                        // Site and user modules are legacy scripts that run in the global scope.
                                                        // This is transported as a string instead of a function to avoid needing
                                                        // to use string manipulation to undo the function wrapper.
-                                                       $.globalEval( script );
+                                                       domEval( script );
                                                        markModuleReady();
 
                                                } else {
                                }
                                mw.requestIdleCallback( function () {
                                        try {
-                                               $.globalEval( implementations.join( ';' ) );
+                                               domEval( implementations.join( ';' ) );
                                        } catch ( err ) {
                                                cb( err );
                                        }
        mw.trackSubscribe( 'resourceloader.exception', logError );
        mw.trackSubscribe( 'resourceloader.assert', logError );
 
-       /**
-        * Fired when all modules associated with the page have finished loading.
-        *
-        * @event resourceloader_loadEnd
-        * @member mw.hook
-        */
-       $( function () {
-               var loading, modules;
-
-               modules = mw.loader.getModuleNames().filter( function ( module ) {
-                       return mw.loader.getState( module ) === 'loading';
-               } );
-               // We only need a callback, not any actual module. First try a single using()
-               // for all loading modules. If one fails, fall back to tracking each module
-               // separately via $.when(), this is expensive.
-               loading = mw.loader.using( modules ).catch( function () {
-                       var all = modules.map( function ( module ) {
-                               return mw.loader.using( module ).catch( function () {
-                                       return $.Deferred().resolve();
-                               } );
-                       } );
-                       return $.when.apply( $, all );
-               } );
-               loading.then( function () {
-                       if ( window.performance && performance.mark ) {
-                               performance.mark( 'mwLoadEnd' );
-                       }
-                       mw.hook( 'resourceloader.loadEnd' ).fire();
-               } );
-       } );
-
        // Attach to window and globally alias
        window.mw = window.mediaWiki = mw;
 }( jQuery ) );
index d9d58dd..33b9f02 100644 (file)
@@ -1,4 +1,3 @@
-/UnicodeData.txt
 /allkeys.txt
 /ucd.all.grouped.xml
 /ucd.all.grouped.zip
index 45aed88..09369ef 100644 (file)
@@ -1,4 +1,4 @@
-SPECIAL_TARGETS=normalize-ar.ser normalize-ml.ser first-letters-root.ser
+SPECIAL_TARGETS=first-letters-root.ser
 ALL_TARGETS=$(SPECIAL_TARGETS)
 DIST_TARGETS=$(SPECIAL_TARGETS)
 UNICODE_VERSION=6.0.0
@@ -13,23 +13,14 @@ dist: $(DIST_TARGETS)
 clean:
        rm -f $(ALL_TARGETS)
 
-normalize-ar.ser: UnicodeData.txt
-       php ../maintenance/language/generateNormalizerDataAr.php
-
-normalize-ml.ser:
-       php ../maintenance/language/generateNormalizerDataMl.php
-
 first-letters-root.ser: allkeys.txt ucd.all.grouped.xml
        php ../maintenance/language/generateCollationData.php
 
-UnicodeData.txt:
-       wget http://www.unicode.org/Public/$(UNICODE_VERSION)/ucd/UnicodeData.txt
-
 allkeys.txt:
-       wget http://www.unicode.org/Public/UCA/$(UNICODE_VERSION)/allkeys.txt
+       wget https://www.unicode.org/Public/UCA/$(UNICODE_VERSION)/allkeys.txt
 
 ucd.all.grouped.xml: ucd.all.grouped.zip
        unzip ucd.all.grouped.zip ucd.all.grouped.xml
 
 ucd.all.grouped.zip:
-       wget http://www.unicode.org/Public/$(UNICODE_VERSION)/ucdxml/ucd.all.grouped.zip
+       wget https://www.unicode.org/Public/$(UNICODE_VERSION)/ucdxml/ucd.all.grouped.zip
diff --git a/serialized/normalize-ar.ser b/serialized/normalize-ar.ser
deleted file mode 100644 (file)
index 2a7f122..0000000
+++ /dev/null
@@ -1 +0,0 @@
-a:731:{s:3:"ﭐ";s:2:"ٱ";s:3:"ﭑ";s:2:"ٱ";s:3:"ﭒ";s:2:"ٻ";s:3:"ﭓ";s:2:"ٻ";s:3:"ﭔ";s:2:"ٻ";s:3:"ﭕ";s:2:"ٻ";s:3:"ﭖ";s:2:"پ";s:3:"ﭗ";s:2:"پ";s:3:"ﭘ";s:2:"پ";s:3:"ﭙ";s:2:"پ";s:3:"ﭚ";s:2:"ڀ";s:3:"ﭛ";s:2:"ڀ";s:3:"ﭜ";s:2:"ڀ";s:3:"ﭝ";s:2:"ڀ";s:3:"ﭞ";s:2:"ٺ";s:3:"ﭟ";s:2:"ٺ";s:3:"ﭠ";s:2:"ٺ";s:3:"ﭡ";s:2:"ٺ";s:3:"ﭢ";s:2:"ٿ";s:3:"ﭣ";s:2:"ٿ";s:3:"ﭤ";s:2:"ٿ";s:3:"ﭥ";s:2:"ٿ";s:3:"ﭦ";s:2:"ٹ";s:3:"ﭧ";s:2:"ٹ";s:3:"ﭨ";s:2:"ٹ";s:3:"ﭩ";s:2:"ٹ";s:3:"ﭪ";s:2:"ڤ";s:3:"ﭫ";s:2:"ڤ";s:3:"ﭬ";s:2:"ڤ";s:3:"ﭭ";s:2:"ڤ";s:3:"ﭮ";s:2:"ڦ";s:3:"ﭯ";s:2:"ڦ";s:3:"ﭰ";s:2:"ڦ";s:3:"ﭱ";s:2:"ڦ";s:3:"ﭲ";s:2:"ڄ";s:3:"ﭳ";s:2:"ڄ";s:3:"ﭴ";s:2:"ڄ";s:3:"ﭵ";s:2:"ڄ";s:3:"ﭶ";s:2:"ڃ";s:3:"ﭷ";s:2:"ڃ";s:3:"ﭸ";s:2:"ڃ";s:3:"ﭹ";s:2:"ڃ";s:3:"ﭺ";s:2:"چ";s:3:"ﭻ";s:2:"چ";s:3:"ﭼ";s:2:"چ";s:3:"ﭽ";s:2:"چ";s:3:"ﭾ";s:2:"ڇ";s:3:"ﭿ";s:2:"ڇ";s:3:"ﮀ";s:2:"ڇ";s:3:"ﮁ";s:2:"ڇ";s:3:"ﮂ";s:2:"ڍ";s:3:"ﮃ";s:2:"ڍ";s:3:"ﮄ";s:2:"ڌ";s:3:"ﮅ";s:2:"ڌ";s:3:"ﮆ";s:2:"ڎ";s:3:"ﮇ";s:2:"ڎ";s:3:"ﮈ";s:2:"ڈ";s:3:"ﮉ";s:2:"ڈ";s:3:"ﮊ";s:2:"ژ";s:3:"ﮋ";s:2:"ژ";s:3:"ﮌ";s:2:"ڑ";s:3:"ﮍ";s:2:"ڑ";s:3:"ﮎ";s:2:"ک";s:3:"ﮏ";s:2:"ک";s:3:"ﮐ";s:2:"ک";s:3:"ﮑ";s:2:"ک";s:3:"ﮒ";s:2:"گ";s:3:"ﮓ";s:2:"گ";s:3:"ﮔ";s:2:"گ";s:3:"ﮕ";s:2:"گ";s:3:"ﮖ";s:2:"ڳ";s:3:"ﮗ";s:2:"ڳ";s:3:"ﮘ";s:2:"ڳ";s:3:"ﮙ";s:2:"ڳ";s:3:"ﮚ";s:2:"ڱ";s:3:"ﮛ";s:2:"ڱ";s:3:"ﮜ";s:2:"ڱ";s:3:"ﮝ";s:2:"ڱ";s:3:"ﮞ";s:2:"ں";s:3:"ﮟ";s:2:"ں";s:3:"ﮠ";s:2:"ڻ";s:3:"ﮡ";s:2:"ڻ";s:3:"ﮢ";s:2:"ڻ";s:3:"ﮣ";s:2:"ڻ";s:3:"ﮤ";s:2:"ۀ";s:3:"ﮥ";s:2:"ۀ";s:3:"ﮦ";s:2:"ہ";s:3:"ﮧ";s:2:"ہ";s:3:"ﮨ";s:2:"ہ";s:3:"ﮩ";s:2:"ہ";s:3:"ﮪ";s:2:"ھ";s:3:"ﮫ";s:2:"ھ";s:3:"ﮬ";s:2:"ھ";s:3:"ﮭ";s:2:"ھ";s:3:"ﮮ";s:2:"ے";s:3:"ﮯ";s:2:"ے";s:3:"ﮰ";s:2:"ۓ";s:3:"ﮱ";s:2:"ۓ";s:3:"ﯓ";s:2:"ڭ";s:3:"ﯔ";s:2:"ڭ";s:3:"ﯕ";s:2:"ڭ";s:3:"ﯖ";s:2:"ڭ";s:3:"ﯗ";s:2:"ۇ";s:3:"ﯘ";s:2:"ۇ";s:3:"ﯙ";s:2:"ۆ";s:3:"ﯚ";s:2:"ۆ";s:3:"ﯛ";s:2:"ۈ";s:3:"ﯜ";s:2:"ۈ";s:3:"ﯝ";s:2:"ٷ";s:3:"ﯞ";s:2:"ۋ";s:3:"ﯟ";s:2:"ۋ";s:3:"ﯠ";s:2:"ۅ";s:3:"ﯡ";s:2:"ۅ";s:3:"ﯢ";s:2:"ۉ";s:3:"ﯣ";s:2:"ۉ";s:3:"ﯤ";s:2:"ې";s:3:"ﯥ";s:2:"ې";s:3:"ﯦ";s:2:"ې";s:3:"ﯧ";s:2:"ې";s:3:"ﯨ";s:2:"ى";s:3:"ﯩ";s:2:"ى";s:3:"ﯪ";s:4:"ئا";s:3:"ﯫ";s:4:"ئا";s:3:"ﯬ";s:4:"ئە";s:3:"ﯭ";s:4:"ئە";s:3:"ﯮ";s:4:"ئو";s:3:"ﯯ";s:4:"ئو";s:3:"ﯰ";s:4:"ئۇ";s:3:"ﯱ";s:4:"ئۇ";s:3:"ﯲ";s:4:"ئۆ";s:3:"ﯳ";s:4:"ئۆ";s:3:"ﯴ";s:4:"ئۈ";s:3:"ﯵ";s:4:"ئۈ";s:3:"ﯶ";s:4:"ئې";s:3:"ﯷ";s:4:"ئې";s:3:"ﯸ";s:4:"ئې";s:3:"ﯹ";s:4:"ئى";s:3:"ﯺ";s:4:"ئى";s:3:"ﯻ";s:4:"ئى";s:3:"ﯼ";s:2:"ی";s:3:"ﯽ";s:2:"ی";s:3:"ﯾ";s:2:"ی";s:3:"ﯿ";s:2:"ی";s:3:"ﰀ";s:4:"ئج";s:3:"ﰁ";s:4:"ئح";s:3:"ﰂ";s:4:"ئم";s:3:"ﰃ";s:4:"ئى";s:3:"ﰄ";s:4:"ئي";s:3:"ﰅ";s:4:"بج";s:3:"ﰆ";s:4:"بح";s:3:"ﰇ";s:4:"بخ";s:3:"ﰈ";s:4:"بم";s:3:"ﰉ";s:4:"بى";s:3:"ﰊ";s:4:"بي";s:3:"ﰋ";s:4:"تج";s:3:"ﰌ";s:4:"تح";s:3:"ﰍ";s:4:"تخ";s:3:"ﰎ";s:4:"تم";s:3:"ﰏ";s:4:"تى";s:3:"ﰐ";s:4:"تي";s:3:"ﰑ";s:4:"ثج";s:3:"ﰒ";s:4:"ثم";s:3:"ﰓ";s:4:"ثى";s:3:"ﰔ";s:4:"ثي";s:3:"ﰕ";s:4:"جح";s:3:"ﰖ";s:4:"جم";s:3:"ﰗ";s:4:"حج";s:3:"ﰘ";s:4:"حم";s:3:"ﰙ";s:4:"خج";s:3:"ﰚ";s:4:"خح";s:3:"ﰛ";s:4:"خم";s:3:"ﰜ";s:4:"سج";s:3:"ﰝ";s:4:"سح";s:3:"ﰞ";s:4:"سخ";s:3:"ﰟ";s:4:"سم";s:3:"ﰠ";s:4:"صح";s:3:"ﰡ";s:4:"صم";s:3:"ﰢ";s:4:"ضج";s:3:"ﰣ";s:4:"ضح";s:3:"ﰤ";s:4:"ضخ";s:3:"ﰥ";s:4:"ضم";s:3:"ﰦ";s:4:"طح";s:3:"ﰧ";s:4:"طم";s:3:"ﰨ";s:4:"ظم";s:3:"ﰩ";s:4:"عج";s:3:"ﰪ";s:4:"عم";s:3:"ﰫ";s:4:"غج";s:3:"ﰬ";s:4:"غم";s:3:"ﰭ";s:4:"فج";s:3:"ﰮ";s:4:"فح";s:3:"ﰯ";s:4:"فخ";s:3:"ﰰ";s:4:"فم";s:3:"ﰱ";s:4:"فى";s:3:"ﰲ";s:4:"في";s:3:"ﰳ";s:4:"قح";s:3:"ﰴ";s:4:"قم";s:3:"ﰵ";s:4:"قى";s:3:"ﰶ";s:4:"قي";s:3:"ﰷ";s:4:"كا";s:3:"ﰸ";s:4:"كج";s:3:"ﰹ";s:4:"كح";s:3:"ﰺ";s:4:"كخ";s:3:"ﰻ";s:4:"كل";s:3:"ﰼ";s:4:"كم";s:3:"ﰽ";s:4:"كى";s:3:"ﰾ";s:4:"كي";s:3:"ﰿ";s:4:"لج";s:3:"ﱀ";s:4:"لح";s:3:"ﱁ";s:4:"لخ";s:3:"ﱂ";s:4:"لم";s:3:"ﱃ";s:4:"لى";s:3:"ﱄ";s:4:"لي";s:3:"ﱅ";s:4:"مج";s:3:"ﱆ";s:4:"مح";s:3:"ﱇ";s:4:"مخ";s:3:"ﱈ";s:4:"مم";s:3:"ﱉ";s:4:"مى";s:3:"ﱊ";s:4:"مي";s:3:"ﱋ";s:4:"نج";s:3:"ﱌ";s:4:"نح";s:3:"ﱍ";s:4:"نخ";s:3:"ﱎ";s:4:"نم";s:3:"ﱏ";s:4:"نى";s:3:"ﱐ";s:4:"ني";s:3:"ﱑ";s:4:"هج";s:3:"ﱒ";s:4:"هم";s:3:"ﱓ";s:4:"هى";s:3:"ﱔ";s:4:"هي";s:3:"ﱕ";s:4:"يج";s:3:"ﱖ";s:4:"يح";s:3:"ﱗ";s:4:"يخ";s:3:"ﱘ";s:4:"يم";s:3:"ﱙ";s:4:"يى";s:3:"ﱚ";s:4:"يي";s:3:"ﱛ";s:4:"ذٰ";s:3:"ﱜ";s:4:"رٰ";s:3:"ﱝ";s:4:"ىٰ";s:3:"ﱞ";s:5:" ٌّ";s:3:"ﱟ";s:5:" ٍّ";s:3:"ﱠ";s:5:" َّ";s:3:"ﱡ";s:5:" ُّ";s:3:"ﱢ";s:5:" ِّ";s:3:"ﱣ";s:5:" ّٰ";s:3:"ﱤ";s:4:"ئر";s:3:"ﱥ";s:4:"ئز";s:3:"ﱦ";s:4:"ئم";s:3:"ﱧ";s:4:"ئن";s:3:"ﱨ";s:4:"ئى";s:3:"ﱩ";s:4:"ئي";s:3:"ﱪ";s:4:"بر";s:3:"ﱫ";s:4:"بز";s:3:"ﱬ";s:4:"بم";s:3:"ﱭ";s:4:"بن";s:3:"ﱮ";s:4:"بى";s:3:"ﱯ";s:4:"بي";s:3:"ﱰ";s:4:"تر";s:3:"ﱱ";s:4:"تز";s:3:"ﱲ";s:4:"تم";s:3:"ﱳ";s:4:"تن";s:3:"ﱴ";s:4:"تى";s:3:"ﱵ";s:4:"تي";s:3:"ﱶ";s:4:"ثر";s:3:"ﱷ";s:4:"ثز";s:3:"ﱸ";s:4:"ثم";s:3:"ﱹ";s:4:"ثن";s:3:"ﱺ";s:4:"ثى";s:3:"ﱻ";s:4:"ثي";s:3:"ﱼ";s:4:"فى";s:3:"ﱽ";s:4:"في";s:3:"ﱾ";s:4:"قى";s:3:"ﱿ";s:4:"قي";s:3:"ﲀ";s:4:"كا";s:3:"ﲁ";s:4:"كل";s:3:"ﲂ";s:4:"كم";s:3:"ﲃ";s:4:"كى";s:3:"ﲄ";s:4:"كي";s:3:"ﲅ";s:4:"لم";s:3:"ﲆ";s:4:"لى";s:3:"ﲇ";s:4:"لي";s:3:"ﲈ";s:4:"ما";s:3:"ﲉ";s:4:"مم";s:3:"ﲊ";s:4:"نر";s:3:"ﲋ";s:4:"نز";s:3:"ﲌ";s:4:"نم";s:3:"ﲍ";s:4:"نن";s:3:"ﲎ";s:4:"نى";s:3:"ﲏ";s:4:"ني";s:3:"ﲐ";s:4:"ىٰ";s:3:"ﲑ";s:4:"ير";s:3:"ﲒ";s:4:"يز";s:3:"ﲓ";s:4:"يم";s:3:"ﲔ";s:4:"ين";s:3:"ﲕ";s:4:"يى";s:3:"ﲖ";s:4:"يي";s:3:"ﲗ";s:4:"ئج";s:3:"ﲘ";s:4:"ئح";s:3:"ﲙ";s:4:"ئخ";s:3:"ﲚ";s:4:"ئم";s:3:"ﲛ";s:4:"ئه";s:3:"ﲜ";s:4:"بج";s:3:"ﲝ";s:4:"بح";s:3:"ﲞ";s:4:"بخ";s:3:"ﲟ";s:4:"بم";s:3:"ﲠ";s:4:"به";s:3:"ﲡ";s:4:"تج";s:3:"ﲢ";s:4:"تح";s:3:"ﲣ";s:4:"تخ";s:3:"ﲤ";s:4:"تم";s:3:"ﲥ";s:4:"ته";s:3:"ﲦ";s:4:"ثم";s:3:"ﲧ";s:4:"جح";s:3:"ﲨ";s:4:"جم";s:3:"ﲩ";s:4:"حج";s:3:"ﲪ";s:4:"حم";s:3:"ﲫ";s:4:"خج";s:3:"ﲬ";s:4:"خم";s:3:"ﲭ";s:4:"سج";s:3:"ﲮ";s:4:"سح";s:3:"ﲯ";s:4:"سخ";s:3:"ﲰ";s:4:"سم";s:3:"ﲱ";s:4:"صح";s:3:"ﲲ";s:4:"صخ";s:3:"ﲳ";s:4:"صم";s:3:"ﲴ";s:4:"ضج";s:3:"ﲵ";s:4:"ضح";s:3:"ﲶ";s:4:"ضخ";s:3:"ﲷ";s:4:"ضم";s:3:"ﲸ";s:4:"طح";s:3:"ﲹ";s:4:"ظم";s:3:"ﲺ";s:4:"عج";s:3:"ﲻ";s:4:"عم";s:3:"ﲼ";s:4:"غج";s:3:"ﲽ";s:4:"غم";s:3:"ﲾ";s:4:"فج";s:3:"ﲿ";s:4:"فح";s:3:"ﳀ";s:4:"فخ";s:3:"ﳁ";s:4:"فم";s:3:"ﳂ";s:4:"قح";s:3:"ﳃ";s:4:"قم";s:3:"ﳄ";s:4:"كج";s:3:"ﳅ";s:4:"كح";s:3:"ﳆ";s:4:"كخ";s:3:"ﳇ";s:4:"كل";s:3:"ﳈ";s:4:"كم";s:3:"ﳉ";s:4:"لج";s:3:"ﳊ";s:4:"لح";s:3:"ﳋ";s:4:"لخ";s:3:"ﳌ";s:4:"لم";s:3:"ﳍ";s:4:"له";s:3:"ﳎ";s:4:"مج";s:3:"ﳏ";s:4:"مح";s:3:"ﳐ";s:4:"مخ";s:3:"ﳑ";s:4:"مم";s:3:"ﳒ";s:4:"نج";s:3:"ﳓ";s:4:"نح";s:3:"ﳔ";s:4:"نخ";s:3:"ﳕ";s:4:"نم";s:3:"ﳖ";s:4:"نه";s:3:"ﳗ";s:4:"هج";s:3:"ﳘ";s:4:"هم";s:3:"ﳙ";s:4:"هٰ";s:3:"ﳚ";s:4:"يج";s:3:"ﳛ";s:4:"يح";s:3:"ﳜ";s:4:"يخ";s:3:"ﳝ";s:4:"يم";s:3:"ﳞ";s:4:"يه";s:3:"ﳟ";s:4:"ئم";s:3:"ﳠ";s:4:"ئه";s:3:"ﳡ";s:4:"بم";s:3:"ﳢ";s:4:"به";s:3:"ﳣ";s:4:"تم";s:3:"ﳤ";s:4:"ته";s:3:"ﳥ";s:4:"ثم";s:3:"ﳦ";s:4:"ثه";s:3:"ﳧ";s:4:"سم";s:3:"ﳨ";s:4:"سه";s:3:"ﳩ";s:4:"شم";s:3:"ﳪ";s:4:"شه";s:3:"ﳫ";s:4:"كل";s:3:"ﳬ";s:4:"كم";s:3:"ﳭ";s:4:"لم";s:3:"ﳮ";s:4:"نم";s:3:"ﳯ";s:4:"نه";s:3:"ﳰ";s:4:"يم";s:3:"ﳱ";s:4:"يه";s:3:"ﳲ";s:6:"ـَّ";s:3:"ﳳ";s:6:"ـُّ";s:3:"ﳴ";s:6:"ـِّ";s:3:"ﳵ";s:4:"طى";s:3:"ﳶ";s:4:"طي";s:3:"ﳷ";s:4:"عى";s:3:"ﳸ";s:4:"عي";s:3:"ﳹ";s:4:"غى";s:3:"ﳺ";s:4:"غي";s:3:"ﳻ";s:4:"سى";s:3:"ﳼ";s:4:"سي";s:3:"ﳽ";s:4:"شى";s:3:"ﳾ";s:4:"شي";s:3:"ﳿ";s:4:"حى";s:3:"ﴀ";s:4:"حي";s:3:"ﴁ";s:4:"جى";s:3:"ﴂ";s:4:"جي";s:3:"ﴃ";s:4:"خى";s:3:"ﴄ";s:4:"خي";s:3:"ﴅ";s:4:"صى";s:3:"ﴆ";s:4:"صي";s:3:"ﴇ";s:4:"ضى";s:3:"ﴈ";s:4:"ضي";s:3:"ﴉ";s:4:"شج";s:3:"ﴊ";s:4:"شح";s:3:"ﴋ";s:4:"شخ";s:3:"ﴌ";s:4:"شم";s:3:"ﴍ";s:4:"شر";s:3:"ﴎ";s:4:"سر";s:3:"ﴏ";s:4:"صر";s:3:"ﴐ";s:4:"ضر";s:3:"ﴑ";s:4:"طى";s:3:"ﴒ";s:4:"طي";s:3:"ﴓ";s:4:"عى";s:3:"ﴔ";s:4:"عي";s:3:"ﴕ";s:4:"غى";s:3:"ﴖ";s:4:"غي";s:3:"ﴗ";s:4:"سى";s:3:"ﴘ";s:4:"سي";s:3:"ﴙ";s:4:"شى";s:3:"ﴚ";s:4:"شي";s:3:"ﴛ";s:4:"حى";s:3:"ﴜ";s:4:"حي";s:3:"ﴝ";s:4:"جى";s:3:"ﴞ";s:4:"جي";s:3:"ﴟ";s:4:"خى";s:3:"ﴠ";s:4:"خي";s:3:"ﴡ";s:4:"صى";s:3:"ﴢ";s:4:"صي";s:3:"ﴣ";s:4:"ضى";s:3:"ﴤ";s:4:"ضي";s:3:"ﴥ";s:4:"شج";s:3:"ﴦ";s:4:"شح";s:3:"ﴧ";s:4:"شخ";s:3:"ﴨ";s:4:"شم";s:3:"ﴩ";s:4:"شر";s:3:"ﴪ";s:4:"سر";s:3:"ﴫ";s:4:"صر";s:3:"ﴬ";s:4:"ضر";s:3:"ﴭ";s:4:"شج";s:3:"ﴮ";s:4:"شح";s:3:"ﴯ";s:4:"شخ";s:3:"ﴰ";s:4:"شم";s:3:"ﴱ";s:4:"سه";s:3:"ﴲ";s:4:"شه";s:3:"ﴳ";s:4:"طم";s:3:"ﴴ";s:4:"سج";s:3:"ﴵ";s:4:"سح";s:3:"ﴶ";s:4:"سخ";s:3:"ﴷ";s:4:"شج";s:3:"ﴸ";s:4:"شح";s:3:"ﴹ";s:4:"شخ";s:3:"ﴺ";s:4:"طم";s:3:"ﴻ";s:4:"ظم";s:3:"ﴼ";s:4:"اً";s:3:"ﴽ";s:4:"اً";s:3:"ﵐ";s:6:"تجم";s:3:"ﵑ";s:6:"تحج";s:3:"ﵒ";s:6:"تحج";s:3:"ﵓ";s:6:"تحم";s:3:"ﵔ";s:6:"تخم";s:3:"ﵕ";s:6:"تمج";s:3:"ﵖ";s:6:"تمح";s:3:"ﵗ";s:6:"تمخ";s:3:"ﵘ";s:6:"جمح";s:3:"ﵙ";s:6:"جمح";s:3:"ﵚ";s:6:"حمي";s:3:"ﵛ";s:6:"حمى";s:3:"ﵜ";s:6:"سحج";s:3:"ﵝ";s:6:"سجح";s:3:"ﵞ";s:6:"سجى";s:3:"ﵟ";s:6:"سمح";s:3:"ﵠ";s:6:"سمح";s:3:"ﵡ";s:6:"سمج";s:3:"ﵢ";s:6:"سمم";s:3:"ﵣ";s:6:"سمم";s:3:"ﵤ";s:6:"صحح";s:3:"ﵥ";s:6:"صحح";s:3:"ﵦ";s:6:"صمم";s:3:"ﵧ";s:6:"شحم";s:3:"ﵨ";s:6:"شحم";s:3:"ﵩ";s:6:"شجي";s:3:"ﵪ";s:6:"شمخ";s:3:"ﵫ";s:6:"شمخ";s:3:"ﵬ";s:6:"شمم";s:3:"ﵭ";s:6:"شمم";s:3:"ﵮ";s:6:"ضحى";s:3:"ﵯ";s:6:"ضخم";s:3:"ﵰ";s:6:"ضخم";s:3:"ﵱ";s:6:"طمح";s:3:"ﵲ";s:6:"طمح";s:3:"ﵳ";s:6:"طمم";s:3:"ﵴ";s:6:"طمي";s:3:"ﵵ";s:6:"عجم";s:3:"ﵶ";s:6:"عمم";s:3:"ﵷ";s:6:"عمم";s:3:"ﵸ";s:6:"عمى";s:3:"ﵹ";s:6:"غمم";s:3:"ﵺ";s:6:"غمي";s:3:"ﵻ";s:6:"غمى";s:3:"ﵼ";s:6:"فخم";s:3:"ﵽ";s:6:"فخم";s:3:"ﵾ";s:6:"قمح";s:3:"ﵿ";s:6:"قمم";s:3:"ﶀ";s:6:"لحم";s:3:"ﶁ";s:6:"لحي";s:3:"ﶂ";s:6:"لحى";s:3:"ﶃ";s:6:"لجج";s:3:"ﶄ";s:6:"لجج";s:3:"ﶅ";s:6:"لخم";s:3:"ﶆ";s:6:"لخم";s:3:"ﶇ";s:6:"لمح";s:3:"ﶈ";s:6:"لمح";s:3:"ﶉ";s:6:"محج";s:3:"ﶊ";s:6:"محم";s:3:"ﶋ";s:6:"محي";s:3:"ﶌ";s:6:"مجح";s:3:"ﶍ";s:6:"مجم";s:3:"ﶎ";s:6:"مخج";s:3:"ﶏ";s:6:"مخم";s:3:"ﶒ";s:6:"مجخ";s:3:"ﶓ";s:6:"همج";s:3:"ﶔ";s:6:"همم";s:3:"ﶕ";s:6:"نحم";s:3:"ﶖ";s:6:"نحى";s:3:"ﶗ";s:6:"نجم";s:3:"ﶘ";s:6:"نجم";s:3:"ﶙ";s:6:"نجى";s:3:"ﶚ";s:6:"نمي";s:3:"ﶛ";s:6:"نمى";s:3:"ﶜ";s:6:"يمم";s:3:"ﶝ";s:6:"يمم";s:3:"ﶞ";s:6:"بخي";s:3:"ﶟ";s:6:"تجي";s:3:"ﶠ";s:6:"تجى";s:3:"ﶡ";s:6:"تخي";s:3:"ﶢ";s:6:"تخى";s:3:"ﶣ";s:6:"تمي";s:3:"ﶤ";s:6:"تمى";s:3:"ﶥ";s:6:"جمي";s:3:"ﶦ";s:6:"جحى";s:3:"ﶧ";s:6:"جمى";s:3:"ﶨ";s:6:"سخى";s:3:"ﶩ";s:6:"صحي";s:3:"ﶪ";s:6:"شحي";s:3:"ﶫ";s:6:"ضحي";s:3:"ﶬ";s:6:"لجي";s:3:"ﶭ";s:6:"لمي";s:3:"ﶮ";s:6:"يحي";s:3:"ﶯ";s:6:"يجي";s:3:"ﶰ";s:6:"يمي";s:3:"ﶱ";s:6:"ممي";s:3:"ﶲ";s:6:"قمي";s:3:"ﶳ";s:6:"نحي";s:3:"ﶴ";s:6:"قمح";s:3:"ﶵ";s:6:"لحم";s:3:"ﶶ";s:6:"عمي";s:3:"ﶷ";s:6:"كمي";s:3:"ﶸ";s:6:"نجح";s:3:"ﶹ";s:6:"مخي";s:3:"ﶺ";s:6:"لجم";s:3:"ﶻ";s:6:"كمم";s:3:"ﶼ";s:6:"لجم";s:3:"ﶽ";s:6:"نجح";s:3:"ﶾ";s:6:"جحي";s:3:"ﶿ";s:6:"حجي";s:3:"ﷀ";s:6:"مجي";s:3:"ﷁ";s:6:"فمي";s:3:"ﷂ";s:6:"بحي";s:3:"ﷃ";s:6:"كمم";s:3:"ﷄ";s:6:"عجم";s:3:"ﷅ";s:6:"صمم";s:3:"ﷆ";s:6:"سخي";s:3:"ﷇ";s:6:"نجي";s:3:"ﷰ";s:6:"صلے";s:3:"ﷱ";s:6:"قلے";s:3:"ﷲ";s:8:"الله";s:3:"ﷳ";s:8:"اكبر";s:3:"ﷴ";s:8:"محمد";s:3:"ﷵ";s:8:"صلعم";s:3:"ﷶ";s:8:"رسول";s:3:"ﷷ";s:8:"عليه";s:3:"ﷸ";s:8:"وسلم";s:3:"ﷹ";s:6:"صلى";s:3:"ﷺ";s:33:"صلى الله عليه وسلم";s:3:"ﷻ";s:15:"جل جلاله";s:3:"﷼";s:8:"ریال";s:3:"ﹰ";s:3:" ً";s:3:"ﹱ";s:4:"ـً";s:3:"ﹲ";s:3:" ٌ";s:3:"ﹴ";s:3:" ٍ";s:3:"ﹶ";s:3:" َ";s:3:"ﹷ";s:4:"ـَ";s:3:"ﹸ";s:3:" ُ";s:3:"ﹹ";s:4:"ـُ";s:3:"ﹺ";s:3:" ِ";s:3:"ﹻ";s:4:"ـِ";s:3:"ﹼ";s:3:" ّ";s:3:"ﹽ";s:4:"ـّ";s:3:"ﹾ";s:3:" ْ";s:3:"ﹿ";s:4:"ـْ";s:3:"ﺀ";s:2:"ء";s:3:"ﺁ";s:2:"آ";s:3:"ﺂ";s:2:"آ";s:3:"ﺃ";s:2:"أ";s:3:"ﺄ";s:2:"أ";s:3:"ﺅ";s:2:"ؤ";s:3:"ﺆ";s:2:"ؤ";s:3:"ﺇ";s:2:"إ";s:3:"ﺈ";s:2:"إ";s:3:"ﺉ";s:2:"ئ";s:3:"ﺊ";s:2:"ئ";s:3:"ﺋ";s:2:"ئ";s:3:"ﺌ";s:2:"ئ";s:3:"ﺍ";s:2:"ا";s:3:"ﺎ";s:2:"ا";s:3:"ﺏ";s:2:"ب";s:3:"ﺐ";s:2:"ب";s:3:"ﺑ";s:2:"ب";s:3:"ﺒ";s:2:"ب";s:3:"ﺓ";s:2:"ة";s:3:"ﺔ";s:2:"ة";s:3:"ﺕ";s:2:"ت";s:3:"ﺖ";s:2:"ت";s:3:"ﺗ";s:2:"ت";s:3:"ﺘ";s:2:"ت";s:3:"ﺙ";s:2:"ث";s:3:"ﺚ";s:2:"ث";s:3:"ﺛ";s:2:"ث";s:3:"ﺜ";s:2:"ث";s:3:"ﺝ";s:2:"ج";s:3:"ﺞ";s:2:"ج";s:3:"ﺟ";s:2:"ج";s:3:"ﺠ";s:2:"ج";s:3:"ﺡ";s:2:"ح";s:3:"ﺢ";s:2:"ح";s:3:"ﺣ";s:2:"ح";s:3:"ﺤ";s:2:"ح";s:3:"ﺥ";s:2:"خ";s:3:"ﺦ";s:2:"خ";s:3:"ﺧ";s:2:"خ";s:3:"ﺨ";s:2:"خ";s:3:"ﺩ";s:2:"د";s:3:"ﺪ";s:2:"د";s:3:"ﺫ";s:2:"ذ";s:3:"ﺬ";s:2:"ذ";s:3:"ﺭ";s:2:"ر";s:3:"ﺮ";s:2:"ر";s:3:"ﺯ";s:2:"ز";s:3:"ﺰ";s:2:"ز";s:3:"ﺱ";s:2:"س";s:3:"ﺲ";s:2:"س";s:3:"ﺳ";s:2:"س";s:3:"ﺴ";s:2:"س";s:3:"ﺵ";s:2:"ش";s:3:"ﺶ";s:2:"ش";s:3:"ﺷ";s:2:"ش";s:3:"ﺸ";s:2:"ش";s:3:"ﺹ";s:2:"ص";s:3:"ﺺ";s:2:"ص";s:3:"ﺻ";s:2:"ص";s:3:"ﺼ";s:2:"ص";s:3:"ﺽ";s:2:"ض";s:3:"ﺾ";s:2:"ض";s:3:"ﺿ";s:2:"ض";s:3:"ﻀ";s:2:"ض";s:3:"ﻁ";s:2:"ط";s:3:"ﻂ";s:2:"ط";s:3:"ﻃ";s:2:"ط";s:3:"ﻄ";s:2:"ط";s:3:"ﻅ";s:2:"ظ";s:3:"ﻆ";s:2:"ظ";s:3:"ﻇ";s:2:"ظ";s:3:"ﻈ";s:2:"ظ";s:3:"ﻉ";s:2:"ع";s:3:"ﻊ";s:2:"ع";s:3:"ﻋ";s:2:"ع";s:3:"ﻌ";s:2:"ع";s:3:"ﻍ";s:2:"غ";s:3:"ﻎ";s:2:"غ";s:3:"ﻏ";s:2:"غ";s:3:"ﻐ";s:2:"غ";s:3:"ﻑ";s:2:"ف";s:3:"ﻒ";s:2:"ف";s:3:"ﻓ";s:2:"ف";s:3:"ﻔ";s:2:"ف";s:3:"ﻕ";s:2:"ق";s:3:"ﻖ";s:2:"ق";s:3:"ﻗ";s:2:"ق";s:3:"ﻘ";s:2:"ق";s:3:"ﻙ";s:2:"ك";s:3:"ﻚ";s:2:"ك";s:3:"ﻛ";s:2:"ك";s:3:"ﻜ";s:2:"ك";s:3:"ﻝ";s:2:"ل";s:3:"ﻞ";s:2:"ل";s:3:"ﻟ";s:2:"ل";s:3:"ﻠ";s:2:"ل";s:3:"ﻡ";s:2:"م";s:3:"ﻢ";s:2:"م";s:3:"ﻣ";s:2:"م";s:3:"ﻤ";s:2:"م";s:3:"ﻥ";s:2:"ن";s:3:"ﻦ";s:2:"ن";s:3:"ﻧ";s:2:"ن";s:3:"ﻨ";s:2:"ن";s:3:"ﻩ";s:2:"ه";s:3:"ﻪ";s:2:"ه";s:3:"ﻫ";s:2:"ه";s:3:"ﻬ";s:2:"ه";s:3:"ﻭ";s:2:"و";s:3:"ﻮ";s:2:"و";s:3:"ﻯ";s:2:"ى";s:3:"ﻰ";s:2:"ى";s:3:"ﻱ";s:2:"ي";s:3:"ﻲ";s:2:"ي";s:3:"ﻳ";s:2:"ي";s:3:"ﻴ";s:2:"ي";s:3:"ﻵ";s:4:"لآ";s:3:"ﻶ";s:4:"لآ";s:3:"ﻷ";s:4:"لأ";s:3:"ﻸ";s:4:"لأ";s:3:"ﻹ";s:4:"لإ";s:3:"ﻺ";s:4:"لإ";s:3:"ﻻ";s:4:"لا";s:3:"ﻼ";s:4:"لا";}
\ No newline at end of file
diff --git a/serialized/normalize-ml.ser b/serialized/normalize-ml.ser
deleted file mode 100644 (file)
index b27a217..0000000
+++ /dev/null
@@ -1 +0,0 @@
-a:6:{s:9:"ണ്‍";s:3:"ൺ";s:9:"ന്‍";s:3:"ൻ";s:9:"ര്‍";s:3:"ർ";s:9:"ല്‍";s:3:"ൽ";s:9:"ള്‍";s:3:"ൾ";s:9:"ക്‍";s:3:"ൿ";}
\ No newline at end of file
index 08ec9f6..ce1dae6 100644 (file)
@@ -829,6 +829,13 @@ class ParserTestRunner {
                        $titleText = 'Parser test';
                }
 
+               if ( isset( $opts['maxincludesize'] ) ) {
+                       $options->setMaxIncludeSize( $opts['maxincludesize'] );
+               }
+               if ( isset( $opts['maxtemplatedepth'] ) ) {
+                       $options->setMaxTemplateDepth( $opts['maxtemplatedepth'] );
+               }
+
                $local = isset( $opts['local'] );
                $preprocessor = isset( $opts['preprocessor'] ) ? $opts['preprocessor'] : null;
                $parser = $this->getParser( $preprocessor );
@@ -1083,6 +1090,11 @@ class ParserTestRunner {
                        'wgFragmentMode' => [ 'legacy' ],
                ];
 
+               $nonIncludable = self::getOptionValue( 'wgNonincludableNamespaces', $opts, false );
+               if ( $nonIncludable !== false ) {
+                       $setup['wgNonincludableNamespaces'] = [ $nonIncludable ];
+               }
+
                if ( $config ) {
                        $configLines = explode( "\n", $config );
 
index 05afefa..216d7e5 100644 (file)
@@ -62,6 +62,12 @@ Template:Foo
 FOO
 !!endarticle
 
+!! article
+Template:redirect to foo
+!! text
+#REDIRECT [[Template:Foo]]
+!! endarticle
+
 !! article
 Template:Blank
 !! text
@@ -109,6 +115,14 @@ Template:echo
 {{{1}}}
 !! endarticle
 
+!! article
+Template:echo3
+!! text
+{{{1}}}
+{{{1}}}
+{{{1}}}
+!! endarticle
+
 // For Serbian; localize Template namespace
 !! article
 Шаблон:Echo
@@ -128,6 +142,12 @@ Template:echo_with_div
 <div>{{{1}}}</div>
 !! endarticle
 
+!! article
+Template:echo with depth
+!! text
+{{echo|{{{1}}}}}
+!! endarticle
+
 !! article
 Template:blank_param
 !! text
@@ -1825,6 +1845,39 @@ b
 </p>
 !! end
 
+!! test
+post-expand include size being exceeded
+!! options
+maxincludesize=20
+!! wikitext
+{{echo3|1234567890}}
+!! html
+<p><a href="/wiki/Template:Echo3" title="Template:Echo3">Template:Echo3</a><!-- WARNING: template omitted, post-expand include size too large -->
+</p>
+!! end
+
+!! test
+max template depth being reached
+!! options
+maxtemplatedepth=1
+!! wikitext
+{{echo with depth|too deep!}}
+!! html
+<p><span class="error">Template recursion depth limit exceeded (1)</span>
+</p>
+!! end
+
+!! test
+multiple templates that are redirects
+!! wikitext
+{{redirect to foo}}
+{{redirect to foo}}
+!! html
+<p>FOO
+FOO
+</p>
+!! end
+
 !! test
 Multiple comments should still parse as SOL-transparent
 !! options
@@ -11504,6 +11557,17 @@ Template from main namespace
 </p>
 !! end
 
+!! test
+Template from non-includable namespace
+!! options
+wgNonincludableNamespaces=10
+!! wikitext
+{{echo|uh oh!}}
+!! html
+<p><a href="/wiki/Template:Echo" title="Template:Echo">Template:Echo</a>
+</p>
+!! end
+
 !! article
 Template:table
 !! text
@@ -28805,7 +28869,7 @@ foo {{echo|<span>bar</span> [[Category:baz]]}} bar
 # of the categories in wikitext
 # Do not remove these characters in edits.
 #
-# As part of the serialization, these bidi characters will get stripped.
+# As part of the serialization, these Unicode directional formatting characters will get stripped.
 !! test
 RTL (\u200f) and LTR (\u200e) markers around category tags should be stripped
 !! options
@@ -30811,3 +30875,27 @@ header
 *foo
 footer
 !! end
+
+!! test
+Check soft hyphens as entities (&shy;) in displaytitle (T66528)
+!! options
+showtitle
+title=[[Lopadotemachoselachogaleokranioleipsanodrimhypotrimmatosilphioparaomelitokatakechymenokichlepikossyphophattoperisteralektryonoptekephalliokigklopeleiolagoiosiraiobaphetraganopterygon]]
+!! wikitext
+{{DISPLAYTITLE:Lopado&shy;temacho&shy;selacho&shy;galeo&shy;kranio&shy;leipsano&shy;drim&shy;hypo&shy;trimmato&shy;silphio&shy;parao&shy;melito&shy;katakechy&shy;meno&shy;kichl&shy;epi&shy;kossypho&shy;phatto&shy;perister&shy;alektryon&shy;opte&shy;kephallio&shy;kigklo&shy;peleio&shy;lagoio&shy;siraio&shy;baphe&shy;tragano&shy;pterygon}}
+!! html/php
+Lopado&#173;temacho&#173;selacho&#173;galeo&#173;kranio&#173;leipsano&#173;drim&#173;hypo&#173;trimmato&#173;silphio&#173;parao&#173;melito&#173;katakechy&#173;meno&#173;kichl&#173;epi&#173;kossypho&#173;phatto&#173;perister&#173;alektryon&#173;opte&#173;kephallio&#173;kigklo&#173;peleio&#173;lagoio&#173;siraio&#173;baphe&#173;tragano&#173;pterygon
+
+!! end
+
+!! test
+Check soft hyphens as Unicode characters (U+00AD) in displaytitle (T66528)
+!! options
+showtitle
+title=[[Lopadotemachoselachogaleokranioleipsanodrimhypotrimmatosilphioparaomelitokatakechymenokichlepikossyphophattoperisteralektryonoptekephalliokigklopeleiolagoiosiraiobaphetraganopterygon]]
+!! wikitext
+{{DISPLAYTITLE:Lopado­temacho­selacho­galeo­kranio­leipsano­drim­hypo­trimmato­silphio­parao­melito­katakechy­meno­kichl­epi­kossypho­phatto­perister­alektryon­opte­kephallio­kigklo­peleio­lagoio­siraio­baphe­tragano­pterygon}}
+!! html/php
+Lopado­temacho­selacho­galeo­kranio­leipsano­drim­hypo­trimmato­silphio­parao­melito­katakechy­meno­kichl­epi­kossypho­phatto­perister­alektryon­opte­kephallio­kigklo­peleio­lagoio­siraio­baphe­tragano­pterygon
+
+!! end
index 5ea72b2..bd0461a 100644 (file)
@@ -317,8 +317,6 @@ return [
                "PhanParamSignatureRealMismatchTooFewParameters",
                // approximate error count: 125
                "PhanParamTooMany",
-               // approximate error count: 1
-               "PhanParamTooManyCallable",
                // approximate error count: 3
                "PhanParamTooManyInternal",
                // approximate error count: 1
@@ -329,10 +327,6 @@ return [
                "PhanTypeComparisonFromArray",
                // approximate error count: 2
                "PhanTypeComparisonToArray",
-               // approximate error count: 3
-               "PhanTypeInvalidRightOperand",
-               // approximate error count: 1
-               "PhanTypeMagicVoidWithReturn",
                // approximate error count: 218
                "PhanTypeMismatchArgument",
                // approximate error count: 13
@@ -341,8 +335,6 @@ return [
                "PhanTypeMismatchDeclaredParam",
                // approximate error count: 111
                "PhanTypeMismatchDeclaredParamNullable",
-               // approximate error count: 1
-               "PhanTypeMismatchDefault",
                // approximate error count: 5
                "PhanTypeMismatchDimAssignment",
                // approximate error count: 2
@@ -355,12 +347,8 @@ return [
                "PhanTypeMismatchProperty",
                // approximate error count: 74
                "PhanTypeMismatchReturn",
-               // approximate error count: 11
-               "PhanTypeMissingReturn",
                // approximate error count: 5
                "PhanTypeNonVarPassByRef",
-               // approximate error count: 1
-               "PhanUndeclaredClassInCallable",
                // approximate error count: 32
                "PhanUndeclaredConstant",
                // approximate error count: 233
@@ -369,10 +357,6 @@ return [
                "PhanUndeclaredProperty",
                // approximate error count: 3
                "PhanUndeclaredStaticMethod",
-               // approximate error count: 11
-               "PhanUndeclaredTypeReturnType",
-               // approximate error count: 27
-               "PhanUndeclaredVariable",
                // approximate error count: 58
                "PhanUndeclaredVariableDim",
        ],
index d5c14a2..f0c78ec 100644 (file)
@@ -31,12 +31,14 @@ abstract class ResourceLoaderTestCase extends MediaWikiTestCase {
                        'skin' => 'vector',
                        'modules' => 'startup',
                        'only' => 'scripts',
+                       'safemode' => null,
                ];
                $resourceLoader = $rl ?: new ResourceLoader();
                $request = new FauxRequest( [
                                'lang' => $options['lang'],
                                'modules' => $options['modules'],
                                'only' => $options['only'],
+                               'safemode' => $options['safemode'],
                                'skin' => $options['skin'],
                                'target' => 'phpunit',
                ] );
diff --git a/tests/phpunit/data/autoloader/psr4/TestFooBar.php b/tests/phpunit/data/autoloader/psr4/TestFooBar.php
new file mode 100644 (file)
index 0000000..4a2e11f
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+
+namespace Test\MediaWiki\AutoLoader;
+
+class TestFooBar {
+}
diff --git a/tests/phpunit/data/categoriesrdf/change.sparql b/tests/phpunit/data/categoriesrdf/change.sparql
new file mode 100644 (file)
index 0000000..d7ec83a
--- /dev/null
@@ -0,0 +1,16 @@
+# Changes
+DELETE {
+?category ?x ?y
+} INSERT {
+
+<http://acme.test/wiki/Category:Changed_category> a mediawiki:Category ;
+       rdfs:label "Changed category" ;
+       mediawiki:pages "7"^^xsd:integer ;
+       mediawiki:subcategories "2"^^xsd:integer ;
+       mediawiki:isInCategory <http://acme.test/wiki/Category:Parent_of_30> .
+
+} WHERE {
+   VALUES ?category {
+     <http://acme.test/wiki/Category:Changed_category>
+   }
+};
diff --git a/tests/phpunit/data/categoriesrdf/delete.sparql b/tests/phpunit/data/categoriesrdf/delete.sparql
new file mode 100644 (file)
index 0000000..7fb642d
--- /dev/null
@@ -0,0 +1,10 @@
+# Deletes
+DELETE {
+?category ?x ?y
+} INSERT {
+
+} WHERE {
+   VALUES ?category {
+     <http://acme.test/wiki/Category:Test> <http://acme.test/wiki/Category:Test_2>
+   }
+};
diff --git a/tests/phpunit/data/categoriesrdf/move.sparql b/tests/phpunit/data/categoriesrdf/move.sparql
new file mode 100644 (file)
index 0000000..c9f284e
--- /dev/null
@@ -0,0 +1,24 @@
+# Moves
+DELETE {
+?category ?x ?y
+} INSERT {
+
+<http://acme.test/wiki/Category:MovedTo> a mediawiki:Category ;
+       rdfs:label "MovedTo" ;
+       mediawiki:pages "7"^^xsd:integer ;
+       mediawiki:subcategories "2"^^xsd:integer .
+
+<http://acme.test/wiki/Category:AlsoMoved> a mediawiki:Category ;
+       rdfs:label "AlsoMoved" ;
+       mediawiki:pages "7"^^xsd:integer ;
+       mediawiki:subcategories "2"^^xsd:integer .
+
+<http://acme.test/wiki/Category:MovedTo> mediawiki:isInCategory <http://acme.test/wiki/Category:Parent_of_4> .
+
+<http://acme.test/wiki/Category:AlsoMoved> mediawiki:isInCategory <http://acme.test/wiki/Category:Parent_of_5> .
+
+} WHERE {
+   VALUES ?category {
+     <http://acme.test/wiki/Category:Test> <http://acme.test/wiki/Category:MovedTo> <http://acme.test/wiki/Category:Test_2> <http://acme.test/wiki/Category:Test_3> <http://acme.test/wiki/Category:Test_4>
+   }
+};
diff --git a/tests/phpunit/data/categoriesrdf/new.sparql b/tests/phpunit/data/categoriesrdf/new.sparql
new file mode 100644 (file)
index 0000000..f9a742d
--- /dev/null
@@ -0,0 +1,19 @@
+# Additions
+INSERT DATA {
+
+<http://acme.test/wiki/Category:New_category> a mediawiki:Category ;
+       rdfs:label "New category" ;
+       mediawiki:pages "7"^^xsd:integer ;
+       mediawiki:subcategories "2"^^xsd:integer .
+
+<http://acme.test/wiki/Category:%D0%9D%D0%BE%D0%B2%D0%B0%D1%8F_%D0%BA%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F_%F0%9F%98%83> a mediawiki:Category,
+               mediawiki:HiddenCategory ;
+       rdfs:label "Новая категория 😃" ;
+       mediawiki:pages "7"^^xsd:integer ;
+       mediawiki:subcategories "2"^^xsd:integer .
+
+<http://acme.test/wiki/Category:New_category> mediawiki:isInCategory <http://acme.test/wiki/Category:Parent_of_20> .
+
+<http://acme.test/wiki/Category:%D0%9D%D0%BE%D0%B2%D0%B0%D1%8F_%D0%BA%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F_%F0%9F%98%83> mediawiki:isInCategory <http://acme.test/wiki/Category:Parent_of_21> .
+
+};
diff --git a/tests/phpunit/data/categoriesrdf/restore.sparql b/tests/phpunit/data/categoriesrdf/restore.sparql
new file mode 100644 (file)
index 0000000..16c0561
--- /dev/null
@@ -0,0 +1,10 @@
+# Restores
+INSERT DATA {
+
+<http://acme.test/wiki/Category:Restored_cat> a mediawiki:Category ;
+       rdfs:label "Restored cat" ;
+       mediawiki:pages "7"^^xsd:integer ;
+       mediawiki:subcategories "2"^^xsd:integer ;
+       mediawiki:isInCategory <http://acme.test/wiki/Category:Parent_of_10> .
+
+};
diff --git a/tests/phpunit/data/categoriesrdf/updatets.txt b/tests/phpunit/data/categoriesrdf/updatets.txt
new file mode 100644 (file)
index 0000000..426bb92
--- /dev/null
@@ -0,0 +1,9 @@
+DELETE {
+  <http://acme.test/wiki/Special:CategoryDump> schema:dateModified ?o .
+}
+WHERE {
+  <http://acme.test/wiki/Special:CategoryDump> schema:dateModified ?o .
+};
+INSERT DATA {
+  <http://acme.test/wiki/Special:CategoryDump> schema:dateModified "2017-08-25T00:29:09Z"^^xsd:dateTime .
+}
index c7725a2..110e00b 100644 (file)
@@ -1,3 +1,3 @@
-@import "test.common.mixins";
+@import "../common/test.common.mixins";
 
 @unitTestColor: green;
diff --git a/tests/phpunit/data/less/module/use-import-dir.less b/tests/phpunit/data/less/module/use-import-dir.less
new file mode 100644 (file)
index 0000000..4710bc6
--- /dev/null
@@ -0,0 +1,6 @@
+@import "test.common.mixins";
+
+/* @noflip */
+.unit-tests {
+       .test-mixin(green);
+}
diff --git a/tests/phpunit/data/registration/bad_url.json b/tests/phpunit/data/registration/bad_url.json
new file mode 100644 (file)
index 0000000..ee0f4b9
--- /dev/null
@@ -0,0 +1,5 @@
+{
+       "name": "Test",
+       "url": "http://www.mediawiki.org/",
+       "manifest_version": 1
+}
diff --git a/tests/phpunit/data/registration/bad_url2.json b/tests/phpunit/data/registration/bad_url2.json
new file mode 100644 (file)
index 0000000..813e9d6
--- /dev/null
@@ -0,0 +1,5 @@
+{
+       "name": "Test",
+       "url": "http://mediawiki.org/",
+       "manifest_version": 1
+}
index ad16c5e..cfad069 100644 (file)
@@ -1,4 +1,12 @@
 {
        "name": "FooBar",
-       "manifest_version": 1
+       "attributes": {
+               "FooBar": {
+                       "Attr": [ "test" ]
+               },
+               "NotLoaded": {
+                       "Attr": [ "test2" ]
+               }
+       },
+       "manifest_version": 2
 }
diff --git a/tests/phpunit/includes/AutoLoaderTest.php b/tests/phpunit/includes/AutoLoaderTest.php
new file mode 100644 (file)
index 0000000..af6911d
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+
+/**
+ * @covers AutoLoader
+ */
+class AutoLoaderTest extends MediaWikiTestCase {
+
+       private $oldPsr4;
+
+       protected function setUp() {
+               parent::setUp();
+
+               // Fancy dance to trigger a rebuild of AutoLoader::$autoloadLocalClassesLower
+               $this->mergeMwGlobalArrayValue( 'wgAutoloadLocalClasses', [
+                       'TestAutoloadedLocalClass' =>
+                               __DIR__ . '/../data/autoloader/TestAutoloadedLocalClass.php',
+                       'TestAutoloadedCamlClass' =>
+                               __DIR__ . '/../data/autoloader/TestAutoloadedCamlClass.php',
+                       'TestAutoloadedSerializedClass' =>
+                               __DIR__ . '/../data/autoloader/TestAutoloadedSerializedClass.php',
+               ] );
+               AutoLoader::resetAutoloadLocalClassesLower();
+
+               $this->mergeMwGlobalArrayValue( 'wgAutoloadClasses', [
+                       'TestAutoloadedClass' => __DIR__ . '/../data/autoloader/TestAutoloadedClass.php',
+               ] );
+
+               $this->oldPsr4 = AutoLoader::$psr4Namespaces;
+               AutoLoader::$psr4Namespaces['Test\\MediaWiki\\AutoLoader\\'] =
+                       __DIR__ . '/../data/autoloader/psr4';
+       }
+
+       protected function tearDown() {
+               AutoLoader::$psr4Namespaces = $this->oldPsr4;
+               parent::tearDown();
+       }
+
+       public function testCoreClass() {
+               $this->assertTrue( class_exists( 'TestAutoloadedLocalClass' ) );
+       }
+
+       public function testExtensionClass() {
+               $this->assertTrue( class_exists( 'TestAutoloadedClass' ) );
+       }
+
+       public function testWrongCaseClass() {
+               $this->setMwGlobals( 'wgAutoloadAttemptLowercase', true );
+
+               $this->assertTrue( class_exists( 'testautoLoadedcamlCLASS' ) );
+       }
+
+       public function testWrongCaseSerializedClass() {
+               $this->setMwGlobals( 'wgAutoloadAttemptLowercase', true );
+
+               $dummyCereal = 'O:29:"testautoloadedserializedclass":0:{}';
+               $uncerealized = unserialize( $dummyCereal );
+               $this->assertFalse( $uncerealized instanceof __PHP_Incomplete_Class,
+                       "unserialize() can load classes case-insensitively." );
+       }
+
+       public function testPsr4() {
+               $this->assertTrue( class_exists( 'Test\\MediaWiki\\AutoLoader\\TestFooBar' ) );
+       }
+}
diff --git a/tests/phpunit/includes/ContentSecurityPolicyTest.php b/tests/phpunit/includes/ContentSecurityPolicyTest.php
new file mode 100644 (file)
index 0000000..3f24030
--- /dev/null
@@ -0,0 +1,310 @@
+<?php
+
+use Wikimedia\TestingAccessWrapper;
+
+class ContentSecurityPolicyTest extends MediaWikiTestCase {
+       /** @var ContentSecurityPolicy */
+       private $csp;
+
+       protected function setUp() {
+               global $wgUploadDirectory;
+               $this->setMwGlobals( [
+                       'wgAllowExternalImages' => false,
+                       'wgAllowExternalImagesFrom' => [],
+                       'wgAllowImageTag' => false,
+                       'wgEnableImageWhitelist' => false,
+                       'wgCrossSiteAJAXdomains' => [
+                               'sister-site.somewhere.com',
+                               '*.wikipedia.org',
+                               '??.wikinews.org'
+                       ],
+                       'wgScriptPath' => '/w',
+                       'wgForeignFileRepos' => [ [
+                               'class' => ForeignAPIRepo::class,
+                               'name' => 'wikimediacommons',
+                               'apibase' => 'https://commons.wikimedia.org/w/api.php',
+                               'url' => 'https://upload.wikimedia.org/wikipedia/commons',
+                               'thumbUrl' => 'https://upload.wikimedia.org/wikipedia/commons/thumb',
+                               'hashLevels' => 2,
+                               'transformVia404' => true,
+                               'fetchDescription' => true,
+                               'descriptionCacheExpiry' => 43200,
+                               'apiThumbCacheExpiry' => 0,
+                               'directory' => $wgUploadDirectory,
+                               'backend' => 'wikimediacommons-backend',
+                       ] ],
+               ] );
+               // Note, there are some obscure globals which
+               // could affect the results which aren't included above.
+
+               RepoGroup::destroySingleton();
+               $context = RequestContext::getMain();
+               $resp = $context->getRequest()->response();
+               $conf = $context->getConfig();
+               $csp = new ContentSecurityPolicy( 'secret', $resp, $conf );
+               $this->csp = TestingAccessWrapper::newFromObject( $csp );
+
+               return parent::setUp();
+       }
+
+       /**
+        * @dataProvider providerFalsePositiveBrowser
+        * @covers ContentSecurityPolicy::falsePositiveBrowser
+        */
+       public function testFalsePositiveBrowser( $ua, $expected ) {
+               $actual = ContentSecurityPolicy::falsePositiveBrowser( $ua );
+               $this->assertEquals( $expected, $actual, $ua );
+       }
+
+       public function providerFalsePositiveBrowser() {
+               // @codingStandardsIgnoreStart Generic.Files.LineLength
+               return [
+                       [ 'Mozilla/5.0 (X11; Linux i686; rv:41.0) Gecko/20100101 Firefox/41.0', true ],
+                       [ 'Mozilla/5.0 (X11; U; Linux i686; en-ca) AppleWebKit/531.2+ (KHTML, like Gecko) Version/5.0 Safari/531.2+ Debian/squeeze (2.30.6-1) Epiphany/2.30.6', false ]
+               ];
+               // @codingStandardsIgnoreEnd Generic.Files.LineLength
+       }
+
+       /**
+        * @dataProvider providerMakeCSPDirectives
+        * @covers ContentSecurityPolicy::makeCSPDirectives
+        */
+       public function testMakeCSPDirectives(
+               $policy,
+               $expectedFull,
+               $expectedReport,
+               $expectedRestricted
+       ) {
+               $actualFull = $this->csp->makeCSPDirectives( $policy, ContentSecurityPolicy::FULL_MODE );
+               $actualReport = $this->csp->makeCSPDirectives(
+                       $policy, ContentSecurityPolicy::REPORT_ONLY_MODE
+               );
+               $actualRestricted = $this->csp->makeCSPDirectives(
+                       $policy, ContentSecurityPolicy::FULL_MODE_RESTRICTED
+               );
+               $policyJson = formatJson::encode( $policy );
+               $this->assertEquals( $expectedFull, $actualFull, "full: " . $policyJson );
+               $this->assertEquals( $expectedReport, $actualReport, "report: " . $policyJson );
+               $this->assertEquals( $expectedRestricted, $actualRestricted, "restricted: " . $policyJson );
+       }
+
+       public function providerMakeCSPDirectives() {
+               // @codingStandardsIgnoreStart Generic.Files.LineLength
+               return [
+                       [ false, '', '', '' ],
+                       [
+                               true,
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&",
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&reportonly=1&",
+                               "script-src 'unsafe-eval' 'self' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'",
+                       ],
+                       [
+                               [],
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&",
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&reportonly=1&",
+                               "script-src 'unsafe-eval' 'self' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'",
+                        ],
+                       [
+                               [ 'script-src' => [ 'http://example.com', 'http://something,else.com' ] ],
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' http://example.com http://something%2Celse.com 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&",
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' http://example.com http://something%2Celse.com 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&reportonly=1&",
+                               "script-src 'unsafe-eval' 'self' http://example.com http://something%2Celse.com sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'",
+                       ],
+                       [
+                               [ 'unsafeFallback' => false ],
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&",
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&reportonly=1&",
+                               "script-src 'unsafe-eval' 'self' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'",
+                       ],
+                       [
+                               [ 'unsafeFallback' => true ],
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&",
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&reportonly=1&",
+                               "script-src 'unsafe-eval' 'self' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'",
+                       ],
+                       [
+                               [ 'default-src' => false ],
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&",
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&reportonly=1&",
+                               "script-src 'unsafe-eval' 'self' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'",
+                       ],
+                       [
+                               [ 'default-src' => true ],
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src 'self' data: blob: https://upload.wikimedia.org https://commons.wikimedia.org sister-site.somewhere.com *.wikipedia.org; style-src 'self' data: blob: https://upload.wikimedia.org https://commons.wikimedia.org sister-site.somewhere.com *.wikipedia.org 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&",
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src 'self' data: blob: https://upload.wikimedia.org https://commons.wikimedia.org sister-site.somewhere.com *.wikipedia.org; style-src 'self' data: blob: https://upload.wikimedia.org https://commons.wikimedia.org sister-site.somewhere.com *.wikipedia.org 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&reportonly=1&",
+                               "script-src 'unsafe-eval' 'self' sister-site.somewhere.com *.wikipedia.org; default-src 'self' data: blob: https://upload.wikimedia.org https://commons.wikimedia.org sister-site.somewhere.com *.wikipedia.org; style-src 'self' data: blob: https://upload.wikimedia.org https://commons.wikimedia.org sister-site.somewhere.com *.wikipedia.org 'unsafe-inline'",
+                       ],
+                       [
+                               [ 'default-src' => [ 'https://foo.com', 'http://bar.com', 'baz.de' ] ],
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src 'self' data: blob: https://upload.wikimedia.org https://commons.wikimedia.org https://foo.com http://bar.com baz.de sister-site.somewhere.com *.wikipedia.org; style-src 'self' data: blob: https://upload.wikimedia.org https://commons.wikimedia.org https://foo.com http://bar.com baz.de sister-site.somewhere.com *.wikipedia.org 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&",
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src 'self' data: blob: https://upload.wikimedia.org https://commons.wikimedia.org https://foo.com http://bar.com baz.de sister-site.somewhere.com *.wikipedia.org; style-src 'self' data: blob: https://upload.wikimedia.org https://commons.wikimedia.org https://foo.com http://bar.com baz.de sister-site.somewhere.com *.wikipedia.org 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&reportonly=1&",
+                               "script-src 'unsafe-eval' 'self' sister-site.somewhere.com *.wikipedia.org; default-src 'self' data: blob: https://upload.wikimedia.org https://commons.wikimedia.org https://foo.com http://bar.com baz.de sister-site.somewhere.com *.wikipedia.org; style-src 'self' data: blob: https://upload.wikimedia.org https://commons.wikimedia.org https://foo.com http://bar.com baz.de sister-site.somewhere.com *.wikipedia.org 'unsafe-inline'",
+                       ],
+                       [
+                               [ 'includeCORS' => false ],
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline'; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&",
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline'; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&reportonly=1&",
+                               "script-src 'unsafe-eval' 'self'; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'",
+                       ],
+                       [
+                               [ 'includeCORS' => false, 'default-src' => true ],
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline'; default-src 'self' data: blob: https://upload.wikimedia.org https://commons.wikimedia.org; style-src 'self' data: blob: https://upload.wikimedia.org https://commons.wikimedia.org 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&",
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline'; default-src 'self' data: blob: https://upload.wikimedia.org https://commons.wikimedia.org; style-src 'self' data: blob: https://upload.wikimedia.org https://commons.wikimedia.org 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&reportonly=1&",
+                               "script-src 'unsafe-eval' 'self'; default-src 'self' data: blob: https://upload.wikimedia.org https://commons.wikimedia.org; style-src 'self' data: blob: https://upload.wikimedia.org https://commons.wikimedia.org 'unsafe-inline'",
+                       ],
+                       [
+                               [ 'includeCORS' => true ],
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&",
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&reportonly=1&",
+                               "script-src 'unsafe-eval' 'self' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'",
+                       ],
+                       [
+                               [ 'report-uri' => false ],
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'",
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'",
+                               "script-src 'unsafe-eval' 'self' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'",
+                       ],
+                       [
+                               [ 'report-uri' => true ],
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&",
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&reportonly=1&",
+                               "script-src 'unsafe-eval' 'self' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'",
+                       ],
+                       [
+                               [ 'report-uri' => 'https://example.com/index.php?foo;report=csp' ],
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri https://example.com/index.php?foo%3Breport=csp",
+                               "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri https://example.com/index.php?foo%3Breport=csp",
+                               "script-src 'unsafe-eval' 'self' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'",
+                       ],
+               ];
+       }
+
+       /**
+        * @covers ContentSecurityPolicy::makeCSPDirectives
+        */
+       public function testMakeCSPDirectivesImage() {
+               global $wgAllowImageTag;
+               $origImg = wfSetVar( $wgAllowImageTag, true );
+
+               $actual = $this->csp->makeCSPDirectives( true, ContentSecurityPolicy::FULL_MODE );
+
+               $wgAllowImageTag = $origImg;
+
+               $expected = "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&";
+               $this->assertEquals( $expected, $actual );
+       }
+
+       /**
+        * @covers ContentSecurityPolicy::makeCSPDirectives
+        */
+       public function testMakeCSPDirectivesReportUri() {
+               $actual = $this->csp->makeCSPDirectives(
+                       true,
+                       ContentSecurityPolicy::REPORT_ONLY_MODE
+               );
+               $expected = "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&reportonly=1&";
+               $this->assertEquals( $expected, $actual );
+               // @codingStandardsIgnoreEnd Generic.Files.LineLength
+       }
+
+       /**
+        * @covers ContentSecurityPolicy::getHeaderName
+        */
+       public function testGetHeaderName() {
+               $this->assertEquals(
+                       $this->csp->getHeaderName( ContentSecurityPolicy::REPORT_ONLY_MODE ),
+                       'Content-Security-Policy-Report-Only'
+               );
+               $this->assertEquals(
+                       $this->csp->getHeaderName( ContentSecurityPolicy::FULL_MODE ),
+                       'Content-Security-Policy'
+               );
+       }
+
+       /**
+        * @covers ContentSecurityPolicy::getReportUri
+        */
+       public function testGetReportUri() {
+               $full = $this->csp->getReportUri( ContentSecurityPolicy::FULL_MODE );
+               $fullExpected = '/w/api.php?action=cspreport&format=json&';
+               $this->assertEquals( $full, $fullExpected, 'normal report uri' );
+
+               $report = $this->csp->getReportUri( ContentSecurityPolicy::REPORT_ONLY_MODE );
+               $reportExpected = $fullExpected . 'reportonly=1&';
+               $this->assertEquals( $report, $reportExpected, 'report only' );
+
+               global $wgScriptPath;
+               $origPath = wfSetVar( $wgScriptPath, '/tl;dr/a,%20wiki' );
+               $esc = $this->csp->getReportUri( ContentSecurityPolicy::FULL_MODE );
+               $escExpected = '/tl%3Bdr/a%2C%20wiki/api.php?action=cspreport&format=json&';
+               $wgScriptPath = $origPath;
+               $this->assertEquals( $esc, $escExpected, 'test esc rules' );
+       }
+
+       /**
+        * @dataProvider providerPrepareUrlForCSP
+        * @covers ContentSecurityPolicy::prepareUrlForCSP
+        */
+       public function testPrepareUrlForCSP( $url, $expected ) {
+               $actual = $this->csp->prepareUrlForCSP( $url );
+               $this->assertEquals( $actual, $expected, $url );
+       }
+
+       public function providerPrepareUrlForCSP() {
+               global $wgServer;
+               return [
+                       [ $wgServer, false ],
+                       [ 'https://example.com', 'https://example.com' ],
+                       [ 'https://example.com:200', 'https://example.com:200' ],
+                       [ 'http://example.com', 'http://example.com' ],
+                       [ 'example.com', 'example.com' ],
+                       [ '*.example.com', '*.example.com' ],
+                       [ 'https://*.example.com', 'https://*.example.com' ],
+                       [ '//example.com', 'example.com' ],
+                       [ 'https://example.com/path', 'https://example.com' ],
+                       [ 'https://example.com/path:', 'https://example.com' ],
+                       [ 'https://example.com/Wikipedia:NPOV', 'https://example.com' ],
+                       [ 'https://tl;dr.com', 'https://tl%3Bdr.com' ],
+                       [ 'yes,no.com', 'yes%2Cno.com' ],
+                       [ '/relative-url', false ],
+                       [ '/relativeUrl:withColon', false ],
+                       [ 'data:', 'data:' ],
+                       [ 'blob:', 'blob:' ],
+               ];
+       }
+
+       /**
+        * @covers ContentSecurityPolicy::escapeUrlForCSP
+        */
+       public function testEscapeUrlForCSP() {
+               $escaped = $this->csp->escapeUrlForCSP( ',;%2B' );
+               $this->assertEquals( $escaped, '%2C%3B%2B' );
+       }
+
+       /**
+        * @dataProvider providerCSPIsEnabled
+        * @covers ContentSecurityPolicy::isEnabled
+        */
+       public function testCSPIsEnabled( $main, $reportOnly, $expected ) {
+               global $wgCSPReportOnlyHeader, $wgCSPHeader;
+               global $wgCSPHeader;
+               $oldReport = wfSetVar( $wgCSPReportOnlyHeader, $reportOnly );
+               $oldMain = wfSetVar( $wgCSPHeader, $main );
+               $res = ContentSecurityPolicy::isEnabled( RequestContext::getMain()->getConfig() );
+               wfSetVar( $wgCSPReportOnlyHeader, $oldReport );
+               wfSetVar( $wgCSPHeader, $oldMain );
+               $this->assertEquals( $res, $expected );
+       }
+
+       public function providerCSPIsEnabled() {
+               return [
+                       [ true, true, true ],
+                       [ false, true, true ],
+                       [ true, false, true ],
+                       [ false, false, false ],
+                       [ false, [], true ],
+                       [ [], false, true ],
+                       [ [ 'default-src' => [ 'foo.example.com' ] ], false, true ],
+               ];
+       }
+}
index efe92ec..c1efc7f 100644 (file)
@@ -33,6 +33,12 @@ class HooksTest extends MediaWikiTestCase {
                                'changed-static',
                                'original'
                        ],
+                       [
+                               'Class::method static call as array',
+                               [ [ 'NothingClass::someStatic' ] ],
+                               'changed-static',
+                               'original'
+                       ],
                        [ 'Global function', [ 'NothingFunction' ], 'changed-func', 'original' ],
                        [ 'Global function with data', [ 'NothingFunctionData', 'data' ], 'data', 'original' ],
                        [ 'Closure', [ function ( &$foo, $bar ) {
@@ -81,10 +87,50 @@ class HooksTest extends MediaWikiTestCase {
                $this->assertSame( $expectedBar, $bar, $msg );
        }
 
+       /**
+        * @covers Hooks::getHandlers
+        */
+       public function testGetHandlers() {
+               global $wgHooks;
+
+               $this->assertSame(
+                       [],
+                       Hooks::getHandlers( 'MediaWikiHooksTest001' ),
+                       'No hooks registered'
+               );
+
+               $a = new NothingClass();
+               $b = new NothingClass();
+
+               $wgHooks['MediaWikiHooksTest001'][] = $a;
+
+               $this->assertSame(
+                       [ $a ],
+                       Hooks::getHandlers( 'MediaWikiHooksTest001' ),
+                       'Hook registered by $wgHooks'
+               );
+
+               Hooks::register( 'MediaWikiHooksTest001', $b );
+               $this->assertSame(
+                       [ $b, $a ],
+                       Hooks::getHandlers( 'MediaWikiHooksTest001' ),
+                       'Hooks::getHandlers() should return hooks registered via wgHooks as well as Hooks::register'
+               );
+
+               Hooks::clear( 'MediaWikiHooksTest001' );
+               unset( $wgHooks['MediaWikiHooksTest001'] );
+
+               Hooks::register( 'MediaWikiHooksTest001', $b );
+               $this->assertSame(
+                       [ $b ],
+                       Hooks::getHandlers( 'MediaWikiHooksTest001' ),
+                       'Hook registered by Hook::register'
+               );
+       }
+
        /**
         * @covers Hooks::isRegistered
         * @covers Hooks::register
-        * @covers Hooks::getHandlers
         * @covers Hooks::run
         * @covers Hooks::callHook
         */
@@ -151,6 +197,56 @@ class HooksTest extends MediaWikiTestCase {
                $this->assertSame( 'original', $foo, 'Hooks abort after a false return.' );
        }
 
+       /**
+        * @covers Hooks::run
+        */
+       public function testNullReturn() {
+               Hooks::register( 'MediaWikiHooksTest001', function ( &$foo ) {
+                       return;
+               } );
+               Hooks::register( 'MediaWikiHooksTest001', function ( &$foo ) {
+                       $foo = 'test';
+
+                       return true;
+               } );
+               $foo = 'original';
+               Hooks::run( 'MediaWikiHooksTest001', [ &$foo ] );
+               $this->assertSame( 'test', $foo, 'Hooks continue after a null return.' );
+       }
+
+       /**
+        * @covers Hooks::callHook
+        */
+       public function testCallHook_FalseHook() {
+               Hooks::register( 'MediaWikiHooksTest001', false );
+               Hooks::register( 'MediaWikiHooksTest001', function ( &$foo ) {
+                       $foo = 'test';
+
+                       return true;
+               } );
+               $foo = 'original';
+               Hooks::run( 'MediaWikiHooksTest001', [ &$foo ] );
+               $this->assertSame( 'test', $foo, 'Hooks that are falsey are skipped.' );
+       }
+
+       /**
+        * @covers Hooks::callHook
+        * @expectedException MWException
+        */
+       public function testCallHook_UnknownDatatype() {
+               Hooks::register( 'MediaWikiHooksTest001', 12345 );
+               Hooks::run( 'MediaWikiHooksTest001' );
+       }
+
+       /**
+        * @covers Hooks::callHook
+        * @expectedException PHPUnit_Framework_Error_Deprecated
+        */
+       public function testCallHook_Deprecated() {
+               Hooks::register( 'MediaWikiHooksTest001', 'NothingClass::someStatic' );
+               Hooks::run( 'MediaWikiHooksTest001', [], '1.31' );
+       }
+
        /**
         * @covers Hooks::runWithoutAbort
         * @covers Hooks::callHook
index 91655ea..73447c9 100644 (file)
@@ -321,7 +321,7 @@ class OutputPageTest extends MediaWikiTestCase {
                        // Single only=scripts load
                        [
                                [ 'test.foo', ResourceLoaderModule::TYPE_SCRIPTS ],
-                               "<script>(window.RLQ=window.RLQ||[]).push(function(){"
+                               "<script nonce=\"secret\">(window.RLQ=window.RLQ||[]).push(function(){"
                                        . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?debug=false\u0026lang=en\u0026modules=test.foo\u0026only=scripts\u0026skin=fallback");'
                                        . "});</script>"
                        ],
@@ -334,10 +334,36 @@ class OutputPageTest extends MediaWikiTestCase {
                        // Private embed (only=scripts)
                        [
                                [ 'test.quux', ResourceLoaderModule::TYPE_SCRIPTS ],
-                               "<script>(window.RLQ=window.RLQ||[]).push(function(){"
+                               "<script nonce=\"secret\">(window.RLQ=window.RLQ||[]).push(function(){"
                                        . "mw.test.baz({token:123});\nmw.loader.state({\"test.quux\":\"ready\"});"
                                        . "});</script>"
                        ],
+                       // Load private module (combined)
+                       [
+                               [ 'test.quux', ResourceLoaderModule::TYPE_COMBINED ],
+                               "<script nonce=\"secret\">(window.RLQ=window.RLQ||[]).push(function(){"
+                                       . "mw.loader.implement(\"test.quux@1ev0ijv\",function($,jQuery,require,module){"
+                                       . "mw.test.baz({token:123});},{\"css\":[\".mw-icon{transition:none}"
+                                       . "\"]});});</script>"
+                       ],
+                       // Load no modules
+                       [
+                               [ [], ResourceLoaderModule::TYPE_COMBINED ],
+                               '',
+                       ],
+                       // noscript group
+                       [
+                               [ 'test.noscript', ResourceLoaderModule::TYPE_STYLES ],
+                               '<noscript><link rel="stylesheet" href="http://127.0.0.1:8080/w/load.php?debug=false&amp;lang=en&amp;modules=test.noscript&amp;only=styles&amp;skin=fallback"/></noscript>'
+                       ],
+                       // Load two modules in separate groups
+                       [
+                               [ [ 'test.group.foo', 'test.group.bar' ], ResourceLoaderModule::TYPE_COMBINED ],
+                               "<script nonce=\"secret\">(window.RLQ=window.RLQ||[]).push(function(){"
+                                       . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?debug=false\u0026lang=en\u0026modules=test.group.bar\u0026skin=fallback");'
+                                       . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?debug=false\u0026lang=en\u0026modules=test.group.foo\u0026skin=fallback");'
+                                       . "});</script>"
+                       ],
                ];
                // phpcs:enable
        }
@@ -352,6 +378,7 @@ class OutputPageTest extends MediaWikiTestCase {
                $this->setMwGlobals( [
                        'wgResourceLoaderDebug' => false,
                        'wgLoadScript' => 'http://127.0.0.1:8080/w/load.php',
+                       'wgCSPReportOnlyHeader' => true,
                ] );
                $class = new ReflectionClass( OutputPage::class );
                $method = $class->getMethod( 'makeResourceLoaderLink' );
@@ -360,6 +387,9 @@ class OutputPageTest extends MediaWikiTestCase {
                $ctx->setSkin( SkinFactory::getDefaultInstance()->makeSkin( 'fallback' ) );
                $ctx->setLanguage( 'en' );
                $out = new OutputPage( $ctx );
+               $nonce = $class->getProperty( 'CSPNonce' );
+               $nonce->setAccessible( true );
+               $nonce->setValue( $out, 'secret' );
                $rl = $out->getResourceLoader();
                $rl->setMessageBlobStore( new NullMessageBlobStore() );
                $rl->register( [
@@ -380,6 +410,18 @@ class OutputPageTest extends MediaWikiTestCase {
                                'styles' => '/* pref-animate=off */ .mw-icon { transition: none; }',
                                'group' => 'private',
                        ] ),
+                       'test.noscript' => new ResourceLoaderTestModule( [
+                               'styles' => '.stuff { color: red; }',
+                               'group' => 'noscript',
+                       ] ),
+                       'test.group.foo' => new ResourceLoaderTestModule( [
+                               'script' => 'mw.doStuff( "foo" );',
+                               'group' => 'foo',
+                       ] ),
+                       'test.group.bar' => new ResourceLoaderTestModule( [
+                               'script' => 'mw.doStuff( "bar" );',
+                               'group' => 'bar',
+                       ] ),
                ] );
                $links = $method->invokeArgs( $out, $args );
                $actualHtml = strval( $links );
index 21d1bf2..17a4182 100644 (file)
@@ -40,8 +40,8 @@ class TestLogger extends \Psr\Log\AbstractLogger {
         * @param bool $collect Whether to collect logs. @see setCollect()
         * @param callable $filter Filter logs before collecting/printing. Signature is
         *  string|null function ( string $message, string $level, array $context );
-        * @param bool $collectContext Whether to keep the context passed to log.
-        *                             @since 1.29 @see setCollectContext()
+        * @param bool $collectContext Whether to keep the context passed to log
+        *             (since 1.29, @see setCollectContext()).
         */
        public function __construct( $collect = false, $filter = null, $collectContext = false ) {
                $this->collect = $collect;
index e46fc67..4556473 100644 (file)
@@ -97,8 +97,8 @@ class XmlTest extends MediaWikiTestCase {
         */
        public function testElementEscaping() {
                $this->assertEquals(
-                       '<element>hello &lt;there&gt; you &amp; you</element>',
-                       Xml::element( 'element', null, 'hello <there> you & you' ),
+                       '<element>"hello &lt;there&gt; your\'s &amp; you"</element>',
+                       Xml::element( 'element', null, '"hello <there> your\'s & you"' ),
                        'Element with no attributes and content that needs escaping'
                );
        }
index b96b491..9c8b957 100644 (file)
@@ -6,7 +6,7 @@
  * @group Action
  * @group Database
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Thiemo Kreuz
  */
 class ActionTest extends MediaWikiTestCase {
diff --git a/tests/phpunit/includes/actions/WatchActionTest.php b/tests/phpunit/includes/actions/WatchActionTest.php
new file mode 100644 (file)
index 0000000..044c30a
--- /dev/null
@@ -0,0 +1,367 @@
+<?php
+
+/**
+ * @covers WatchAction
+ *
+ * @group Action
+ */
+class WatchActionTest extends MediaWikiTestCase {
+
+       /**
+        * @var WatchAction
+        */
+       private $watchAction;
+
+       /**
+        * @var WikiPage
+        */
+       private $testWikiPage;
+
+       protected function setUp() {
+               parent::setUp();
+
+               $testTitle = Title::newFromText( 'UTTest' );
+               $this->testWikiPage = new WikiPage( $testTitle );
+               $testContext = new DerivativeContext( RequestContext::getMain() );
+               $testContext->setTitle( $testTitle );
+               $this->watchAction = new WatchAction( $this->testWikiPage, $testContext );
+       }
+
+       /**
+        * @throws MWException
+        */
+       protected function tearDown() {
+               parent::tearDown();
+
+               Hooks::clear( 'WatchArticle' );
+               Hooks::clear( 'UnwatchArticle' );
+       }
+
+       /**
+        * @covers WatchAction::getName()
+        */
+       public function testGetName() {
+               $this->assertEquals( 'watch', $this->watchAction->getName() );
+       }
+
+       /**
+        * @covers WatchAction::requiresUnblock()
+        */
+       public function testRequiresUnlock() {
+               $this->assertFalse( $this->watchAction->requiresUnblock() );
+       }
+
+       /**
+        * @covers WatchAction::doesWrites()
+        */
+       public function testDoesWrites() {
+               $this->assertTrue( $this->watchAction->doesWrites() );
+       }
+
+       /**
+        * @covers WatchAction::onSubmit()
+        * @covers WatchAction::doWatch()
+        */
+       public function testOnSubmit() {
+               /** @var Status $actual */
+               $actual = $this->watchAction->onSubmit( [] );
+
+               $this->assertTrue( $actual->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::onSubmit()
+        * @covers WatchAction::doWatch()
+        */
+       public function testOnSubmitHookAborted() {
+               Hooks::register( 'WatchArticle', function () {
+                       return false;
+               } );
+
+               /** @var Status $actual */
+               $actual = $this->watchAction->onSubmit( [] );
+
+               $this->assertInstanceOf( Status::class, $actual );
+               $this->assertTrue( $actual->hasMessage( 'hookaborted' ) );
+       }
+
+       /**
+        * @covers WatchAction::checkCanExecute()
+        */
+       public function testShowUserNotLoggedIn() {
+               $notLoggedInUser = new User();
+               $testContext = new DerivativeContext( $this->watchAction->getContext() );
+               $testContext->setUser( $notLoggedInUser );
+               $watchAction = new WatchAction( $this->testWikiPage, $testContext );
+               $this->setExpectedException( UserNotLoggedIn::class );
+
+               $watchAction->show();
+       }
+
+       /**
+        * @covers WatchAction::checkCanExecute()
+        */
+       public function testShowUserLoggedInNoException() {
+               $loggedInUser = $this->getMock( User::class );
+               $loggedInUser->method( 'isLoggedIn' )->willReturn( true );
+               $testContext = new DerivativeContext( $this->watchAction->getContext() );
+               $testContext->setUser( $loggedInUser );
+               $watchAction = new WatchAction( $this->testWikiPage, $testContext );
+
+               $exception = null;
+               try {
+                       $watchAction->show();
+               } catch ( UserNotLoggedIn $e ) {
+                       $exception = $e;
+               }
+               $this->assertNull( $exception,
+                       'UserNotLoggedIn exception should not be thrown if user is logged in.' );
+       }
+
+       /**
+        * @covers WatchAction::onSuccess()
+        */
+       public function testOnSuccessMainNamespaceTitle() {
+               $testContext = $this->getMock(
+                       DerivativeContext::class,
+                       [ 'msg' ],
+                       [ $this->watchAction->getContext() ]
+               );
+               $testOutput = new OutputPage( $testContext );
+               $testContext->setOutput( $testOutput );
+               $testContext->method( 'msg' )->willReturnCallback( function ( $msgKey ) {
+                       return new RawMessage( $msgKey );
+               } );
+               $watchAction = new WatchAction( $this->testWikiPage, $testContext );
+
+               $watchAction->onSuccess();
+
+               $this->assertEquals( '<p>addedwatchtext
+</p>', $testOutput->getHTML() );
+       }
+
+       /**
+        * @covers WatchAction::onSuccess()
+        */
+       public function testOnSuccessTalkPage() {
+               $testContext = $this->getMock(
+                       DerivativeContext::class,
+                       [],
+                       [ $this->watchAction->getContext() ]
+               );
+               $testOutput = new OutputPage( $testContext );
+               $testContext->method( 'getOutput' )->willReturn( $testOutput );
+               $testContext->method( 'msg' )->willReturnCallback( function ( $msgKey ) {
+                       return new RawMessage( $msgKey );
+               } );
+               $talkPageTitle = Title::newFromText( 'Talk:UTTest' );
+               $testContext->setTitle( $talkPageTitle );
+               $watchAction = new WatchAction( new WikiPage( $talkPageTitle ), $testContext );
+
+               $watchAction->onSuccess();
+
+               $this->assertEquals( '<p>addedwatchtext-talk
+</p>', $testOutput->getHTML() );
+       }
+
+       /**
+        * @covers WatchAction::doWatch()
+        */
+       public function testDoWatchNoCheckRights() {
+               $notPermittedUser = $this->getMock( User::class );
+               $notPermittedUser->method( 'isAllowed' )->willReturn( false );
+
+               $actual = WatchAction::doWatch( $this->testWikiPage->getTitle(), $notPermittedUser, false );
+
+               $this->assertTrue( $actual->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::doWatch()
+        */
+       public function testDoWatchUserNotPermittedStatusNotGood() {
+               $notPermittedUser = $this->getMock( User::class );
+               $notPermittedUser->method( 'isAllowed' )->willReturn( false );
+
+               $actual = WatchAction::doWatch( $this->testWikiPage->getTitle(), $notPermittedUser, true );
+
+               $this->assertFalse( $actual->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::doWatch()
+        */
+       public function testDoWatchCallsUserAddWatch() {
+               $permittedUser = $this->getMock( User::class );
+               $permittedUser->method( 'isAllowed' )->willReturn( true );
+               $permittedUser->expects( $this->once() )
+                       ->method( 'addWatch' )
+                       ->with( $this->equalTo( $this->testWikiPage->getTitle() ), $this->equalTo( true ) );
+
+               $actual = WatchAction::doWatch( $this->testWikiPage->getTitle(), $permittedUser );
+
+               $this->assertTrue( $actual->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::doUnWatch()
+        */
+       public function testDoUnWatchWithoutRights() {
+               $notPermittedUser = $this->getMock( User::class );
+               $notPermittedUser->method( 'isAllowed' )->willReturn( false );
+
+               $actual = WatchAction::doUnWatch( $this->testWikiPage->getTitle(), $notPermittedUser );
+
+               $this->assertFalse( $actual->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::doUnWatch()
+        */
+       public function testDoUnWatchUserHookAborted() {
+               $permittedUser = $this->getMock( User::class );
+               $permittedUser->method( 'isAllowed' )->willReturn( true );
+               Hooks::register( 'UnwatchArticle', function () {
+                       return false;
+               } );
+
+               $status = WatchAction::doUnWatch( $this->testWikiPage->getTitle(), $permittedUser );
+
+               $this->assertFalse( $status->isGood() );
+               $errors = $status->getErrors();
+               $this->assertEquals( 1, count( $errors ) );
+               $this->assertEquals( 'hookaborted', $errors[0]['message'] );
+       }
+
+       /**
+        * @covers WatchAction::doUnWatch()
+        */
+       public function testDoUnWatchCallsUserRemoveWatch() {
+               $permittedUser = $this->getMock( User::class );
+               $permittedUser->method( 'isAllowed' )->willReturn( true );
+               $permittedUser->expects( $this->once() )
+                       ->method( 'removeWatch' )
+                       ->with( $this->equalTo( $this->testWikiPage->getTitle() ) );
+
+               $actual = WatchAction::doUnWatch( $this->testWikiPage->getTitle(), $permittedUser );
+
+               $this->assertTrue( $actual->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::getWatchToken()
+        */
+       public function testGetWatchTokenNormalizesToWatch() {
+               $user = $this->getMock( User::class );
+               $user->expects( $this->once() )
+                       ->method( 'getEditToken' )
+                       ->with( $this->equalTo( 'watch' ) );
+
+               WatchAction::getWatchToken( $this->watchAction->getTitle(), $user, 'INVALID_ACTION' );
+       }
+
+       /**
+        * @covers WatchAction::getWatchToken()
+        */
+       public function testGetWatchTokenProxiesUserGetEditToken() {
+               $user = $this->getMock( User::class );
+               $user->expects( $this->once() )->method( 'getEditToken' );
+
+               WatchAction::getWatchToken( $this->watchAction->getTitle(), $user );
+       }
+
+       /**
+        * @covers WatchAction::getUnwatchToken()
+        */
+       public function testGetUnwatchToken() {
+               $user = $this->getMock( User::class );
+               $user->expects( $this->once() )->method( 'getEditToken' );
+               $this->hideDeprecated( 'WatchAction::getUnwatchToken' );
+
+               WatchAction::getUnWatchToken( $this->watchAction->getTitle(), $user );
+       }
+
+       /**
+        * @covers WatchAction::doWatchOrUnwatch()
+        */
+       public function testDoWatchOrUnwatchUserNotLoggedIn() {
+               $user = $this->getLoggedInIsWatchedUser( false );
+               $user->expects( $this->never() )->method( 'removeWatch' );
+               $user->expects( $this->never() )->method( 'addWatch' );
+
+               $status = WatchAction::doWatchOrUnwatch( true, $this->watchAction->getTitle(), $user );
+
+               $this->assertTrue( $status->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::doWatchOrUnwatch()
+        */
+       public function testDoWatchOrUnwatchSkipsIfAlreadyWatched() {
+               $user = $this->getLoggedInIsWatchedUser();
+               $user->expects( $this->never() )->method( 'removeWatch' );
+               $user->expects( $this->never() )->method( 'addWatch' );
+
+               $status = WatchAction::doWatchOrUnwatch( true, $this->watchAction->getTitle(), $user );
+
+               $this->assertTrue( $status->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::doWatchOrUnwatch()
+        */
+       public function testDoWatchOrUnwatchSkipsIfAlreadyUnWatched() {
+               $user = $this->getLoggedInIsWatchedUser( true, false );
+               $user->expects( $this->never() )->method( 'removeWatch' );
+               $user->expects( $this->never() )->method( 'addWatch' );
+
+               $status = WatchAction::doWatchOrUnwatch( false, $this->watchAction->getTitle(), $user );
+
+               $this->assertTrue( $status->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::doWatchOrUnwatch()
+        */
+       public function testDoWatchOrUnwatchWatchesIfWatch() {
+               $user = $this->getLoggedInIsWatchedUser( true, false );
+               $user->expects( $this->never() )->method( 'removeWatch' );
+               $user->expects( $this->once() )
+                       ->method( 'addWatch' )
+                       ->with( $this->equalTo( $this->testWikiPage->getTitle() ), $this->equalTo( false ) );
+
+               $status = WatchAction::doWatchOrUnwatch( true, $this->watchAction->getTitle(), $user );
+
+               $this->assertTrue( $status->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::doWatchOrUnwatch()
+        */
+       public function testDoWatchOrUnwatchUnwatchesIfUnwatch() {
+               $user = $this->getLoggedInIsWatchedUser();
+               $user->method( 'isAllowed' )->willReturn( true );
+               $user->expects( $this->never() )->method( 'addWatch' );
+               $user->expects( $this->once() )
+                       ->method( 'removeWatch' )
+                       ->with( $this->equalTo( $this->testWikiPage->getTitle() ) );
+
+               $status = WatchAction::doWatchOrUnwatch( false, $this->watchAction->getTitle(), $user );
+
+               $this->assertTrue( $status->isGood() );
+       }
+
+       /**
+        * @param bool $isLoggedIn Whether the user should be "marked" as logged in
+        * @param bool $isWatched The value any call to isWatched should return
+        * @return PHPUnit_Framework_MockObject_MockObject
+        */
+       private function getLoggedInIsWatchedUser( $isLoggedIn = true, $isWatched = true ) {
+               $user = $this->getMock( User::class );
+               $user->method( 'isLoggedIn' )->willReturn( $isLoggedIn );
+               $user->method( 'isWatched' )->willReturn( $isWatched );
+
+               return $user;
+       }
+
+}
index 4bffc74..cce99ce 100644 (file)
@@ -212,6 +212,44 @@ class ApiBaseTest extends ApiTestCase {
                $mock->getTitleFromTitleOrPageId( [ 'pageid' => 298401643 ] );
        }
 
+       public function testGetParameter() {
+               $mock = $this->getMockBuilder( MockApi::class )
+                       ->setMethods( [ 'getAllowedParams' ] )
+                       ->getMock();
+               $mock->method( 'getAllowedParams' )->willReturn( [
+                       'foo' => [
+                               ApiBase::PARAM_TYPE => [ 'value' ],
+                       ],
+                       'bar' => [
+                               ApiBase::PARAM_TYPE => [ 'value' ],
+                       ],
+               ] );
+               $wrapper = TestingAccessWrapper::newFromObject( $mock );
+
+               $context = new DerivativeContext( $mock );
+               $context->setRequest( new FauxRequest( [ 'foo' => 'bad', 'bar' => 'value' ] ) );
+               $wrapper->mMainModule = new ApiMain( $context );
+
+               // Even though 'foo' is bad, getParameter( 'bar' ) must not fail
+               $this->assertSame( 'value', $wrapper->getParameter( 'bar' ) );
+
+               // But getParameter( 'foo' ) must throw.
+               try {
+                       $wrapper->getParameter( 'foo' );
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( ApiUsageException $ex ) {
+                       $this->assertTrue( $this->apiExceptionHasCode( $ex, 'unknown_foo' ) );
+               }
+
+               // And extractRequestParams() must throw too.
+               try {
+                       $mock->extractRequestParams();
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( ApiUsageException $ex ) {
+                       $this->assertTrue( $this->apiExceptionHasCode( $ex, 'unknown_foo' ) );
+               }
+       }
+
        /**
         * @dataProvider provideGetParameterFromSettings
         * @param string|null $input
@@ -363,8 +401,10 @@ class ApiBaseTest extends ApiTestCase {
                                        ApiBase::PARAM_ISMULTI => true,
                                        ApiBase::PARAM_ISMULTI_LIMIT1 => 2,
                                ],
-                               [ 'a', 'b' ],
-                               [ [ 'apiwarn-toomanyvalues', 'myParam', 2 ] ],
+                               ApiUsageException::newWithMessage(
+                                       null, [ 'apierror-toomanyvalues', 'myParam', 2 ], 'too-many-myParam'
+                               ),
+                               []
                        ],
                        'Multi-valued parameter with exceeded limits for non-bot' => [
                                'a|b|c',
@@ -373,8 +413,10 @@ class ApiBaseTest extends ApiTestCase {
                                        ApiBase::PARAM_ISMULTI_LIMIT1 => 2,
                                        ApiBase::PARAM_ISMULTI_LIMIT2 => 3,
                                ],
-                               [ 'a', 'b' ],
-                               [ [ 'apiwarn-toomanyvalues', 'myParam', 2 ] ],
+                               ApiUsageException::newWithMessage(
+                                       null, [ 'apierror-toomanyvalues', 'myParam', 2 ], 'too-many-myParam'
+                               ),
+                               []
                        ],
                        'Multi-valued parameter with non-exceeded limits for bot' => [
                                'a|b|c',
@@ -995,6 +1037,12 @@ class ApiBaseTest extends ApiTestCase {
                                'Foo bar',
                                [],
                        ],
+                       'User prefixed with "User:"' => [
+                               'User:foo_bar',
+                               [ ApiBase::PARAM_TYPE => 'user' ],
+                               'Foo bar',
+                               [],
+                       ],
                        'Invalid username "|"' => [
                                '|',
                                [ ApiBase::PARAM_TYPE => 'user' ],
@@ -1272,4 +1320,99 @@ class ApiBaseTest extends ApiTestCase {
                }
        }
 
+       /**
+        * @covers ApiBase::extractRequestParams
+        */
+       public function testExtractRequestParams() {
+               $request = new FauxRequest( [
+                       'xxexists' => 'exists!',
+                       'xxmulti' => 'a|b|c|d|{bad}',
+                       'xxempty' => '',
+                       'xxtemplate-a' => 'A!',
+                       'xxtemplate-b' => 'B1|B2|B3',
+                       'xxtemplate-c' => '',
+                       'xxrecursivetemplate-b-B1' => 'X',
+                       'xxrecursivetemplate-b-B3' => 'Y',
+                       'xxrecursivetemplate-b-B4' => '?',
+                       'xxemptytemplate-' => 'nope',
+                       'foo' => 'a|b|c',
+                       'xxfoo' => 'a|b|c',
+                       'errorformat' => 'raw',
+               ] );
+               $context = new DerivativeContext( RequestContext::getMain() );
+               $context->setRequest( $request );
+               $main = new ApiMain( $context );
+
+               $mock = $this->getMockBuilder( ApiBase::class )
+                       ->setConstructorArgs( [ $main, 'test', 'xx' ] )
+                       ->setMethods( [ 'getAllowedParams' ] )
+                       ->getMockForAbstractClass();
+               $mock->method( 'getAllowedParams' )->willReturn( [
+                       'notexists' => null,
+                       'exists' => null,
+                       'multi' => [
+                               ApiBase::PARAM_ISMULTI => true,
+                       ],
+                       'empty' => [
+                               ApiBase::PARAM_ISMULTI => true,
+                       ],
+                       'template-{m}' => [
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_TEMPLATE_VARS => [ 'm' => 'multi' ],
+                       ],
+                       'recursivetemplate-{m}-{t}' => [
+                               ApiBase::PARAM_TEMPLATE_VARS => [ 't' => 'template-{m}', 'm' => 'multi' ],
+                       ],
+                       'emptytemplate-{m}' => [
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_TEMPLATE_VARS => [ 'm' => 'empty' ],
+                       ],
+                       'badtemplate-{e}' => [
+                               ApiBase::PARAM_TEMPLATE_VARS => [ 'e' => 'exists' ],
+                       ],
+                       'badtemplate2-{e}' => [
+                               ApiBase::PARAM_TEMPLATE_VARS => [ 'e' => 'badtemplate2-{e}' ],
+                       ],
+                       'badtemplate3-{x}' => [
+                               ApiBase::PARAM_TEMPLATE_VARS => [ 'x' => 'foo' ],
+                       ],
+               ] );
+
+               $this->assertEquals( [
+                       'notexists' => null,
+                       'exists' => 'exists!',
+                       'multi' => [ 'a', 'b', 'c', 'd', '{bad}' ],
+                       'empty' => [],
+                       'template-a' => [ 'A!' ],
+                       'template-b' => [ 'B1', 'B2', 'B3' ],
+                       'template-c' => [],
+                       'template-d' => null,
+                       'recursivetemplate-a-A!' => null,
+                       'recursivetemplate-b-B1' => 'X',
+                       'recursivetemplate-b-B2' => null,
+                       'recursivetemplate-b-B3' => 'Y',
+               ], $mock->extractRequestParams() );
+
+               $used = TestingAccessWrapper::newFromObject( $main )->getParamsUsed();
+               sort( $used );
+               $this->assertEquals( [
+                       'xxempty',
+                       'xxexists',
+                       'xxmulti',
+                       'xxnotexists',
+                       'xxrecursivetemplate-a-A!',
+                       'xxrecursivetemplate-b-B1',
+                       'xxrecursivetemplate-b-B2',
+                       'xxrecursivetemplate-b-B3',
+                       'xxtemplate-a',
+                       'xxtemplate-b',
+                       'xxtemplate-c',
+                       'xxtemplate-d',
+               ], $used );
+
+               $warnings = $mock->getResult()->getResultData( 'warnings', [ 'Strip' => 'all' ] );
+               $this->assertCount( 1, $warnings );
+               $this->assertSame( 'ignoring-invalid-templated-value', $warnings[0]['code'] );
+       }
+
 }
index 5b43dd1..a95d5c1 100644 (file)
@@ -863,6 +863,65 @@ class ApiQueryRecentChangesIntegrationTest extends ApiTestCase {
                );
        }
 
+       public function testTitleParams() {
+               $page1 = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
+               $page2 = new TitleValue( 1, 'ApiQueryRecentChangesIntegrationTestPage2' );
+               $page3 = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage3' );
+               $this->doPageEdits(
+                       $this->getLoggedInTestUser(),
+                       [
+                               [
+                                       'target' => $page1,
+                                       'summary' => 'Create the page',
+                               ],
+                               [
+                                       'target' => $page2,
+                                       'summary' => 'Create the page',
+                               ],
+                               [
+                                       'target' => $page3,
+                                       'summary' => 'Create the page',
+                               ],
+                       ]
+               );
+
+               $result = $this->doListRecentChangesRequest(
+                       [
+                               'rctitle' => 'ApiQueryRecentChangesIntegrationTestPage',
+                               'rcprop' => 'title'
+                       ]
+               );
+
+               $result2 = $this->doListRecentChangesRequest(
+                       [
+                               'rctitle' => 'Talk:ApiQueryRecentChangesIntegrationTestPage2',
+                               'rcprop' => 'title'
+                       ]
+               );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'ns' => $page1->getNamespace(),
+                                       'title' => $this->getPrefixedText( $page1 )
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $result )
+               );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'ns' => $page2->getNamespace(),
+                                       'title' => $this->getPrefixedText( $page2 )
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $result2 )
+               );
+       }
+
        public function testStartEndParams() {
                $target = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
                $this->doPageEdit( $this->getLoggedInTestUser(), $target, 'Create the page' );
index 915fb5c..4438332 100644 (file)
@@ -109,7 +109,7 @@ class ApiFormatXmlTest extends ApiFormatTestBase {
                                [ 'xslt' => 'DoesNotExist' ] ],
                        [ [], '<?xml version="1.0"?><api><warnings><xml xml:space="preserve">Stylesheet should be in the MediaWiki namespace.</xml></warnings></api>',
                                [ 'xslt' => 'ApiFormatXmlTest' ] ],
-                       [ [], '<?xml version="1.0"?><api><warnings><xml xml:space="preserve">Stylesheet should have &quot;.xsl&quot; extension.</xml></warnings></api>',
+                       [ [], '<?xml version="1.0"?><api><warnings><xml xml:space="preserve">Stylesheet should have ".xsl" extension.</xml></warnings></api>',
                                [ 'xslt' => 'MediaWiki:ApiFormatXmlTest' ] ],
                        [ [],
                                '<?xml version="1.0"?><?xml-stylesheet href="' .
diff --git a/tests/phpunit/includes/api/query/ApiQueryUserContribsTest.php b/tests/phpunit/includes/api/query/ApiQueryUserContribsTest.php
new file mode 100644 (file)
index 0000000..1d0b471
--- /dev/null
@@ -0,0 +1,194 @@
+<?php
+
+/**
+ * @group API
+ * @group Database
+ * @group medium
+ * @covers ApiQueryUserContribs
+ */
+class ApiQueryUserContribsTest extends ApiTestCase {
+       public function addDBDataOnce() {
+               global $wgActorTableSchemaMigrationStage;
+
+               $reset = new \Wikimedia\ScopedCallback( function ( $v ) {
+                       global $wgActorTableSchemaMigrationStage;
+                       $wgActorTableSchemaMigrationStage = $v;
+                       $this->overrideMwServices();
+               }, [ $wgActorTableSchemaMigrationStage ] );
+               $wgActorTableSchemaMigrationStage = MIGRATION_WRITE_BOTH;
+               $this->overrideMwServices();
+
+               $users = [
+                       User::newFromName( '192.168.2.2', false ),
+                       User::newFromName( '192.168.2.1', false ),
+                       User::newFromName( '192.168.2.3', false ),
+                       User::createNew( __CLASS__ . ' B' ),
+                       User::createNew( __CLASS__ . ' A' ),
+                       User::createNew( __CLASS__ . ' C' ),
+                       User::newFromName( 'IW>' . __CLASS__, false ),
+               ];
+
+               $title = Title::newFromText( __CLASS__ );
+               $page = WikiPage::factory( $title );
+               for ( $i = 0; $i < 3; $i++ ) {
+                       foreach ( array_reverse( $users ) as $user ) {
+                               $status = $page->doEditContent(
+                                       ContentHandler::makeContent( "Test revision $user #$i", $title ), 'Test edit', 0, false, $user
+                               );
+                               if ( !$status->isOK() ) {
+                                       $this->fail( "Failed to edit $title: " . $status->getWikiText( false, false, 'en' ) );
+                               }
+                       }
+               }
+       }
+
+       /**
+        * @dataProvider provideSorting
+        * @param int $stage One of the MIGRATION_* constants for $wgActorTableSchemaMigrationStage
+        * @param array $params Extra parameters for the query
+        * @param bool $reverse Reverse order?
+        * @param int $revs Number of revisions to expect
+        */
+       public function testSorting( $stage, $params, $reverse, $revs ) {
+               if ( isset( $params['ucuserprefix'] ) &&
+                       ( $stage === MIGRATION_WRITE_BOTH || $stage === MIGRATION_WRITE_NEW ) &&
+                       $this->db->getType() === 'mysql' && $this->usesTemporaryTables()
+               ) {
+                       // https://bugs.mysql.com/bug.php?id=10327
+                       $this->markTestSkipped( 'MySQL bug 10327 - can\'t reopen temporary tables' );
+               }
+
+               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', $stage );
+               $this->overrideMwServices();
+
+               if ( isset( $params['ucuserids'] ) ) {
+                       $params['ucuserids'] = implode( '|', array_map( 'User::idFromName', $params['ucuserids'] ) );
+               }
+               if ( isset( $params['ucuser'] ) ) {
+                       $params['ucuser'] = implode( '|', $params['ucuser'] );
+               }
+
+               $sort = 'rsort';
+               if ( $reverse ) {
+                       $params['ucdir'] = 'newer';
+                       $sort = 'sort';
+               }
+
+               $params += [
+                       'action' => 'query',
+                       'list' => 'usercontribs',
+                       'ucprop' => 'ids',
+               ];
+
+               $apiResult = $this->doApiRequest( $params + [ 'uclimit' => 500 ] );
+               $this->assertArrayNotHasKey( 'continue', $apiResult[0] );
+               $this->assertArrayHasKey( 'query', $apiResult[0] );
+               $this->assertArrayHasKey( 'usercontribs', $apiResult[0]['query'] );
+
+               $count = 0;
+               $ids = [];
+               foreach ( $apiResult[0]['query']['usercontribs'] as $page ) {
+                       $count++;
+                       $ids[$page['user']][] = $page['revid'];
+               }
+               $this->assertSame( $revs, $count, 'Expected number of revisions' );
+               foreach ( $ids as $user => $revids ) {
+                       $sorted = $revids;
+                       call_user_func_array( $sort, [ &$sorted ] );
+                       $this->assertSame( $sorted, $revids, "IDs for $user are sorted" );
+               }
+
+               for ( $limit = 1; $limit < $revs; $limit++ ) {
+                       $continue = [];
+                       $count = 0;
+                       $batchedIds = [];
+                       while ( $continue !== null ) {
+                               $apiResult = $this->doApiRequest( $params + [ 'uclimit' => $limit ] + $continue );
+                               $this->assertArrayHasKey( 'query', $apiResult[0], "Batching with limit $limit" );
+                               $this->assertArrayHasKey( 'usercontribs', $apiResult[0]['query'],
+                                       "Batching with limit $limit" );
+                               $continue = isset( $apiResult[0]['continue'] ) ? $apiResult[0]['continue'] : null;
+                               foreach ( $apiResult[0]['query']['usercontribs'] as $page ) {
+                                       $count++;
+                                       $batchedIds[$page['user']][] = $page['revid'];
+                               }
+                               $this->assertLessThanOrEqual( $revs, $count, "Batching with limit $limit" );
+                       }
+                       $this->assertSame( $ids, $batchedIds, "Result set is the same when batching with limit $limit" );
+               }
+       }
+
+       public static function provideSorting() {
+               $users = [ __CLASS__ . ' A', __CLASS__ . ' B', __CLASS__ . ' C' ];
+               $users2 = [ __CLASS__ . ' A', __CLASS__ . ' B', __CLASS__ . ' D' ];
+               $ips = [ '192.168.2.1', '192.168.2.2', '192.168.2.3', '192.168.2.4' ];
+
+               foreach (
+                       [
+                               'old' => MIGRATION_OLD,
+                               'write both' => MIGRATION_WRITE_BOTH,
+                               'write new' => MIGRATION_WRITE_NEW,
+                               'new' => MIGRATION_NEW,
+                       ] as $stageName => $stage
+               ) {
+                       foreach ( [ false, true ] as $reverse ) {
+                               $name = $stageName . ( $reverse ? ', reverse' : '' );
+                               yield "Named users, $name" => [ $stage, [ 'ucuser' => $users ], $reverse, 9 ];
+                               yield "Named users including a no-edit user, $name" => [
+                                       $stage, [ 'ucuser' => $users2 ], $reverse, 6
+                               ];
+                               yield "IP users, $name" => [ $stage, [ 'ucuser' => $ips ], $reverse, 9 ];
+                               yield "All users, $name" => [
+                                       $stage, [ 'ucuser' => array_merge( $users, $ips ) ], $reverse, 18
+                               ];
+                               yield "User IDs, $name" => [ $stage, [ 'ucuserids' => $users ], $reverse, 9 ];
+                               yield "Users by prefix, $name" => [ $stage, [ 'ucuserprefix' => __CLASS__ ], $reverse, 9 ];
+                               yield "IPs by prefix, $name" => [ $stage, [ 'ucuserprefix' => '192.168.2.' ], $reverse, 9 ];
+                       }
+               }
+       }
+
+       /**
+        * @dataProvider provideInterwikiUser
+        * @param int $stage One of the MIGRATION_* constants for $wgActorTableSchemaMigrationStage
+        */
+       public function testInterwikiUser( $stage ) {
+               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', $stage );
+               $this->overrideMwServices();
+
+               $params = [
+                       'action' => 'query',
+                       'list' => 'usercontribs',
+                       'ucuser' => 'IW>' . __CLASS__,
+                       'ucprop' => 'ids',
+                       'uclimit' => 'max',
+               ];
+
+               $apiResult = $this->doApiRequest( $params );
+               $this->assertArrayNotHasKey( 'continue', $apiResult[0] );
+               $this->assertArrayHasKey( 'query', $apiResult[0] );
+               $this->assertArrayHasKey( 'usercontribs', $apiResult[0]['query'] );
+
+               $count = 0;
+               $ids = [];
+               foreach ( $apiResult[0]['query']['usercontribs'] as $page ) {
+                       $count++;
+                       $this->assertSame( 'IW>' . __CLASS__, $page['user'], 'Correct user returned' );
+                       $ids[] = $page['revid'];
+               }
+               $this->assertSame( 3, $count, 'Expected number of revisions' );
+               $sorted = $ids;
+               rsort( $sorted );
+               $this->assertSame( $sorted, $ids, "IDs are sorted" );
+       }
+
+       public static function provideInterwikiUser() {
+               return [
+                       'old' => [ MIGRATION_OLD ],
+                       'write both' => [ MIGRATION_WRITE_BOTH ],
+                       'write new' => [ MIGRATION_WRITE_NEW ],
+                       'new' => [ MIGRATION_NEW ],
+               ];
+       }
+
+}
diff --git a/tests/phpunit/includes/api/query/ApiQueryUserContributionsTest.php b/tests/phpunit/includes/api/query/ApiQueryUserContributionsTest.php
deleted file mode 100644 (file)
index ca6a929..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-<?php
-
-/**
- * @group API
- * @group Database
- * @group medium
- * @covers ApiQueryContributions
- */
-class ApiQueryContributionsTest extends ApiTestCase {
-       public function addDBDataOnce() {
-               global $wgActorTableSchemaMigrationStage;
-
-               $reset = new \Wikimedia\ScopedCallback( function ( $v ) {
-                       global $wgActorTableSchemaMigrationStage;
-                       $wgActorTableSchemaMigrationStage = $v;
-                       $this->overrideMwServices();
-               }, [ $wgActorTableSchemaMigrationStage ] );
-               $wgActorTableSchemaMigrationStage = MIGRATION_WRITE_BOTH;
-               $this->overrideMwServices();
-
-               $users = [
-                       User::newFromName( '192.168.2.2', false ),
-                       User::newFromName( '192.168.2.1', false ),
-                       User::newFromName( '192.168.2.3', false ),
-                       User::createNew( __CLASS__ . ' B' ),
-                       User::createNew( __CLASS__ . ' A' ),
-                       User::createNew( __CLASS__ . ' C' ),
-                       User::newFromName( 'IW>' . __CLASS__, false ),
-               ];
-
-               $title = Title::newFromText( __CLASS__ );
-               $page = WikiPage::factory( $title );
-               for ( $i = 0; $i < 3; $i++ ) {
-                       foreach ( array_reverse( $users ) as $user ) {
-                               $status = $page->doEditContent(
-                                       ContentHandler::makeContent( "Test revision $user #$i", $title ), 'Test edit', 0, false, $user
-                               );
-                               if ( !$status->isOK() ) {
-                                       $this->fail( "Failed to edit $title: " . $status->getWikiText( false, false, 'en' ) );
-                               }
-                       }
-               }
-       }
-
-       /**
-        * @dataProvider provideSorting
-        * @param int $stage One of the MIGRATION_* constants for $wgActorTableSchemaMigrationStage
-        * @param array $params Extra parameters for the query
-        * @param bool $reverse Reverse order?
-        * @param int $revs Number of revisions to expect
-        */
-       public function testSorting( $stage, $params, $reverse, $revs ) {
-               if ( isset( $params['ucuserprefix'] ) &&
-                       ( $stage === MIGRATION_WRITE_BOTH || $stage === MIGRATION_WRITE_NEW ) &&
-                       $this->db->getType() === 'mysql' && $this->usesTemporaryTables()
-               ) {
-                       // https://bugs.mysql.com/bug.php?id=10327
-                       $this->markTestSkipped( 'MySQL bug 10327 - can\'t reopen temporary tables' );
-               }
-
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', $stage );
-               $this->overrideMwServices();
-
-               if ( isset( $params['ucuserids'] ) ) {
-                       $params['ucuserids'] = implode( '|', array_map( 'User::idFromName', $params['ucuserids'] ) );
-               }
-               if ( isset( $params['ucuser'] ) ) {
-                       $params['ucuser'] = implode( '|', $params['ucuser'] );
-               }
-
-               $sort = 'rsort';
-               if ( $reverse ) {
-                       $params['ucdir'] = 'newer';
-                       $sort = 'sort';
-               }
-
-               $params += [
-                       'action' => 'query',
-                       'list' => 'usercontribs',
-                       'ucprop' => 'ids',
-               ];
-
-               $apiResult = $this->doApiRequest( $params + [ 'uclimit' => 500 ] );
-               $this->assertArrayNotHasKey( 'continue', $apiResult[0] );
-               $this->assertArrayHasKey( 'query', $apiResult[0] );
-               $this->assertArrayHasKey( 'usercontribs', $apiResult[0]['query'] );
-
-               $count = 0;
-               $ids = [];
-               foreach ( $apiResult[0]['query']['usercontribs'] as $page ) {
-                       $count++;
-                       $ids[$page['user']][] = $page['revid'];
-               }
-               $this->assertSame( $revs, $count, 'Expected number of revisions' );
-               foreach ( $ids as $user => $revids ) {
-                       $sorted = $revids;
-                       call_user_func_array( $sort, [ &$sorted ] );
-                       $this->assertSame( $sorted, $revids, "IDs for $user are sorted" );
-               }
-
-               for ( $limit = 1; $limit < $revs; $limit++ ) {
-                       $continue = [];
-                       $count = 0;
-                       $batchedIds = [];
-                       while ( $continue !== null ) {
-                               $apiResult = $this->doApiRequest( $params + [ 'uclimit' => $limit ] + $continue );
-                               $this->assertArrayHasKey( 'query', $apiResult[0], "Batching with limit $limit" );
-                               $this->assertArrayHasKey( 'usercontribs', $apiResult[0]['query'],
-                                       "Batching with limit $limit" );
-                               $continue = isset( $apiResult[0]['continue'] ) ? $apiResult[0]['continue'] : null;
-                               foreach ( $apiResult[0]['query']['usercontribs'] as $page ) {
-                                       $count++;
-                                       $batchedIds[$page['user']][] = $page['revid'];
-                               }
-                               $this->assertLessThanOrEqual( $revs, $count, "Batching with limit $limit" );
-                       }
-                       $this->assertSame( $ids, $batchedIds, "Result set is the same when batching with limit $limit" );
-               }
-       }
-
-       public static function provideSorting() {
-               $users = [ __CLASS__ . ' A', __CLASS__ . ' B', __CLASS__ . ' C' ];
-               $users2 = [ __CLASS__ . ' A', __CLASS__ . ' B', __CLASS__ . ' D' ];
-               $ips = [ '192.168.2.1', '192.168.2.2', '192.168.2.3', '192.168.2.4' ];
-
-               foreach (
-                       [
-                               'old' => MIGRATION_OLD,
-                               'write both' => MIGRATION_WRITE_BOTH,
-                               'write new' => MIGRATION_WRITE_NEW,
-                               'new' => MIGRATION_NEW,
-                       ] as $stageName => $stage
-               ) {
-                       foreach ( [ false, true ] as $reverse ) {
-                               $name = $stageName . ( $reverse ? ', reverse' : '' );
-                               yield "Named users, $name" => [ $stage, [ 'ucuser' => $users ], $reverse, 9 ];
-                               yield "Named users including a no-edit user, $name" => [
-                                       $stage, [ 'ucuser' => $users2 ], $reverse, 6
-                               ];
-                               yield "IP users, $name" => [ $stage, [ 'ucuser' => $ips ], $reverse, 9 ];
-                               yield "All users, $name" => [
-                                       $stage, [ 'ucuser' => array_merge( $users, $ips ) ], $reverse, 18
-                               ];
-                               yield "User IDs, $name" => [ $stage, [ 'ucuserids' => $users ], $reverse, 9 ];
-                               yield "Users by prefix, $name" => [ $stage, [ 'ucuserprefix' => __CLASS__ ], $reverse, 9 ];
-                               yield "IPs by prefix, $name" => [ $stage, [ 'ucuserprefix' => '192.168.2.' ], $reverse, 9 ];
-                       }
-               }
-       }
-
-       /**
-        * @dataProvider provideInterwikiUser
-        * @param int $stage One of the MIGRATION_* constants for $wgActorTableSchemaMigrationStage
-        */
-       public function testInterwikiUser( $stage ) {
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', $stage );
-               $this->overrideMwServices();
-
-               $params = [
-                       'action' => 'query',
-                       'list' => 'usercontribs',
-                       'ucuser' => 'IW>' . __CLASS__,
-                       'ucprop' => 'ids',
-                       'uclimit' => 'max',
-               ];
-
-               $apiResult = $this->doApiRequest( $params );
-               $this->assertArrayNotHasKey( 'continue', $apiResult[0] );
-               $this->assertArrayHasKey( 'query', $apiResult[0] );
-               $this->assertArrayHasKey( 'usercontribs', $apiResult[0]['query'] );
-
-               $count = 0;
-               $ids = [];
-               foreach ( $apiResult[0]['query']['usercontribs'] as $page ) {
-                       $count++;
-                       $this->assertSame( 'IW>' . __CLASS__, $page['user'], 'Correct user returned' );
-                       $ids[] = $page['revid'];
-               }
-               $this->assertSame( 3, $count, 'Expected number of revisions' );
-               $sorted = $ids;
-               rsort( $sorted );
-               $this->assertSame( $sorted, $ids, "IDs are sorted" );
-       }
-
-       public static function provideInterwikiUser() {
-               return [
-                       'old' => [ MIGRATION_OLD ],
-                       'write both' => [ MIGRATION_WRITE_BOTH ],
-                       'write new' => [ MIGRATION_WRITE_NEW ],
-                       'new' => [ MIGRATION_NEW ],
-               ];
-       }
-
-}
index f963ad9..12e8a49 100644 (file)
@@ -199,7 +199,7 @@ class ThrottlerTest extends \MediaWikiTestCase {
                $logger->expects( $this->once() )->method( 'log' )->with( $this->anything(), $this->anything(), [
                        'throttle' => 'custom',
                        'index' => 0,
-                       'ip' => '1.2.3.4',
+                       'ipKey' => '1.2.3.4',
                        'username' => 'SomeUser',
                        'count' => 1,
                        'expiry' => 10,
diff --git a/tests/phpunit/includes/collation/CollationFaTest.php b/tests/phpunit/includes/collation/CollationFaTest.php
deleted file mode 100644 (file)
index f745541..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-
-/**
- * @covers CollationFa
- */
-class CollationFaTest extends MediaWikiTestCase {
-
-       /*
-        * The ordering is a weird hack designed to work only with a very
-        * specific version of libicu, and as such can't really be unit tested
-        * against a random version of libicu
-        */
-
-       public function setUp() {
-               parent::setUp();
-               $this->checkPHPExtension( 'intl' );
-       }
-
-       /**
-        * @dataProvider provideGetFirstLetter
-        */
-       public function testGetFirstLetter( $letter, $str ) {
-               $coll = new CollationFa;
-               $this->assertEquals( $letter, $coll->getFirstLetter( $str ), $str );
-       }
-
-       public function provideGetFirstLetter() {
-               return [
-                       [
-                               '۷',
-                               '۷'
-                       ],
-                       [
-                               'ا',
-                               'ا'
-                       ],
-                       [
-                               'ا',
-                               'ایران'
-                       ],
-                       [
-                               'ب',
-                               'برلین'
-                       ],
-                       [
-                               'و',
-                               'واو'
-                       ],
-                       [ "\xd8\xa7", "\xd8\xa7Foo" ],
-                       [ "\xd9\x88", "\xd9\x88Foo" ],
-                       [ "\xd9\xb2", "\xd9\xb2Foo" ],
-                       [ "\xd9\xb3", "\xd9\xb3Foo" ],
-               ];
-       }
-}
index a84cc04..0395bff 100644 (file)
@@ -153,64 +153,75 @@ class LBFactoryTest extends MediaWikiTestCase {
                $lb->closeAll();
        }
 
-       public function testLBFactoryMulti() {
-               global $wgDBserver, $wgDBname, $wgDBuser, $wgDBpassword, $wgDBtype, $wgSQLiteDataDir;
-
-               $factory = new LBFactoryMulti( [
-                       'sectionsByDB' => [
-                               's1wiki' => 's1',
-                       ],
-                       'sectionLoads' => [
-                               's1' => [
-                                       'test-db3' => 0,
-                                       'test-db4' => 100,
-                               ],
-                               'DEFAULT' => [
-                                       'test-db1' => 0,
-                                       'test-db2' => 100,
-                               ]
-                       ],
-                       'serverTemplate' => [
-                               'dbname'      => $wgDBname,
-                               'user'        => $wgDBuser,
-                               'password'    => $wgDBpassword,
-                               'type'        => $wgDBtype,
-                               'dbDirectory' => $wgSQLiteDataDir,
-                               'flags'       => DBO_DEFAULT
-                       ],
-                       'hostsByName' => [
-                               'test-db1'  => $wgDBserver,
-                               'test-db2'  => $wgDBserver,
-                               'test-db3'  => $wgDBserver,
-                               'test-db4'  => $wgDBserver
-                       ],
-                       'loadMonitorClass' => LoadMonitorNull::class
-               ] );
-               $lb = $factory->getMainLB();
+       public function testLBFactoryMultiConns() {
+               $factory = $this->newLBFactoryMultiLBs();
 
-               $dbw = $lb->getConnection( DB_MASTER );
+               $dbw = $factory->getMainLB()->getConnection( DB_MASTER );
                $this->assertTrue( $dbw->getLBInfo( 'master' ), 'master shows as master' );
 
-               $dbr = $lb->getConnection( DB_REPLICA );
+               $dbr = $factory->getMainLB()->getConnection( DB_REPLICA );
                $this->assertTrue( $dbr->getLBInfo( 'replica' ), 'slave shows as slave' );
 
-               // Test that LoadBalancer instances made during commitMasterChanges() do not throw
-               // DBTransactionError due to transaction ROUND_* stages being mismatched.
+               // Destructor should trigger without round stage errors
+               unset( $factory );
+       }
+
+       public function testLBFactoryMultiRoundCallbacks() {
+               $called = 0;
+               $countLBsFunc = function ( LBFactoryMulti $factory ) {
+                       $count = 0;
+                       $factory->forEachLB( function () use ( &$count ) {
+                               ++$count;
+                       } );
+
+                       return $count;
+               };
+
+               $factory = $this->newLBFactoryMultiLBs();
+               $this->assertEquals( 0, $countLBsFunc( $factory ) );
+               $dbw = $factory->getMainLB()->getConnection( DB_MASTER );
+               $this->assertEquals( 1, $countLBsFunc( $factory ) );
+               // Test that LoadBalancer instances made during pre-commit callbacks in do not
+               // throw DBTransactionError due to transaction ROUND_* stages being mismatched.
                $factory->beginMasterChanges( __METHOD__ );
-               $dbw->onTransactionPreCommitOrIdle( function () use ( $factory ) {
+               $dbw->onTransactionPreCommitOrIdle( function () use ( $factory, &$called ) {
+                       ++$called;
                        // Trigger s1 LoadBalancer instantiation during "finalize" stage.
                        // There is no s1wiki DB to select so it is not in getConnection(),
                        // but this fools getMainLB() at least.
                        $factory->getMainLB( 's1wiki' )->getConnection( DB_MASTER );
                } );
                $factory->commitMasterChanges( __METHOD__ );
+               $this->assertEquals( 1, $called );
+               $this->assertEquals( 2, $countLBsFunc( $factory ) );
+               $factory->shutdown();
+               $factory->closeAll();
 
-               $count = 0;
-               $factory->forEachLB( function () use ( &$count ) {
-                       ++$count;
+               $called = 0;
+               $factory = $this->newLBFactoryMultiLBs();
+               $this->assertEquals( 0, $countLBsFunc( $factory ) );
+               $dbw = $factory->getMainLB()->getConnection( DB_MASTER );
+               $this->assertEquals( 1, $countLBsFunc( $factory ) );
+               // Test that LoadBalancer instances made during pre-commit callbacks in do not
+               // throw DBTransactionError due to transaction ROUND_* stages being mismatched.hrow
+               // DBTransactionError due to transaction ROUND_* stages being mismatched.
+               $factory->beginMasterChanges( __METHOD__ );
+               $dbw->query( "SELECT 1 as t", __METHOD__ );
+               $dbw->onTransactionResolution( function () use ( $factory, &$called ) {
+                       ++$called;
+                       // Trigger s1 LoadBalancer instantiation during "finalize" stage.
+                       // There is no s1wiki DB to select so it is not in getConnection(),
+                       // but this fools getMainLB() at least.
+                       $factory->getMainLB( 's1wiki' )->getConnection( DB_MASTER );
                } );
-               $this->assertEquals( 2, $count );
+               $factory->commitMasterChanges( __METHOD__ );
+               $this->assertEquals( 1, $called );
+               $this->assertEquals( 2, $countLBsFunc( $factory ) );
+               $factory->shutdown();
+               $factory->closeAll();
 
+               $factory = $this->newLBFactoryMultiLBs();
+               $dbw = $factory->getMainLB()->getConnection( DB_MASTER );
                // DBTransactionError should not be thrown
                $ran = 0;
                $dbw->onTransactionPreCommitOrIdle( function () use ( &$ran ) {
@@ -223,6 +234,41 @@ class LBFactoryTest extends MediaWikiTestCase {
                $factory->closeAll();
        }
 
+       private function newLBFactoryMultiLBs() {
+               global $wgDBserver, $wgDBname, $wgDBuser, $wgDBpassword, $wgDBtype, $wgSQLiteDataDir;
+
+               return new LBFactoryMulti( [
+                       'sectionsByDB' => [
+                               's1wiki' => 's1',
+                       ],
+                       'sectionLoads' => [
+                               's1' => [
+                                       'test-db3' => 0,
+                                       'test-db4' => 100,
+                               ],
+                               'DEFAULT' => [
+                                       'test-db1' => 0,
+                                       'test-db2' => 100,
+                               ]
+                       ],
+                       'serverTemplate' => [
+                               'dbname' => $wgDBname,
+                               'user' => $wgDBuser,
+                               'password' => $wgDBpassword,
+                               'type' => $wgDBtype,
+                               'dbDirectory' => $wgSQLiteDataDir,
+                               'flags' => DBO_DEFAULT
+                       ],
+                       'hostsByName' => [
+                               'test-db1' => $wgDBserver,
+                               'test-db2' => $wgDBserver,
+                               'test-db3' => $wgDBserver,
+                               'test-db4' => $wgDBserver
+                       ],
+                       'loadMonitorClass' => LoadMonitorNull::class
+               ] );
+       }
+
        /**
         * @covers \Wikimedia\Rdbms\ChronologyProtector
         */
@@ -560,4 +606,38 @@ class LBFactoryTest extends MediaWikiTestCase {
                        return $db->addIdentifierQuotes( $table );
                }
        }
+
+       /**
+        * @covers \Wikimedia\Rdbms\LBFactory::makeCookieValueFromCPIndex()
+        * @covers \Wikimedia\Rdbms\LBFactory::getCPIndexFromCookieValue()
+        */
+       public function testCPPosIndexCookieValues() {
+               $this->assertEquals( '3@542', LBFactory::makeCookieValueFromCPIndex( 3, 542 ) );
+
+               $time = 1526522031;
+               $this->assertSame(
+                       5,
+                       LBFactory::getCPIndexFromCookieValue( "5", $time - 10 )
+               );
+               $this->assertSame(
+                       null,
+                       LBFactory::getCPIndexFromCookieValue( "0", $time - 10 )
+               );
+               $this->assertSame(
+                       2,
+                       LBFactory::getCPIndexFromCookieValue( "2@$time", $time - 10 )
+               );
+               $this->assertSame(
+                       2,
+                       LBFactory::getCPIndexFromCookieValue( "2@$time", $time + 9 - 10 )
+               );
+               $this->assertSame(
+                       null,
+                       LBFactory::getCPIndexFromCookieValue( "0@$time", $time + 9 - 10 )
+               );
+               $this->assertSame(
+                       null,
+                       LBFactory::getCPIndexFromCookieValue( "2@$time", $time + 11 - 10 )
+               );
+       }
 }
index e20cf94..05e15a3 100644 (file)
@@ -3,7 +3,7 @@
 /**
  * @covers HTMLForm
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Gergő Tisza
  * @author Thiemo Mättig
  */
index f80d18c..cd24be4 100644 (file)
@@ -515,8 +515,8 @@ class MWHttpRequestTester extends MWHttpRequest {
                if ( !Http::$httpEngine ) {
                        Http::$httpEngine = function_exists( 'curl_init' ) ? 'curl' : 'php';
                } elseif ( Http::$httpEngine == 'curl' && !function_exists( 'curl_init' ) ) {
-                       throw new DomainException( __METHOD__ . ': curl (http://php.net/curl) is not installed, but' .
-                               'Http::$httpEngine is set to "curl"' );
+                       throw new DomainException( __METHOD__ . ': curl (https://secure.php.net/curl) is not ' .
+                               'installed, but Http::$httpEngine is set to "curl"' );
                }
 
                switch ( Http::$httpEngine ) {
@@ -526,7 +526,7 @@ class MWHttpRequestTester extends MWHttpRequest {
                                if ( !wfIniGetBool( 'allow_url_fopen' ) ) {
                                        throw new DomainException( __METHOD__ .
                                                ': allow_url_fopen needs to be enabled for pure PHP HTTP requests to work. '
-                                                       . 'If possible, curl should be used instead. See http://php.net/curl.' );
+                                                       . 'If possible, curl should be used instead. See https://secure.php.net/curl.' );
                                }
 
                                return new PhpHttpRequestTester( $url, $options, $caller );
index bf8603d..b2e7ea4 100644 (file)
@@ -5,7 +5,7 @@
  *
  * @group JobQueue
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Thiemo Kreuz
  */
 class JobQueueMemoryTest extends PHPUnit\Framework\TestCase {
index 5960a16..1f73324 100644 (file)
@@ -6,7 +6,7 @@
  * @group JobQueue
  * @group Database
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Addshore
  */
 class CategoryMembershipChangeJobTest extends MediaWikiTestCase {
index 6ae7d60..27cae8a 100644 (file)
@@ -7,7 +7,7 @@ use MediaWiki\MediaWikiServices;
  * @group JobQueue
  * @group Database
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Addshore
  */
 class ClearUserWatchlistJobTest extends MediaWikiTestCase {
index dabf66b..354dae2 100644 (file)
@@ -35,7 +35,7 @@ class CSSMinTest extends MediaWikiTestCase {
        public static function provideSerializeStringValue() {
                return [
                        [ 'Hello World!', '"Hello World!"' ],
-                       [ "Null\0Null", "\"Null\\fffd Null\"" ],
+                       [ "Null\0Null", "\"Null\xEF\xBF\xBDNull\"" ],
                        [ '"', '"\\""' ],
                        [ "'", '"\'"' ],
                        [ "\\", '"\\\\"' ],
@@ -199,6 +199,9 @@ class CSSMinTest extends MediaWikiTestCase {
                        [ true, '//example.org/x.y.z/image.png' ],
                        [ true, '//localhost/styles.css?query=yes' ],
                        [ true, 'data:image/gif;base64,R0lGODlhAQABAIAAAP8AADAAACwAAAAAAQABAAACAkQBADs=' ],
+                       [ false, '' ],
+                       [ false, '/' ],
+                       [ true, '//' ],
                        [ false, 'x.gif' ],
                        [ false, '/x.gif' ],
                        [ false, './x.gif' ],
@@ -217,6 +220,9 @@ class CSSMinTest extends MediaWikiTestCase {
 
        public static function provideIsLocalUrls() {
                return [
+                       [ false, '' ],
+                       [ false, '/' ],
+                       [ false, '//' ],
                        [ false, 'x.gif' ],
                        [ true, '/x.gif' ],
                        [ false, './x.gif' ],
index 9702c82..9ec53c0 100644 (file)
@@ -325,6 +325,7 @@ class IPTest extends PHPUnit\Framework\TestCase {
                        [ '0.0.0.0', '0.0.0.0' ],
                        [ '0.0.0.0', '00.00.00.00' ],
                        [ '0.0.0.0', '000.000.000.000' ],
+                       [ '0.0.0.0/24', '000.000.000.000/24' ],
                        [ '141.0.11.253', '141.000.011.253' ],
                        [ '1.2.4.5', '1.2.4.5' ],
                        [ '1.2.4.5', '01.02.04.05' ],
index 826957e..4b3ba07 100644 (file)
@@ -44,13 +44,6 @@ class IPTCTest extends MediaWikiTestCase {
         * @covers IPTC::parse
         */
        public function testIPTCParseForcedUTFButInvalid() {
-               if ( version_compare( PHP_VERSION, '5.5.26', '<' )
-                       || ( version_compare( PHP_VERSION, '5.6.0', '>' )
-                               && version_compare( PHP_VERSION, '5.6.10', '<' )
-                       )
-               ) {
-                       $this->markTestSkipped( 'Test fails on pre-PHP 5.5.25. See T124574/T39665 for details.' );
-               }
                $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x11\x1c\x02\x19\x00\x04\xC3\xC3\xC3\xB8"
                        . "\x1c\x01\x5A\x00\x03\x1B\x25\x47";
                $res = IPTC::parse( $iptcData );
index e2ed1d5..8c61b03 100644 (file)
@@ -25,17 +25,16 @@ class ParserOptionsTest extends MediaWikiTestCase {
        }
 
        protected function setUp() {
-               global $wgHooks;
-
                parent::setUp();
                self::clearCache();
 
                $this->setMwGlobals( [
                        'wgRenderHashAppend' => '',
-                       'wgHooks' => [
-                               'PageRenderingHash' => [],
-                       ] + $wgHooks,
                ] );
+
+               // This is crazy, but registering false, null, or other falsey values
+               // as a hook callback "works".
+               $this->setTemporaryHook( 'PageRenderingHash', null );
        }
 
        protected function tearDown() {
@@ -84,17 +83,13 @@ class ParserOptionsTest extends MediaWikiTestCase {
         * @param string $expect Expected value
         * @param array $options Options to set
         * @param array $globals Globals to set
+        * @param callable|null $hookFunc PageRenderingHash hook function
         */
-       public function testOptionsHash( $usedOptions, $expect, $options, $globals = [] ) {
-               global $wgHooks;
-
-               $globals += [
-                       'wgHooks' => [],
-               ];
-               $globals['wgHooks'] += [
-                       'PageRenderingHash' => [],
-               ] + $wgHooks;
+       public function testOptionsHash(
+               $usedOptions, $expect, $options, $globals = [], $hookFunc = null
+       ) {
                $this->setMwGlobals( $globals );
+               $this->setTemporaryHook( 'PageRenderingHash', $hookFunc );
 
                $popt = ParserOptions::newCanonical();
                foreach ( $options as $name => $value ) {
@@ -129,14 +124,50 @@ class ParserOptionsTest extends MediaWikiTestCase {
                                [],
                                'canonical!wgRenderHashAppend!onPageRenderingHash',
                                [],
-                               [
-                                       'wgRenderHashAppend' => '!wgRenderHashAppend',
-                                       'wgHooks' => [ 'PageRenderingHash' => [ [ __CLASS__ . '::onPageRenderingHash' ] ] ],
-                               ]
+                               [ 'wgRenderHashAppend' => '!wgRenderHashAppend' ],
+                               [ __CLASS__ . '::onPageRenderingHash' ],
                        ],
                ];
        }
 
+       public function testUsedLazyOptionsInHash() {
+               $this->setTemporaryHook( 'ParserOptionsRegister',
+                       function ( &$defaults, &$inCacheKey, &$lazyOptions ) {
+                               $lazyFuncs = $this->getMockBuilder( stdClass::class )
+                                       ->setMethods( [ 'neverCalled', 'calledOnce' ] )
+                                       ->getMock();
+                               $lazyFuncs->expects( $this->never() )->method( 'neverCalled' );
+                               $lazyFuncs->expects( $this->once() )->method( 'calledOnce' )->willReturn( 'value' );
+
+                               $defaults += [
+                                       'opt1' => null,
+                                       'opt2' => null,
+                                       'opt3' => null,
+                               ];
+                               $inCacheKey += [
+                                       'opt1' => true,
+                                       'opt2' => true,
+                               ];
+                               $lazyOptions += [
+                                       'opt1' => [ $lazyFuncs, 'calledOnce' ],
+                                       'opt2' => [ $lazyFuncs, 'neverCalled' ],
+                                       'opt3' => [ $lazyFuncs, 'neverCalled' ],
+                               ];
+                       }
+               );
+
+               self::clearCache();
+
+               $popt = ParserOptions::newCanonical();
+               $popt->registerWatcher( function () {
+                       $this->fail( 'Watcher should not have been called' );
+               } );
+               $this->assertSame( 'opt1=value', $popt->optionsHash( [ 'opt1', 'opt3' ] ) );
+
+               // Second call to see that opt1 isn't resolved a second time
+               $this->assertSame( 'opt1=value', $popt->optionsHash( [ 'opt1', 'opt3' ] ) );
+       }
+
        public static function onPageRenderingHash( &$confstr ) {
                $confstr .= '!onPageRenderingHash';
        }
@@ -192,10 +223,7 @@ class ParserOptionsTest extends MediaWikiTestCase {
        }
 
        public function testAllCacheVaryingOptions() {
-               global $wgHooks;
-
-               // $wgHooks is already saved in self::setUp(), so we can modify it freely here
-               $wgHooks['ParserOptionsRegister'] = [];
+               $this->setTemporaryHook( 'ParserOptionsRegister', null );
                $this->assertSame( [
                        'dateformat', 'numberheadings', 'printable', 'stubthreshold',
                        'thumbsize', 'userlang'
@@ -203,7 +231,7 @@ class ParserOptionsTest extends MediaWikiTestCase {
 
                self::clearCache();
 
-               $wgHooks['ParserOptionsRegister'][] = function ( &$defaults, &$inCacheKey ) {
+               $this->setTemporaryHook( 'ParserOptionsRegister', function ( &$defaults, &$inCacheKey ) {
                        $defaults += [
                                'foo' => 'foo',
                                'bar' => 'bar',
@@ -213,7 +241,7 @@ class ParserOptionsTest extends MediaWikiTestCase {
                                'foo' => true,
                                'bar' => false,
                        ];
-               };
+               } );
                $this->assertSame( [
                        'dateformat', 'foo', 'numberheadings', 'printable', 'stubthreshold',
                        'thumbsize', 'userlang'
index 7dfb3cf..5ddbe27 100644 (file)
@@ -156,4 +156,21 @@ class PasswordPolicyChecksTest extends MediaWikiTestCase {
                $status = PasswordPolicyChecks::checkPopularPasswordBlacklist( PHP_INT_MAX, $user, $password );
                $this->assertSame( $expected, $status->isGood() );
        }
+
+       /**
+        * Verify that all password policy description messages actually exist.
+        * Messages used on Special:PasswordPolicies
+        */
+       public function testPasswordPolicyDescriptionsExist() {
+               global $wgPasswordPolicy;
+               $lang = Language::factory( 'en' );
+
+               foreach ( array_keys( $wgPasswordPolicy['checks'] ) as $check ) {
+                       $msgKey = 'passwordpolicies-policy-' . strtolower( $check );
+                       $this->assertTrue(
+                               wfMessage( $msgKey )->useDatabase( false )->inLanguage( $lang )->exists(),
+                               "Message '$msgKey' required by '$check' must exist"
+                       );
+               }
+       }
 }
index 62ab44c..9a8608f 100644 (file)
@@ -66,7 +66,7 @@ class DefaultPreferencesFactoryTest extends MediaWikiTestCase {
        public function testGetForm() {
                $testUser = $this->getTestUser();
                $form = $this->getPreferencesFactory()->getForm( $testUser->getUser(), $this->context );
-               $this->assertInstanceOf( PreferencesForm::class, $form );
+               $this->assertInstanceOf( PreferencesFormLegacy::class, $form );
                $this->assertCount( 5, $form->getPreferenceSections() );
        }
 
index d69ad59..355f4ef 100644 (file)
@@ -78,6 +78,15 @@ class ExtensionJsonValidatorTest extends MediaWikiTestCase {
                                'good.json',
                                true
                        ],
+                       [
+                               'bad_url.json', 'bad_url.json did not pass validation.
+[url] Should use HTTPS for www.mediawiki.org URLs'
+                       ],
+                       [
+                               'bad_url2.json', 'bad_url2.json did not pass validation.
+[url] Should use www.mediawiki.org domain
+[url] Should use HTTPS for www.mediawiki.org URLs'
+                       ]
                ];
        }
 
index 67bc088..a372c8c 100644 (file)
@@ -51,6 +51,26 @@ class ExtensionRegistryTest extends MediaWikiTestCase {
                $registry->loadFromQueue();
        }
 
+       public function testLoadFromQueue() {
+               $registry = new ExtensionRegistry();
+               $registry->queue( "{$this->dataDir}/good.json" );
+               $registry->loadFromQueue();
+               $this->assertArrayHasKey( 'FooBar', $registry->getAllThings() );
+               $this->assertTrue( $registry->isLoaded( 'FooBar' ) );
+               $this->assertSame( [ 'test' ], $registry->getAttribute( 'FooBarAttr' ) );
+               $this->assertSame( [], $registry->getAttribute( 'NotLoadedAttr' ) );
+       }
+
+       /**
+        * @expectedException PHPUnit_Framework_Error
+        */
+       public function testReadFromQueue_nonexistent() {
+               $registry = new ExtensionRegistry();
+               $registry->readFromQueue( [
+                       __DIR__ . '/doesnotexist.json' => 1
+               ] );
+       }
+
        /**
         * @dataProvider provideExportExtractedDataGlobals
         */
index ea3d199..7cd6983 100644 (file)
@@ -72,6 +72,10 @@ class ResourceLoaderClientHtmlTest extends PHPUnit\Framework\TestCase {
                                'shouldEmbed' => true,
                                'styles' => '.shouldembed{}',
                        ],
+                       'test.styles.deprecated' => [
+                               'type' => ResourceLoaderModule::LOAD_STYLES,
+                               'deprecated' => 'Deprecation message.',
+                       ],
 
                        'test.scripts' => [],
                        'test.scripts.user' => [ 'group' => 'user' ],
@@ -125,6 +129,7 @@ class ResourceLoaderClientHtmlTest extends PHPUnit\Framework\TestCase {
                        'test.styles.private',
                        'test.styles.pure',
                        'test.styles.shouldembed',
+                       'test.styles.deprecated',
                        'test.unregistered.styles',
                ] );
                $client->setModuleScripts( [
@@ -145,6 +150,7 @@ class ResourceLoaderClientHtmlTest extends PHPUnit\Framework\TestCase {
                                'test.styles.user.empty' => 'ready',
                                'test.styles.private' => 'ready',
                                'test.styles.shouldembed' => 'ready',
+                               'test.styles.deprecated' => 'ready',
                                'test.scripts' => 'loading',
                                'test.scripts.user' => 'loading',
                                'test.scripts.user.empty' => 'ready',
@@ -155,6 +161,7 @@ class ResourceLoaderClientHtmlTest extends PHPUnit\Framework\TestCase {
                        ],
                        'styles' => [
                                'test.styles.pure',
+                               'test.styles.deprecated',
                        ],
                        'scripts' => [
                                'test.scripts',
@@ -169,6 +176,13 @@ class ResourceLoaderClientHtmlTest extends PHPUnit\Framework\TestCase {
                                        'test.user',
                                ],
                        ],
+                       'styleDeprecations' => [
+                               Xml::encodeJsCall(
+                                       'mw.log.warn',
+                                       [ 'This page is using the deprecated ResourceLoader module "test.styles.deprecated".
+Deprecation message.' ]
+                               )
+                       ],
                ];
 
                $access = TestingAccessWrapper::newFromObject( $client );
@@ -186,7 +200,9 @@ class ResourceLoaderClientHtmlTest extends PHPUnit\Framework\TestCase {
                $context = self::makeContext();
                $context->getResourceLoader()->register( self::makeSampleModules() );
 
-               $client = new ResourceLoaderClientHtml( $context );
+               $client = new ResourceLoaderClientHtml( $context, [
+                       'nonce' => false,
+               ] );
                $client->setConfig( [ 'key' => 'value' ] );
                $client->setModules( [
                        'test',
@@ -195,6 +211,7 @@ class ResourceLoaderClientHtmlTest extends PHPUnit\Framework\TestCase {
                $client->setModuleStyles( [
                        'test.styles.pure',
                        'test.styles.private',
+                       'test.styles.deprecated',
                ] );
                $client->setModuleScripts( [
                        'test.scripts',
@@ -207,12 +224,12 @@ class ResourceLoaderClientHtmlTest extends PHPUnit\Framework\TestCase {
                $expected = '<script>document.documentElement.className = document.documentElement.className.replace( /(^|\s)client-nojs(\s|$)/, "$1client-js$2" );</script>' . "\n"
                        . '<script>(window.RLQ=window.RLQ||[]).push(function(){'
                        . 'mw.config.set({"key":"value"});'
-                       . 'mw.loader.state({"test.exempt":"ready","test.private":"loading","test.styles.pure":"ready","test.styles.private":"ready","test.scripts":"loading"});'
+                       . 'mw.loader.state({"test.exempt":"ready","test.private":"loading","test.styles.pure":"ready","test.styles.private":"ready","test.styles.deprecated":"ready","test.scripts":"loading"});'
                        . 'mw.loader.implement("test.private@{blankVer}",function($,jQuery,require,module){},{"css":[]});'
                        . 'mw.loader.load(["test"]);'
                        . 'mw.loader.load("/w/load.php?debug=false\u0026lang=nl\u0026modules=test.scripts\u0026only=scripts\u0026skin=fallback");'
                        . '});</script>' . "\n"
-                       . '<link rel="stylesheet" href="/w/load.php?debug=false&amp;lang=nl&amp;modules=test.styles.pure&amp;only=styles&amp;skin=fallback"/>' . "\n"
+                       . '<link rel="stylesheet" href="/w/load.php?debug=false&amp;lang=nl&amp;modules=test.styles.deprecated%2Cpure&amp;only=styles&amp;skin=fallback"/>' . "\n"
                        . '<style>.private{}</style>' . "\n"
                        . '<script async="" src="/w/load.php?debug=false&amp;lang=nl&amp;modules=startup&amp;only=scripts&amp;skin=fallback"></script>';
                // phpcs:enable
@@ -240,6 +257,25 @@ class ResourceLoaderClientHtmlTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( $expected, $client->getHeadHtml() );
        }
 
+       /**
+        * Confirm that 'safemode' is passed down to startup.
+        *
+        * @covers ResourceLoaderClientHtml::getHeadHtml
+        */
+       public function testGetHeadHtmlWithSafemode() {
+               $client = new ResourceLoaderClientHtml(
+                       self::makeContext(),
+                       [ 'safemode' => '1' ]
+               );
+
+               // phpcs:disable Generic.Files.LineLength
+               $expected = '<script>document.documentElement.className = document.documentElement.className.replace( /(^|\s)client-nojs(\s|$)/, "$1client-js$2" );</script>' . "\n"
+                       . '<script async="" src="/w/load.php?debug=false&amp;lang=nl&amp;modules=startup&amp;only=scripts&amp;safemode=1&amp;skin=fallback"></script>';
+               // phpcs:enable
+
+               $this->assertEquals( $expected, $client->getHeadHtml() );
+       }
+
        /**
         * Confirm that a null 'target' is the same as no target.
         *
@@ -267,18 +303,23 @@ class ResourceLoaderClientHtmlTest extends PHPUnit\Framework\TestCase {
                $context = self::makeContext();
                $context->getResourceLoader()->register( self::makeSampleModules() );
 
-               $client = new ResourceLoaderClientHtml( $context );
+               $client = new ResourceLoaderClientHtml( $context, [ 'nonce' => false ] );
                $client->setConfig( [ 'key' => 'value' ] );
                $client->setModules( [
                        'test',
                        'test.private.bottom',
                ] );
+               $client->setModuleStyles( [
+                       'test.styles.deprecated',
+               ] );
                $client->setModuleScripts( [
                        'test.scripts',
                ] );
-
-               $expected = '';
-               $expected = self::expandVariables( $expected );
+               // phpcs:disable Generic.Files.LineLength
+               $expected = '<script>(window.RLQ=window.RLQ||[]).push(function(){'
+                       . 'mw.log.warn("This page is using the deprecated ResourceLoader module \"test.styles.deprecated\".\nDeprecation message.");'
+                       . '});</script>';
+               // phpcs:enable
 
                $this->assertEquals( $expected, $client->getBodyHtml() );
        }
@@ -408,7 +449,7 @@ class ResourceLoaderClientHtmlTest extends PHPUnit\Framework\TestCase {
        public function testMakeLoad( array $extraQuery, array $modules, $type, $expected ) {
                $context = self::makeContext( $extraQuery );
                $context->getResourceLoader()->register( self::makeSampleModules() );
-               $actual = ResourceLoaderClientHtml::makeLoad( $context, $modules, $type, $extraQuery );
+               $actual = ResourceLoaderClientHtml::makeLoad( $context, $modules, $type, $extraQuery, false );
                $expected = self::expandVariables( $expected );
                $this->assertEquals( $expected, (string)$actual );
        }
index a42e4be..bb51de0 100644 (file)
@@ -38,6 +38,6 @@ class ResourceLoaderLessVarFileModuleTest extends ResourceLoaderTestCase {
        public function testEscapeMessage( $msg, $expected ) {
                $method = new ReflectionMethod( ResourceLoaderLessVarFileModule::class, 'wrapAndEscapeMessage' );
                $method->setAccessible( true );
-               $this->assertEquals( $expected, $method->invoke( ResourceLoaderLessVarFileModule::class, $msg ) );
+               $this->assertEquals( $expected, $method->invoke( null, $msg ) );
        }
 }
index 564f50b..ca4fb34 100644 (file)
@@ -162,6 +162,75 @@ mw.loader.register( [
         "test.blank",
         "{blankVer}"
     ]
+] );'
+                       ] ],
+                       [ [
+                               'msg' => 'Safemode disabled (default; register all modules)',
+                               'modules' => [
+                                       // Default origin: ORIGIN_CORE_SITEWIDE
+                                       'test.blank' => new ResourceLoaderTestModule(),
+                                       'test.core-generated' => new ResourceLoaderTestModule( [
+                                               'origin' => ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL
+                                       ] ),
+                                       'test.sitewide' => new ResourceLoaderTestModule( [
+                                               'origin' => ResourceLoaderModule::ORIGIN_USER_SITEWIDE
+                                       ] ),
+                                       'test.user' => new ResourceLoaderTestModule( [
+                                               'origin' => ResourceLoaderModule::ORIGIN_USER_INDIVIDUAL
+                                       ] ),
+                               ],
+                               'out' => '
+mw.loader.addSource( {
+    "local": "/w/load.php"
+} );
+mw.loader.register( [
+    [
+        "test.blank",
+        "{blankVer}"
+    ],
+    [
+        "test.core-generated",
+        "{blankVer}"
+    ],
+    [
+        "test.sitewide",
+        "{blankVer}"
+    ],
+    [
+        "test.user",
+        "{blankVer}"
+    ]
+] );'
+                       ] ],
+                       [ [
+                               'msg' => 'Safemode enabled (filter modules with user/site origin)',
+                               'extraQuery' => [ 'safemode' => '1' ],
+                               'modules' => [
+                                       // Default origin: ORIGIN_CORE_SITEWIDE
+                                       'test.blank' => new ResourceLoaderTestModule(),
+                                       'test.core-generated' => new ResourceLoaderTestModule( [
+                                               'origin' => ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL
+                                       ] ),
+                                       'test.sitewide' => new ResourceLoaderTestModule( [
+                                               'origin' => ResourceLoaderModule::ORIGIN_USER_SITEWIDE
+                                       ] ),
+                                       'test.user' => new ResourceLoaderTestModule( [
+                                               'origin' => ResourceLoaderModule::ORIGIN_USER_INDIVIDUAL
+                                       ] ),
+                               ],
+                               'out' => '
+mw.loader.addSource( {
+    "local": "/w/load.php"
+} );
+mw.loader.register( [
+    [
+        "test.blank",
+        "{blankVer}"
+    ],
+    [
+        "test.core-generated",
+        "{blankVer}"
+    ]
 ] );'
                        ] ],
                        [ [
@@ -394,7 +463,8 @@ mw.loader.register( [
                        $this->setMwGlobals( 'wgResourceLoaderSources', $case['sources'] );
                }
 
-               $context = $this->getResourceLoaderContext();
+               $extraQuery = isset( $case['extraQuery'] ) ? $case['extraQuery'] : [];
+               $context = $this->getResourceLoaderContext( $extraQuery );
                $rl = $context->getResourceLoader();
                $rl->register( $case['modules'] );
                $module = new ResourceLoaderStartUpModule();
index e811d87..e0b8c5e 100644 (file)
@@ -8,9 +8,6 @@ class ResourceLoaderTest extends ResourceLoaderTestCase {
                parent::setUp();
 
                $this->setMwGlobals( [
-                       'wgResourceLoaderLESSImportPaths' => [
-                               dirname( dirname( __DIR__ ) ) . '/data/less/common',
-                       ],
                        'wgResourceLoaderLESSVars' => [
                                'foo'  => '2px',
                                'Foo' => '#eeeeee',
@@ -264,6 +261,20 @@ class ResourceLoaderTest extends ResourceLoaderTestCase {
                $this->assertStringEqualsFile( $basePath . '/styles.css', $styles['all'] );
        }
 
+       /**
+        * @covers ResourceLoader::getLessCompiler
+        */
+       public function testLessImportDirs() {
+               $rl = new EmptyResourceLoader();
+               $lc = $rl->getLessCompiler( $rl->getLessVars() );
+               $basePath = dirname( dirname( __DIR__ ) ) . '/data/less';
+               $lc->SetImportDirs( [
+                        "$basePath/common" => '',
+               ] );
+               $css = $lc->parseFile( "$basePath/module/use-import-dir.less" )->getCss();
+               $this->assertStringEqualsFile( "$basePath/module/styles.css", $css );
+       }
+
        public static function providePackedModules() {
                return [
                        [
@@ -584,11 +595,11 @@ mw.example();
                }
        }
 
-       protected function getFailFerryMock() {
+       protected function getFailFerryMock( $getter = 'getScript' ) {
                $mock = $this->getMockBuilder( ResourceLoaderTestModule::class )
-                       ->setMethods( [ 'getScript' ] )
+                       ->setMethods( [ $getter ] )
                        ->getMock();
-               $mock->method( 'getScript' )->will( $this->throwException(
+               $mock->method( $getter )->will( $this->throwException(
                        new Exception( 'Ferry not found' )
                ) );
                return $mock;
@@ -602,6 +613,14 @@ mw.example();
                return $mock;
        }
 
+       protected function getSimpleStyleModuleMock( $styles = '' ) {
+               $mock = $this->getMockBuilder( ResourceLoaderTestModule::class )
+                       ->setMethods( [ 'getStyles' ] )
+                       ->getMock();
+               $mock->method( 'getStyles' )->willReturn( [ '' => $styles ] );
+               return $mock;
+       }
+
        /**
         * @covers ResourceLoader::getCombinedVersion
         */
@@ -717,6 +736,21 @@ mw.example();
                $this->assertEquals( $expected, $response, $message ?: 'Response' );
        }
 
+       /**
+        * @covers ResourceLoader::makeModuleResponse
+        */
+       public function testMakeModuleResponseEmpty() {
+               $rl = new EmptyResourceLoader();
+               $context = $this->getResourceLoaderContext(
+                       [ 'modules' => '', 'only' => 'scripts' ],
+                       $rl
+               );
+
+               $response = $rl->makeModuleResponse( $context, [] );
+               $this->assertSame( [], $rl->getErrors(), 'Errors' );
+               $this->assertRegExp( '/^\/\*.+no modules were requested.+\*\/$/ms', $response );
+       }
+
        /**
         * Verify that when building module content in a load.php response,
         * an exception from one module will not break script output from
@@ -758,6 +792,43 @@ mw.example();
                );
        }
 
+       /**
+        * Verify that exceptions in PHP for one module will not break others
+        * (stylesheet response).
+        *
+        * @covers ResourceLoader::makeModuleResponse
+        */
+       public function testMakeModuleResponseErrorCSS() {
+               $modules = [
+                       'foo' => self::getSimpleStyleModuleMock( '.foo{}' ),
+                       'ferry' => self::getFailFerryMock( 'getStyles' ),
+                       'bar' => self::getSimpleStyleModuleMock( '.bar{}' ),
+               ];
+               $rl = new EmptyResourceLoader();
+               $rl->register( $modules );
+               $context = $this->getResourceLoaderContext(
+                       [
+                               'modules' => 'foo|ferry|bar',
+                               'only' => 'styles',
+                               'debug' => 'false',
+                       ],
+                       $rl
+               );
+
+               // Disable log from makeModuleResponse via outputErrorAndLog
+               $this->setLogger( 'exception', new Psr\Log\NullLogger() );
+
+               $response = $rl->makeModuleResponse( $context, $modules );
+               $errors = $rl->getErrors();
+
+               $this->assertCount( 2, $errors );
+               $this->assertRegExp( '/Ferry not found/', $errors[0] );
+               $this->assertRegExp( '/Problem.+"ferry":\s*"error"/ms', $errors[1] );
+               $this->assertEquals(
+                       '.foo{}.bar{}',
+                       $response
+               );
+       }
        /**
         * Verify that when building the startup module response,
         * an exception from one module class will not break the entire
index e0d059f..879acfe 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Addshore
  *
  * @covers SpecialBlankpage
index 274a23c..4809e1b 100644 (file)
@@ -5,7 +5,7 @@
  *
  * @since 1.26
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  * @author Daniel Kinzler
  * @author Addshore
index f799b11..236c5c4 100644 (file)
@@ -5,7 +5,7 @@
  *
  * @since 1.30
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  */
 class SpecialShortpagesTest extends MediaWikiTestCase {
 
index e1b98ec..c272551 100644 (file)
@@ -104,6 +104,13 @@ class MediaWikiTitleCodecTest extends MediaWikiTestCase {
                        // names ending in "a" to be female.
                        [ NS_USER, 'Lisa_Müller', '', '', 'de', 'Benutzerin:Lisa Müller' ],
                        [ NS_MAIN, 'FooBar', '', 'remotetestiw', 'en', 'remotetestiw:FooBar' ],
+                       // Strip soft hyphen and Unicode directional formatting characters
+                       [ NS_MAIN, "Foo\xC2\xAD\xD8\x9C\xE2\x80\x8E\xE2\x80\x8F\xE2\x80\xAA\xE2\x80\xAB" .
+                               "\xE2\x80\xAC\xE2\x80\xAD\xE2\x80\xAE\xE2\x81\xA6\xE2\x81\xA7" .
+                               "\xE2\x81\xA8\xE2\x81\xA9bar", '', '', 'en',
+                               "Foo\xC2\xAD\xD8\x9C\xE2\x80\x8E\xE2\x80\x8F\xE2\x80\xAA\xE2\x80\xAB" .
+                               "\xE2\x80\xAC\xE2\x80\xAD\xE2\x80\xAE\xE2\x81\xA6\xE2\x81\xA7" .
+                               "\xE2\x81\xA8\xE2\x81\xA9bar", 'Foobar' ],
                ];
        }
 
index e819d35..3eb6abd 100644 (file)
@@ -1199,4 +1199,113 @@ class UserTest extends MediaWikiTestCase {
                $this->assertFalse( $user->isBlockedFrom( $ut ) );
        }
 
+       /**
+        * Block cookie should be set for IP Blocks if
+        * wgCookieSetOnIpBlock is set to true
+        */
+       public function testIpBlockCookieSet() {
+               $this->setMwGlobals( [
+                       'wgCookieSetOnIpBlock' => true,
+                       'wgCookiePrefix' => 'wiki',
+                       'wgSecretKey' => MWCryptRand::generateHex( 64, true ),
+               ] );
+
+               // setup block
+               $block = new Block( [
+                       'expiry' => wfTimestamp( TS_MW, wfTimestamp() + ( 5 * 60 * 60 ) ),
+               ] );
+               $block->setTarget( '1.2.3.4' );
+               $block->setBlocker( $this->getTestSysop()->getUser() );
+               $block->insert();
+
+               // setup request
+               $request = new FauxRequest();
+               $request->setIP( '1.2.3.4' );
+
+               // get user
+               $user = User::newFromSession( $request );
+               $user->trackBlockWithCookie();
+
+               // test cookie was set
+               $cookies = $request->response()->getCookies();
+               $this->assertArrayHasKey( 'wikiBlockID', $cookies );
+
+               // clean up
+               $block->delete();
+       }
+
+       /**
+        * Block cookie should NOT be set when wgCookieSetOnIpBlock
+        * is disabled
+        */
+       public function testIpBlockCookieNotSet() {
+               $this->setMwGlobals( [
+                       'wgCookieSetOnIpBlock' => false,
+                       'wgCookiePrefix' => 'wiki',
+                       'wgSecretKey' => MWCryptRand::generateHex( 64, true ),
+               ] );
+
+               // setup block
+               $block = new Block( [
+                       'expiry' => wfTimestamp( TS_MW, wfTimestamp() + ( 5 * 60 * 60 ) ),
+               ] );
+               $block->setTarget( '1.2.3.4' );
+               $block->setBlocker( $this->getTestSysop()->getUser() );
+               $block->insert();
+
+               // setup request
+               $request = new FauxRequest();
+               $request->setIP( '1.2.3.4' );
+
+               // get user
+               $user = User::newFromSession( $request );
+               $user->trackBlockWithCookie();
+
+               // test cookie was not set
+               $cookies = $request->response()->getCookies();
+               $this->assertArrayNotHasKey( 'wikiBlockID', $cookies );
+
+               // clean up
+               $block->delete();
+       }
+
+       /**
+        * When an ip user is blocked and then they log in, cookie block
+        * should be invalid and the cookie removed.
+        */
+       public function testIpBlockCookieIgnoredWhenUserLoggedIn() {
+               $this->setMwGlobals( [
+                       'wgAutoblockExpiry' => 8000,
+                       'wgCookieSetOnIpBlock' => true,
+                       'wgCookiePrefix' => 'wiki',
+                       'wgSecretKey' => MWCryptRand::generateHex( 64, true ),
+               ] );
+
+               // setup block
+               $block = new Block( [
+                       'expiry' => wfTimestamp( TS_MW, wfTimestamp() + ( 40 * 60 * 60 ) ),
+               ] );
+               $block->setTarget( '1.2.3.4' );
+               $block->setBlocker( $this->getTestSysop()->getUser() );
+               $block->insert();
+
+               // setup request
+               $request = new FauxRequest();
+               $request->setIP( '1.2.3.4' );
+               $request->getSession()->setUser( $this->getTestUser()->getUser() );
+               $request->setCookie( 'BlockID', $block->getCookieValue() );
+
+               // setup user
+               $user = User::newFromSession( $request );
+
+               // logged in users should be inmune to cookie block of type ip/range
+               $this->assertFalse( $user->isBlocked() );
+
+               // cookie is being cleared
+               $cookies = $request->response()->getCookies();
+               $this->assertEquals( '', $cookies['wikiBlockID']['value'] );
+
+               // clean up
+               $block->delete();
+       }
 }
index 5a554a0..11c1097 100644 (file)
@@ -3,6 +3,7 @@
 /**
  * @covers LanguageCrh
  * @covers CrhConverter
+ * @covers MediaWiki\Languages\Data\CrhExceptions
  */
 class LanguageCrhTest extends LanguageClassesTestCase {
        /**
@@ -103,6 +104,14 @@ class LanguageCrhTest extends LanguageClassesTestCase {
                                ],
                                'ДЖУРЬМЕК CÜRMEK кетсин ketsin джумлеси cümlesi ильи ilyi Ильи İlyi'
                        ],
+                       [ // recent problem words, part 7
+                               [
+                                       'crh'      => 'бруцел brutsel коцюб kotsüb плацен platsen эпицентр epitsentr',
+                                       'crh-cyrl' => 'бруцел бруцел коцюб коцюб плацен плацен эпицентр эпицентр',
+                                       'crh-latn' => 'brutsel brutsel kotsüb kotsüb platsen platsen epitsentr epitsentr',
+                               ],
+                               'бруцел brutsel коцюб kotsüb плацен platsen эпицентр epitsentr'
+                       ],
                        [ // regex pattern words
                                [
                                        'crh'      => 'köyünden коюнден ange аньге',
index e81d537..30b4df8 100644 (file)
@@ -68,7 +68,7 @@ class LanguageSrTest extends LanguageClassesTestCase {
         * @covers LanguageConverter::convertTo
         */
        public function testConversionToCyrillic() {
-               // A simple convertion of Latin to Cyrillic
+               // A simple conversion of Latin to Cyrillic
                $this->assertEquals( 'абвг',
                        $this->convertToCyrillic( 'abvg' )
                );
@@ -76,7 +76,7 @@ class LanguageSrTest extends LanguageClassesTestCase {
                $this->assertEquals( 'ljабnjвгdž',
                        $this->convertToCyrillic( '-{lj}-ab-{nj}-vg-{dž}-' )
                );
-               // A simple convertion of Cyrillic to Cyrillic
+               // A simple conversion of Cyrillic to Cyrillic
                $this->assertEquals( 'абвг',
                        $this->convertToCyrillic( 'абвг' )
                );
@@ -110,11 +110,11 @@ class LanguageSrTest extends LanguageClassesTestCase {
         * @covers LanguageConverter::convertTo
         */
        public function testConversionToLatin() {
-               // A simple convertion of Latin to Latin
+               // A simple conversion of Latin to Latin
                $this->assertEquals( 'abcd',
                        $this->convertToLatin( 'abcd' )
                );
-               // A simple convertion of Cyrillic to Latin
+               // A simple conversion of Cyrillic to Latin
                $this->assertEquals( 'abcd',
                        $this->convertToLatin( 'абцд' )
                );
diff --git a/tests/phpunit/maintenance/categoryChangesRdfTest.php b/tests/phpunit/maintenance/categoryChangesRdfTest.php
new file mode 100644 (file)
index 0000000..30a56f4
--- /dev/null
@@ -0,0 +1,263 @@
+<?php
+
+/**
+ * Tests for CategoryChangesAsRdf recent changes exporter.
+ *  @covers CategoryChangesAsRdf
+ */
+class CategoryChangesRdfTest extends MediaWikiLangTestCase {
+
+       public function setUp() {
+               parent::setUp();
+               $this->setMwGlobals( [
+                       'wgServer' => 'http://acme.test',
+                       'wgCanonicalServer' => 'http://acme.test',
+                       'wgArticlePath' => '/wiki/$1',
+               ] );
+       }
+
+       public function provideCategoryData() {
+               return [
+                       'delete category' => [
+                               __DIR__ . "/../data/categoriesrdf/delete.sparql",
+                               'getDeletedCatsIterator',
+                               'handleDeletes',
+                               [
+                                       (object)[ 'rc_title' => 'Test', 'rc_cur_id' => 1, '_processed' => 1 ],
+                                       (object)[ 'rc_title' => 'Test 2', 'rc_cur_id' => 2, '_processed' => 2 ],
+                               ],
+                       ],
+                       'move category' => [
+                               __DIR__ . "/../data/categoriesrdf/move.sparql",
+                               'getMovedCatsIterator',
+                               'handleMoves',
+                               [
+                                       (object)[
+                                               'rc_title' => 'Test',
+                                               'rc_cur_id' => 4,
+                                               'page_title' => 'MovedTo',
+                                               'page_namespace' => NS_CATEGORY,
+                                               '_processed' => 4,
+                                               'pp_propname' => null,
+                                               'cat_pages' => 10,
+                                               'cat_subcats' => 2,
+                                               'cat_files' => 1,
+                                       ],
+                                       (object)[
+                                               'rc_title' => 'MovedTo',
+                                               'rc_cur_id' => 4,
+                                               'page_title' => 'MovedAgain',
+                                               'page_namespace' => NS_CATEGORY,
+                                               'pp_propname' => 'hiddencat',
+                                               'cat_pages' => 10,
+                                               'cat_subcats' => 2,
+                                               'cat_files' => 1,
+                                       ],
+                                       (object)[
+                                               'rc_title' => 'Test 2',
+                                               'rc_cur_id' => 5,
+                                               'page_title' => 'AlsoMoved',
+                                               'page_namespace' => NS_CATEGORY,
+                                               '_processed' => 5,
+                                               'pp_propname' => null,
+                                               'cat_pages' => 10,
+                                               'cat_subcats' => 2,
+                                               'cat_files' => 1,
+                                       ],
+                                       (object)[
+                                               'rc_title' => 'Test 3',
+                                               'rc_cur_id' => 6,
+                                               'page_title' => 'MovedOut',
+                                               'page_namespace' => NS_MAIN,
+                                               'pp_propname' => null,
+                                               'cat_pages' => 10,
+                                               'cat_subcats' => 2,
+                                               'cat_files' => 1,
+                                       ],
+                                       (object)[
+                                               'rc_title' => 'Test 4',
+                                               'rc_cur_id' => 7,
+                                               'page_title' => 'Already Done',
+                                               'page_namespace' => NS_CATEGORY,
+                                               'pp_propname' => null,
+                                               'cat_pages' => 10,
+                                               'cat_subcats' => 2,
+                                               'cat_files' => 1,
+                                       ],
+                               ],
+                               [ 7 => true ],
+                       ],
+                       'restore deleted category' => [
+                               __DIR__ . "/../data/categoriesrdf/restore.sparql",
+                               'getRestoredCatsIterator',
+                               'handleRestores',
+                               [
+                                       (object)[
+                                               'rc_title' => 'Restored cat',
+                                               'rc_cur_id' => 10,
+                                               '_processed' => 10,
+                                               'pp_propname' => null,
+                                               'cat_pages' => 10,
+                                               'cat_subcats' => 2,
+                                               'cat_files' => 1,
+                                       ],
+                                       (object)[
+                                               'rc_title' => 'Restored again',
+                                               'rc_cur_id' => 10,
+                                               'pp_propname' => null,
+                                               'cat_pages' => 10,
+                                               'cat_subcats' => 2,
+                                               'cat_files' => 1,
+                                       ],
+                                       (object)[
+                                               'rc_title' => 'Already seen',
+                                               'rc_cur_id' => 11,
+                                               'pp_propname' => null,
+                                               'cat_pages' => 10,
+                                               'cat_subcats' => 2,
+                                               'cat_files' => 1,
+                                       ],
+                               ],
+                               [ 11 => true ],
+                       ],
+                       'new page' => [
+                               __DIR__ . "/../data/categoriesrdf/new.sparql",
+                               'getNewCatsIterator',
+                               'handleAdds',
+                               [
+                                       (object)[
+                                               'rc_title' => 'New category',
+                                               'rc_cur_id' => 20,
+                                               '_processed' => 20,
+                                               'pp_propname' => null,
+                                               'cat_pages' => 10,
+                                               'cat_subcats' => 2,
+                                               'cat_files' => 1,
+                                       ],
+                                       (object)[
+                                               'rc_title' => 'Новая категория 😃',
+                                               'rc_cur_id' => 21,
+                                               '_processed' => 21,
+                                               'pp_propname' => 'hiddencat',
+                                               'cat_pages' => 10,
+                                               'cat_subcats' => 2,
+                                               'cat_files' => 1,
+                                       ],
+                                       (object)[
+                                               'rc_title' => 'Processed already',
+                                               'rc_cur_id' => 22,
+                                       ],
+                               ],
+                               [ 22 => true ],
+                       ],
+                       'change in categories' => [
+                               __DIR__ . "/../data/categoriesrdf/change.sparql",
+                               'getChangedCatsIterator',
+                               'handleChanges',
+                               [
+                                       (object)[
+                                               'rc_title' => 'Changed category',
+                                               'rc_cur_id' => 30,
+                                               '_processed' => 30,
+                                               'pp_propname' => null,
+                                               'cat_pages' => 10,
+                                               'cat_subcats' => 2,
+                                               'cat_files' => 1,
+                                       ],
+                                       (object)[
+                                               'rc_title' => 'Changed again',
+                                               'rc_cur_id' => 30,
+                                               'pp_propname' => null,
+                                               'cat_pages' => 10,
+                                               'cat_subcats' => 2,
+                                               'cat_files' => 1,
+                                       ],
+                                       (object)[
+                                               'rc_title' => 'Processed already',
+                                               'rc_cur_id' => 31,
+                                               'pp_propname' => null,
+                                               'cat_pages' => 10,
+                                               'cat_subcats' => 2,
+                                               'cat_files' => 1,
+                                       ],
+                               ],
+                               [ 31 => true ],
+                       ],
+
+               ];
+       }
+
+       /**
+        * Mock category links iterator.
+        * @param $dbr
+        * @param array $ids
+        * @return array
+        */
+       public function getCategoryLinksIterator( $dbr, array $ids ) {
+               $res = [];
+               foreach ( $ids as $pageid ) {
+                       $res[] = (object)[ 'cl_from' => $pageid, 'cl_to' => "Parent of $pageid" ];
+               }
+               return $res;
+       }
+
+       /**
+        * @dataProvider provideCategoryData
+        * @param string $testFileName Name of the test, defines filename with expected results.
+        * @param string $iterator Iterator method name to mock
+        * @param string $handler Handler method to call
+        * @param array $result Result to be returned from mock iterator
+        * @param array $preProcessed List of pre-processed items
+        */
+       public function testSparqlUpdate( $testFileName, $iterator, $handler, $result,
+                       array $preProcessed = [] ) {
+               $dumpScript =
+                       $this->getMockBuilder( CategoryChangesAsRdf::class )
+                               ->setMethods( [ $iterator, 'getCategoryLinksIterator' ] )
+                               ->getMock();
+
+               $dumpScript->expects( $this->any() )
+                       ->method( 'getCategoryLinksIterator' )
+                       ->willReturnCallback( [ $this, 'getCategoryLinksIterator' ] );
+
+               $dumpScript->expects( $this->once() )
+                       ->method( $iterator )
+                       ->willReturn( [ $result ] );
+
+               $ref = new ReflectionObject( $dumpScript );
+               $processedProperty = $ref->getProperty( 'processed' );
+               $processedProperty->setAccessible( true );
+               $processedProperty->setValue( $dumpScript, $preProcessed );
+
+               $output = fopen( "php://memory", "w+b" );
+               $dbr = wfGetDB( DB_REPLICA );
+               /** @var CategoryChangesAsRdf $dumpScript */
+               $dumpScript->initialize();
+               $dumpScript->getRdf();
+               $dumpScript->$handler( $dbr, $output );
+
+               rewind( $output );
+               $sparql = stream_get_contents( $output );
+               $this->assertFileContains( $testFileName, $sparql );
+
+               $processed = $processedProperty->getValue( $dumpScript );
+               $expectedProcessed = $preProcessed;
+               foreach ( $result as $row ) {
+                       if ( isset( $row->_processed ) ) {
+                               $this->assertArrayHasKey( $row->_processed, $processed,
+                                       "ID {$row->_processed} was not processed!" );
+                               $expectedProcessed[] = $row->_processed;
+                       }
+               }
+               $this->assertArrayEquals( $expectedProcessed, array_keys( $processed ),
+                       'Processed array has wrong items' );
+       }
+
+       public function testUpdateTs() {
+               $dumpScript = new CategoryChangesAsRdf();
+               $dumpScript->initialize();
+               $update = $dumpScript->updateTS( 1503620949 );
+               $outFile = __DIR__ . '/../data/categoriesrdf/updatets.txt';
+               $this->assertFileContains( $outFile, $update );
+       }
+
+}
index c141817..cd68fa5 100644 (file)
@@ -92,6 +92,24 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                        'log_timestamp' => 20091223210426
                ];
 
+               // Autopatrol #4 very old way
+               $logs[] = [
+                       'log_type' => 'patrol',
+                       'log_action' => 'patrol',
+                       'log_user' => 7257,
+                       'log_params' => "9227851\n0\n1",
+                       'log_timestamp' => 20081223210426
+               ];
+
+               // Manual patrol #3 very old way
+               $logs[] = [
+                       'log_type' => 'patrol',
+                       'log_action' => 'patrol',
+                       'log_user' => 7258,
+                       'log_params' => "9227851\n0\n0",
+                       'log_timestamp' => 20091223210426
+               ];
+
                wfGetDB( DB_MASTER )->insert( 'logging', $logs );
        }
 
@@ -132,6 +150,16 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                                'log_action' => 'patrol',
                                'log_user' => '7256',
                        ],
+                       (object)[
+                               'log_type' => 'patrol',
+                               'log_action' => 'patrol',
+                               'log_user' => '7257',
+                       ],
+                       (object)[
+                               'log_type' => 'patrol',
+                               'log_action' => 'patrol',
+                               'log_user' => '7258',
+                       ],
                ];
 
                $cases = [
@@ -146,6 +174,8 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                                        $allRows[3],
                                        $allRows[5],
                                        $allRows[6],
+                                       $allRows[7],
+                                       $allRows[8],
                                ],
                                [ '--sleep', '0', '-q' ]
                        ],
@@ -157,6 +187,8 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                                        $allRows[4],
                                        $allRows[5],
                                        $allRows[6],
+                                       $allRows[7],
+                                       $allRows[8],
                                ],
                                [ '--sleep', '0', '--before', '20060123210426', '-q' ]
                        ],
@@ -168,6 +200,7 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                                        $allRows[3],
                                        $allRows[4],
                                        $allRows[6],
+                                       $allRows[8],
                                ],
                                [ '--sleep', '0', '--check-old', '-q' ]
                        ],
index 77d6e74..692bd73 100644 (file)
@@ -60,6 +60,7 @@ class ApiStructureTest extends MediaWikiTestCase {
                ApiBase::PARAM_ISMULTI_LIMIT2 => [ 'integer' ],
                ApiBase::PARAM_MAX_BYTES => [ 'integer' ],
                ApiBase::PARAM_MAX_CHARS => [ 'integer' ],
+               ApiBase::PARAM_TEMPLATE_VARS => [ 'array' ],
        ];
 
        // param => [ other param that must be present => required value or null ]
@@ -422,6 +423,45 @@ class ApiStructureTest extends MediaWikiTestCase {
                                                "$param: PARAM_MAX_BYTES cannot be less than PARAM_MAX_CHARS"
                                        );
                                }
+
+                               if ( isset( $config[ApiBase::PARAM_TEMPLATE_VARS] ) ) {
+                                       $this->assertNotSame( [], $config[ApiBase::PARAM_TEMPLATE_VARS],
+                                               "$param: PARAM_TEMPLATE_VARS cannot be empty" );
+                                       foreach ( $config[ApiBase::PARAM_TEMPLATE_VARS] as $key => $target ) {
+                                               $this->assertRegExp( '/^[^{}]+$/', $key,
+                                                       "$param: PARAM_TEMPLATE_VARS key may not contain '{' or '}'" );
+
+                                               $this->assertContains( '{' . $key . '}', $param,
+                                                       "$param: Name must contain PARAM_TEMPLATE_VARS key {" . $key . "}" );
+                                               $this->assertArrayHasKey( $target, $params,
+                                                       "$param: PARAM_TEMPLATE_VARS target parameter '$target' does not exist" );
+                                               $config2 = $params[$target];
+                                               $this->assertTrue( !empty( $config2[ApiBase::PARAM_ISMULTI] ),
+                                                       "$param: PARAM_TEMPLATE_VARS target parameter '$target' must have PARAM_ISMULTI = true" );
+
+                                               if ( isset( $config2[ApiBase::PARAM_TEMPLATE_VARS] ) ) {
+                                                       $this->assertNotSame( $param, $target,
+                                                               "$param: PARAM_TEMPLATE_VARS cannot target itself" );
+
+                                                       $this->assertArraySubset(
+                                                               $config2[ApiBase::PARAM_TEMPLATE_VARS],
+                                                               $config[ApiBase::PARAM_TEMPLATE_VARS],
+                                                               true,
+                                                               "$param: PARAM_TEMPLATE_VARS target parameter '$target': "
+                                                               . "the target's PARAM_TEMPLATE_VARS must be a subset of the original."
+                                                       );
+                                               }
+                                       }
+
+                                       $keys = implode( '|',
+                                               array_map( 'preg_quote', array_keys( $config[ApiBase::PARAM_TEMPLATE_VARS] ) )
+                                       );
+                                       $this->assertRegExp( '/^(?>[^{}]+|\{(?:' . $keys . ')\})+$/', $param,
+                                               "$param: Name may not contain '{' or '}' other than as defined by PARAM_TEMPLATE_VARS" );
+                               } else {
+                                       $this->assertRegExp( '/^[^{}]+$/', $param,
+                                               "$param: Name may not contain '{' or '}' without PARAM_TEMPLATE_VARS" );
+                               }
                        }
                }
        }
diff --git a/tests/phpunit/structure/AutoLoaderStructureTest.php b/tests/phpunit/structure/AutoLoaderStructureTest.php
new file mode 100644 (file)
index 0000000..2800d02
--- /dev/null
@@ -0,0 +1,193 @@
+<?php
+
+/**
+ * @coversNothing
+ */
+class AutoLoaderStructureTest extends MediaWikiTestCase {
+       /**
+        * Assert that there were no classes loaded that are not registered with the AutoLoader.
+        *
+        * For example foo.php having class Foo and class Bar but only registering Foo.
+        * This is important because we should not be relying on Foo being used before Bar.
+        */
+       public function testAutoLoadConfig() {
+               $results = self::checkAutoLoadConf();
+
+               $this->assertEquals(
+                       $results['expected'],
+                       $results['actual']
+               );
+       }
+
+       public function providePSR4Completeness() {
+               foreach ( AutoLoader::$psr4Namespaces as $prefix => $dir ) {
+                       foreach ( $this->recurseFiles( $dir ) as $file ) {
+                               yield [ $prefix, $dir, $file ];
+                       }
+               }
+       }
+
+       private function recurseFiles( $dir ) {
+               return ( new File_Iterator_Facade() )->getFilesAsArray( $dir, [ '.php' ] );
+       }
+
+       /**
+        * @dataProvider providePSR4Completeness
+        */
+       public function testPSR4Completeness( $prefix, $dir, $file ) {
+               global $wgAutoloadLocalClasses, $wgAutoloadClasses;
+               $contents = file_get_contents( $file );
+               list( $classesInFile, $aliasesInFile ) = self::parseFile( $contents );
+               $classes = array_keys( $classesInFile );
+               if ( $classes ) {
+                       $this->assertCount( 1, $classes,
+                               "Only one class per file in PSR-4 autoloaded classes ($file)" );
+
+                       // Check that the expected class name (based on the filename) is the
+                       // same as the one we found.
+                       // Strip directory prefix from front of filename, and .php extension
+                       $abbrFileName = substr( substr( $file, strlen( $dir ) ), 0, -4 );
+                       $expectedClassName = $prefix . str_replace( '/', '\\', $abbrFileName );
+
+                       $this->assertSame(
+                               $expectedClassName,
+                               $classes[0],
+                               "Class not autoloaded properly"
+                       );
+
+               } else {
+                       // Dummy assertion so this test isn't marked in risky
+                       // if the file has no classes nor aliases in it
+                       $this->assertCount( 0, $classes );
+               }
+
+               if ( $aliasesInFile ) {
+                       $otherClasses = $wgAutoloadLocalClasses + $wgAutoloadClasses;
+                       foreach ( $aliasesInFile as $alias => $class ) {
+                               $this->assertArrayHasKey( $alias, $otherClasses,
+                                       'Alias must be in the classmap autoloader'
+                               );
+                       }
+               }
+       }
+
+       private static function parseFile( $contents ) {
+               // We could use token_get_all() here, but this is faster
+               // Note: Keep in sync with ClassCollector
+               $matches = [];
+               preg_match_all( '/
+                               ^ [\t ]* (?:
+                                       (?:final\s+)? (?:abstract\s+)? (?:class|interface|trait) \s+
+                                       (?P<class> [a-zA-Z0-9_]+)
+                               |
+                                       class_alias \s* \( \s*
+                                               ([\'"]) (?P<original> [^\'"]+) \g{-2} \s* , \s*
+                                               ([\'"]) (?P<alias> [^\'"]+ ) \g{-2} \s*
+                                       \) \s* ;
+                               |
+                                       class_alias \s* \( \s*
+                                               (?P<originalStatic> [a-zA-Z0-9_]+)::class \s* , \s*
+                                               ([\'"]) (?P<aliasString> [^\'"]+ ) \g{-2} \s*
+                                       \) \s* ;
+                               )
+                       /imx', $contents, $matches, PREG_SET_ORDER );
+
+               $namespaceMatch = [];
+               preg_match( '/
+                               ^ [\t ]*
+                                       namespace \s+
+                                               ([a-zA-Z0-9_]+(\\\\[a-zA-Z0-9_]+)*)
+                                       \s* ;
+                       /imx', $contents, $namespaceMatch );
+               $fileNamespace = $namespaceMatch ? $namespaceMatch[1] . '\\' : '';
+
+               $classesInFile = [];
+               $aliasesInFile = [];
+
+               foreach ( $matches as $match ) {
+                       if ( !empty( $match['class'] ) ) {
+                               // 'class Foo {}'
+                               $class = $fileNamespace . $match['class'];
+                               $classesInFile[$class] = true;
+                       } else {
+                               if ( !empty( $match['original'] ) ) {
+                                       // 'class_alias( "Foo", "Bar" );'
+                                       $aliasesInFile[$match['alias']] = $match['original'];
+                               } else {
+                                       // 'class_alias( Foo::class, "Bar" );'
+                                       $aliasesInFile[$match['aliasString']] = $fileNamespace . $match['originalStatic'];
+                               }
+                       }
+               }
+
+               return [ $classesInFile, $aliasesInFile ];
+       }
+
+       protected static function checkAutoLoadConf() {
+               global $wgAutoloadLocalClasses, $wgAutoloadClasses, $IP;
+
+               // wgAutoloadLocalClasses has precedence, just like in includes/AutoLoader.php
+               $expected = $wgAutoloadLocalClasses + $wgAutoloadClasses;
+               $actual = [];
+
+               $files = array_unique( $expected );
+
+               foreach ( $files as $class => $file ) {
+                       // Only prefix $IP if it doesn't have it already.
+                       // Generally local classes don't have it, and those from extensions and test suites do.
+                       if ( substr( $file, 0, 1 ) != '/' && substr( $file, 1, 1 ) != ':' ) {
+                               $filePath = "$IP/$file";
+                       } else {
+                               $filePath = $file;
+                       }
+
+                       if ( !file_exists( $filePath ) ) {
+                               $actual[$class] = "[file '$filePath' does not exist]";
+                               continue;
+                       }
+
+                       Wikimedia\suppressWarnings();
+                       $contents = file_get_contents( $filePath );
+                       Wikimedia\restoreWarnings();
+
+                       if ( $contents === false ) {
+                               $actual[$class] = "[couldn't read file '$filePath']";
+                               continue;
+                       }
+
+                       list( $classesInFile, $aliasesInFile ) = self::parseFile( $contents );
+
+                       foreach ( $classesInFile as $className => $ignore ) {
+                               $actual[$className] = $file;
+                       }
+
+                       // Only accept aliases for classes in the same file, because for correct
+                       // behavior, all aliases for a class must be set up when the class is loaded
+                       // (see <https://bugs.php.net/bug.php?id=61422>).
+                       foreach ( $aliasesInFile as $alias => $class ) {
+                               if ( isset( $classesInFile[$class] ) ) {
+                                       $actual[$alias] = $file;
+                               } else {
+                                       $actual[$alias] = "[original class not in $file]";
+                               }
+                       }
+               }
+
+               return [
+                       'expected' => $expected,
+                       'actual' => $actual,
+               ];
+       }
+
+       public function testAutoloadOrder() {
+               $path = realpath( __DIR__ . '/../../..' );
+               $oldAutoload = file_get_contents( $path . '/autoload.php' );
+               $generator = new AutoloadGenerator( $path, 'local' );
+               $generator->setExcludePaths( array_values( AutoLoader::getAutoloadNamespaces() ) );
+               $generator->initMediaWikiDefault();
+               $newAutoload = $generator->getAutoload( 'maintenance/generateLocalAutoload.php' );
+
+               $this->assertEquals( $oldAutoload, $newAutoload, 'autoload.php does not match' .
+                       ' output of generateLocalAutoload.php script.' );
+       }
+}
diff --git a/tests/phpunit/structure/AutoLoaderTest.php b/tests/phpunit/structure/AutoLoaderTest.php
deleted file mode 100644 (file)
index 217232e..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-<?php
-
-class AutoLoaderTest extends MediaWikiTestCase {
-       protected function setUp() {
-               parent::setUp();
-
-               // Fancy dance to trigger a rebuild of AutoLoader::$autoloadLocalClassesLower
-               $this->mergeMwGlobalArrayValue( 'wgAutoloadLocalClasses', [
-                       'TestAutoloadedLocalClass' =>
-                               __DIR__ . '/../data/autoloader/TestAutoloadedLocalClass.php',
-                       'TestAutoloadedCamlClass' =>
-                               __DIR__ . '/../data/autoloader/TestAutoloadedCamlClass.php',
-                       'TestAutoloadedSerializedClass' =>
-                               __DIR__ . '/../data/autoloader/TestAutoloadedSerializedClass.php',
-               ] );
-               AutoLoader::resetAutoloadLocalClassesLower();
-
-               $this->mergeMwGlobalArrayValue( 'wgAutoloadClasses', [
-                       'TestAutoloadedClass' => __DIR__ . '/../data/autoloader/TestAutoloadedClass.php',
-               ] );
-       }
-
-       /**
-        * Assert that there were no classes loaded that are not registered with the AutoLoader.
-        *
-        * For example foo.php having class Foo and class Bar but only registering Foo.
-        * This is important because we should not be relying on Foo being used before Bar.
-        */
-       public function testAutoLoadConfig() {
-               $results = self::checkAutoLoadConf();
-
-               $this->assertEquals(
-                       $results['expected'],
-                       $results['actual']
-               );
-       }
-
-       protected static function checkAutoLoadConf() {
-               global $wgAutoloadLocalClasses, $wgAutoloadClasses, $IP;
-
-               // wgAutoloadLocalClasses has precedence, just like in includes/AutoLoader.php
-               $expected = $wgAutoloadLocalClasses + $wgAutoloadClasses;
-               $actual = [];
-
-               $files = array_unique( $expected );
-
-               foreach ( $files as $class => $file ) {
-                       // Only prefix $IP if it doesn't have it already.
-                       // Generally local classes don't have it, and those from extensions and test suites do.
-                       if ( substr( $file, 0, 1 ) != '/' && substr( $file, 1, 1 ) != ':' ) {
-                               $filePath = "$IP/$file";
-                       } else {
-                               $filePath = $file;
-                       }
-
-                       if ( !file_exists( $filePath ) ) {
-                               $actual[$class] = "[file '$filePath' does not exist]";
-                               continue;
-                       }
-
-                       Wikimedia\suppressWarnings();
-                       $contents = file_get_contents( $filePath );
-                       Wikimedia\restoreWarnings();
-
-                       if ( $contents === false ) {
-                               $actual[$class] = "[couldn't read file '$filePath']";
-                               continue;
-                       }
-
-                       // We could use token_get_all() here, but this is faster
-                       // Note: Keep in sync with ClassCollector
-                       $matches = [];
-                       preg_match_all( '/
-                               ^ [\t ]* (?:
-                                       (?:final\s+)? (?:abstract\s+)? (?:class|interface|trait) \s+
-                                       (?P<class> [a-zA-Z0-9_]+)
-                               |
-                                       class_alias \s* \( \s*
-                                               ([\'"]) (?P<original> [^\'"]+) \g{-2} \s* , \s*
-                                               ([\'"]) (?P<alias> [^\'"]+ ) \g{-2} \s*
-                                       \) \s* ;
-                               |
-                                       class_alias \s* \( \s*
-                                               (?P<originalStatic> [a-zA-Z0-9_]+)::class \s* , \s*
-                                               ([\'"]) (?P<aliasString> [^\'"]+ ) \g{-2} \s*
-                                       \) \s* ;
-                               )
-                       /imx', $contents, $matches, PREG_SET_ORDER );
-
-                       $namespaceMatch = [];
-                       preg_match( '/
-                               ^ [\t ]*
-                                       namespace \s+
-                                               ([a-zA-Z0-9_]+(\\\\[a-zA-Z0-9_]+)*)
-                                       \s* ;
-                       /imx', $contents, $namespaceMatch );
-                       $fileNamespace = $namespaceMatch ? $namespaceMatch[1] . '\\' : '';
-
-                       $classesInFile = [];
-                       $aliasesInFile = [];
-
-                       foreach ( $matches as $match ) {
-                               if ( !empty( $match['class'] ) ) {
-                                       // 'class Foo {}'
-                                       $class = $fileNamespace . $match['class'];
-                                       $actual[$class] = $file;
-                                       $classesInFile[$class] = true;
-                               } else {
-                                       if ( !empty( $match['original'] ) ) {
-                                               // 'class_alias( "Foo", "Bar" );'
-                                               $aliasesInFile[$match['alias']] = $match['original'];
-                                       } else {
-                                               // 'class_alias( Foo::class, "Bar" );'
-                                               $aliasesInFile[$match['aliasString']] = $fileNamespace . $match['originalStatic'];
-                                       }
-                               }
-                       }
-
-                       // Only accept aliases for classes in the same file, because for correct
-                       // behavior, all aliases for a class must be set up when the class is loaded
-                       // (see <https://bugs.php.net/bug.php?id=61422>).
-                       foreach ( $aliasesInFile as $alias => $class ) {
-                               if ( isset( $classesInFile[$class] ) ) {
-                                       $actual[$alias] = $file;
-                               } else {
-                                       $actual[$alias] = "[original class not in $file]";
-                               }
-                       }
-               }
-
-               return [
-                       'expected' => $expected,
-                       'actual' => $actual,
-               ];
-       }
-
-       function testCoreClass() {
-               $this->assertTrue( class_exists( 'TestAutoloadedLocalClass' ) );
-       }
-
-       function testExtensionClass() {
-               $this->assertTrue( class_exists( 'TestAutoloadedClass' ) );
-       }
-
-       function testWrongCaseClass() {
-               $this->setMwGlobals( 'wgAutoloadAttemptLowercase', true );
-
-               $this->assertTrue( class_exists( 'testautoLoadedcamlCLASS' ) );
-       }
-
-       function testWrongCaseSerializedClass() {
-               $this->setMwGlobals( 'wgAutoloadAttemptLowercase', true );
-
-               $dummyCereal = 'O:29:"testautoloadedserializedclass":0:{}';
-               $uncerealized = unserialize( $dummyCereal );
-               $this->assertFalse( $uncerealized instanceof __PHP_Incomplete_Class,
-                       "unserialize() can load classes case-insensitively." );
-       }
-
-       function testAutoloadOrder() {
-               $path = realpath( __DIR__ . '/../../..' );
-               $oldAutoload = file_get_contents( $path . '/autoload.php' );
-               $generator = new AutoloadGenerator( $path, 'local' );
-               $generator->setExcludePaths( array_values( AutoLoader::getAutoloadNamespaces() ) );
-               $generator->initMediaWikiDefault();
-               $newAutoload = $generator->getAutoload( 'maintenance/generateLocalAutoload.php' );
-
-               $this->assertEquals( $oldAutoload, $newAutoload, 'autoload.php does not match' .
-                       ' output of generateLocalAutoload.php script.' );
-       }
-}
index 785e114..1922de5 100644 (file)
@@ -115,12 +115,6 @@ return [
                        'jquery.tablesorter',
                        'jquery.textSelection',
                        'mediawiki.api',
-                       'mediawiki.api.category',
-                       'mediawiki.api.messages',
-                       'mediawiki.api.options',
-                       'mediawiki.api.parse',
-                       'mediawiki.api.upload',
-                       'mediawiki.api.watch',
                        'mediawiki.ForeignApi.core',
                        'mediawiki.jqueryMsg',
                        'mediawiki.messagePoster',
index 2300949..3b710c4 100644 (file)
  * @author Lupo
  * @since 1.20
  */
+
+// This file doesn't run as part of MediaWiki
+// phpcs:disable MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals
+
 header( 'Content-Type: text/javascript; charset=utf-8' );
 
 $moduleImplementations = [
index 0e84581..e37f67d 100644 (file)
  * @author Timo Tijhof
  * @since 1.20
  */
+
+// This file doesn't run as part of MediaWiki
+// phpcs:disable MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals
+
 header( 'Content-Type: text/css; charset=utf-8' );
 
 /**
index d51dc37..d3f6533 100644 (file)
 
                $clone.find( '.mw-collapsible-toggle a' ).trigger( 'click' );
        } );
+
+       QUnit.test( 'T168689 - nested collapsible divs should keep independent state', function ( assert ) {
+               var $collapsible1 = prepareCollapsible(
+                               '<div class="mw-collapsible">' + loremIpsum + '</div>'
+                       ),
+                       $collapsible2 = prepareCollapsible(
+                               '<div class="mw-collapsible">' + loremIpsum + '</div>'
+                       );
+
+               $collapsible1
+                       .append( $collapsible2 )
+                       .appendTo( '#qunit-fixture' ).makeCollapsible();
+
+               $collapsible1.on( 'afterCollapse.mw-collapsible', function () {
+                       assert.assertTrue( $collapsible1.hasClass( 'mw-collapsed' ), 'after collapsing: parent is collapsed' );
+                       assert.assertFalse( $collapsible2.hasClass( 'mw-collapsed' ), 'after collapsing: child is not collapsed' );
+                       assert.assertTrue( $collapsible1.find( '> .mw-collapsible-toggle' ).hasClass( 'mw-collapsible-toggle-collapsed' ) );
+                       assert.assertFalse( $collapsible2.find( '> .mw-collapsible-toggle' ).hasClass( 'mw-collapsible-toggle-collapsed' ) );
+               } ).find( '> .mw-collapsible-toggle a' ).trigger( 'click' );
+       } );
 }( jQuery ) );
index 74caf5c..495ce74 100644 (file)
                                '<tr><td>B</td></tr>' +
                                '<tr><td>G</td></tr>' +
                                '<tr><td data-sort-value="F">C</td></tr>' +
+                               '<tr><td><span data-sort-value="D">H</span></td></tr>' +
                                '</tbody></table>'
                );
                $table.tablesorter().find( '.headerSort:eq(0)' ).click();
                                data: undefined,
                                text: 'D'
                        },
+                       {
+                               data: undefined,
+                               text: 'H'
+                       },
                        {
                                data: 'E',
                                text: 'A'
index d6fe744..e8db4e1 100644 (file)
                title = new mw.Title( 'Foo \u00A0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202F\u205F\u3000 bar' );
                assert.equal( title.getMain(), 'Foo_bar', 'Merge multiple types of whitespace/underscores into a single underscore' );
 
-               title = new mw.Title( 'Foo\u200E\u200F\u202A\u202B\u202C\u202D\u202Ebar' );
-               assert.equal( title.getMain(), 'Foobar', 'Strip Unicode bidi override characters' );
+               title = new mw.Title( 'Foo\u00AD\u061C\u200E\u200F\u202A\u202B\u202C\u202D\u202E\u2066\u2067\u2068\u2069bar' );
+               assert.equal( title.getMain(), 'Foobar', 'Strip soft hyphen and Unicode directional formatting characters' );
 
                // Regression test: Previously it would only detect an extension if there is no space after it
                title = new mw.Title( 'Example.js  ' );
                                },
                                {
                                        fileName: 'BI\u200EDI.jpg',
-                                       typeOfName: 'Name containing BIDI overrides',
+                                       typeOfName: 'Name containing Unicode directional formatting characters',
                                        nameText: 'BIDI',
                                        prefixedText: 'File:BIDI.jpg'
                                },
index 119222a..75dc665 100644 (file)
                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.strictEqual( conf.set( null, 'Null' ), false, 'Map.set returns false if key is invalid (null)' );
+               assert.strictEqual( conf.set( {}, 'Object' ), false, 'Map.set returns false if key is invalid (plain object)' );
 
                conf.set( String( nummy ), 'I used to be a number' );
 
index 3b71413..a3c9d84 100644 (file)
--- a/thumb.php
+++ b/thumb.php
@@ -35,7 +35,7 @@ if ( defined( 'THUMB_HANDLER' ) ) {
        wfThumbHandle404();
 } else {
        // Called directly, use $_GET params
-       wfStreamThumb( $_GET );
+       wfStreamThumb( $wgRequest->getQueryValues() );
 }
 
 $mediawiki = new MediaWiki();