Merge "Fix @covers for FileBackend"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 7 Mar 2017 07:08:17 +0000 (07:08 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 7 Mar 2017 07:08:17 +0000 (07:08 +0000)
564 files changed:
.stylelintrc
CREDITS
Gemfile
Gemfile.lock
RELEASE-NOTES-1.29
api.php
autoload.php
composer.json
docs/uidesign/child-selector-emu.html
img_auth.php
includes/Block.php
includes/Category.php
includes/DefaultSettings.php
includes/Defines.php
includes/EditPage.php
includes/FeedUtils.php
includes/GlobalFunctions.php
includes/HistoryBlob.php
includes/Html.php
includes/Linker.php
includes/MWTimestamp.php
includes/MagicWord.php
includes/MediaWiki.php
includes/MergeHistory.php
includes/MovePage.php
includes/NoLocalSettings.php
includes/OutputPage.php
includes/PHPVersionCheck.php
includes/Preferences.php
includes/PrefixSearch.php
includes/Revision.php
includes/RevisionList.php
includes/Sanitizer.php
includes/Setup.php
includes/Title.php
includes/TitleArray.php
includes/TitleArrayFromResult.php
includes/WatchedItemQueryService.php
includes/WatchedItemQueryServiceExtension.php
includes/WebRequest.php
includes/WebStart.php
includes/Xml.php
includes/actions/HistoryAction.php
includes/api/ApiBase.php
includes/api/ApiBlock.php
includes/api/ApiFeedRecentChanges.php
includes/api/ApiFormatBase.php
includes/api/ApiFormatJson.php
includes/api/ApiFormatPhp.php
includes/api/ApiLogin.php
includes/api/ApiMain.php
includes/api/ApiMove.php
includes/api/ApiPageSet.php
includes/api/ApiQueryAllDeletedRevisions.php
includes/api/ApiQueryAllRevisions.php
includes/api/ApiQueryAllUsers.php
includes/api/ApiQueryBacklinks.php
includes/api/ApiQueryBase.php
includes/api/ApiQueryDeletedRevisions.php
includes/api/ApiQueryDeletedrevs.php
includes/api/ApiQueryImageInfo.php
includes/api/ApiQueryLogEvents.php
includes/api/ApiQueryRecentChanges.php
includes/api/ApiQueryRevisions.php
includes/api/ApiQuerySiteinfo.php
includes/api/ApiResult.php
includes/api/ApiUnblock.php
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/mk.json
includes/api/i18n/pl.json
includes/api/i18n/pt.json
includes/api/i18n/qqq.json
includes/api/i18n/sv.json
includes/api/i18n/zh-hans.json
includes/api/i18n/zh-hant.json
includes/cache/BacklinkCache.php
includes/cache/LinkBatch.php
includes/cache/MessageBlobStore.php
includes/changes/ChangesFeed.php
includes/changes/ChangesList.php
includes/changes/EnhancedChangesList.php
includes/changes/OldChangesList.php
includes/changes/RCCacheEntryFactory.php
includes/collation/CollationEt.php
includes/collation/IcuCollation.php
includes/compat/Timestamp.php [new file with mode: 0644]
includes/content/ContentHandler.php
includes/content/FileContentHandler.php
includes/content/TextContentHandler.php
includes/content/WikiTextStructure.php
includes/content/WikitextContentHandler.php
includes/context/RequestContext.php
includes/db/CloneDatabase.php
includes/db/DatabaseOracle.php
includes/debug/MWDebug.php
includes/debug/logger/monolog/KafkaHandler.php
includes/deferred/DeferredUpdates.php
includes/deferred/LinksUpdate.php
includes/diff/DifferenceEngine.php
includes/diff/WordAccumulator.php
includes/exception/ErrorPageError.php
includes/exception/MWExceptionHandler.php
includes/exception/UserNotLoggedIn.php
includes/export/WikiExporter.php
includes/filerepo/FileRepo.php
includes/filerepo/LocalRepo.php
includes/filerepo/file/File.php
includes/filerepo/file/LocalFile.php
includes/htmlform/HTMLForm.php
includes/http/Http.php
includes/http/MWHttpRequest.php
includes/import/WikiImporter.php
includes/installer/DatabaseUpdater.php
includes/installer/Installer.php
includes/installer/MysqlUpdater.php
includes/installer/PostgresUpdater.php
includes/installer/SqliteInstaller.php
includes/installer/WebInstaller.php
includes/installer/WebInstallerName.php
includes/installer/WebInstallerOutput.php
includes/installer/WebInstallerPage.php
includes/installer/WebInstallerUpgrade.php
includes/installer/i18n/ckb.json
includes/installer/i18n/fa.json
includes/installer/i18n/he.json
includes/installer/i18n/hi.json
includes/installer/i18n/mk.json
includes/jobqueue/JobQueueDB.php
includes/jobqueue/JobQueueRedis.php
includes/jobqueue/jobs/DoubleRedirectJob.php
includes/jobqueue/jobs/PublishStashedFileJob.php
includes/jobqueue/jobs/RefreshLinksJob.php
includes/jobqueue/utils/BacklinkJobUtils.php
includes/libs/CSSMin.php
includes/libs/CryptHKDF.php
includes/libs/IP.php
includes/libs/StatusValue.php
includes/libs/filebackend/FSFileBackend.php
includes/libs/filebackend/FileBackendStore.php
includes/libs/filebackend/HTTPFileStreamer.php
includes/libs/filebackend/SwiftFileBackend.php
includes/libs/mime/mime.info
includes/libs/objectcache/RESTBagOStuff.php
includes/libs/objectcache/RedisBagOStuff.php
includes/libs/objectcache/WANObjectCache.php
includes/libs/objectcache/WinCacheBagOStuff.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/MssqlResultWrapper.php
includes/libs/rdbms/database/resultwrapper/ResultWrapper.php
includes/libs/rdbms/lbfactory/LBFactory.php
includes/libs/time/ConvertibleTimestamp.php [deleted file]
includes/libs/time/TimestampException.php [deleted file]
includes/libs/time/defines.php [deleted file]
includes/libs/xmp/XMP.php
includes/libs/xmp/XMPInfo.php
includes/libs/xmp/XMPValidate.php
includes/logging/LogFormatter.php
includes/logging/LogPager.php
includes/mail/EmailNotification.php
includes/mail/UserMailer.php
includes/media/Bitmap.php
includes/media/DjVuImage.php
includes/media/FormatMetadata.php
includes/media/Jpeg.php
includes/media/MediaHandler.php
includes/media/SVGMetadataExtractor.php
includes/objectcache/SqlBagOStuff.php
includes/page/Article.php
includes/page/ImagePage.php
includes/page/PageAcrhive.php [new file with mode: 0644]
includes/page/WikiFilePage.php
includes/page/WikiPage.php
includes/pager/IndexPager.php
includes/pager/ReverseChronologicalPager.php
includes/parser/BlockLevelPass.php
includes/parser/CoreParserFunctions.php
includes/parser/DateFormatter.php
includes/parser/Parser.php
includes/parser/ParserCache.php
includes/parser/ParserOptions.php
includes/parser/ParserOutput.php
includes/parser/Preprocessor_DOM.php
includes/parser/Preprocessor_Hash.php
includes/poolcounter/PoolWorkArticleView.php
includes/profiler/output/ProfilerOutputDb.php
includes/registration/Processor.php
includes/registration/VersionChecker.php
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderClientHtml.php
includes/resourceloader/ResourceLoaderContext.php
includes/resourceloader/ResourceLoaderModule.php
includes/resourceloader/ResourceLoaderStartUpModule.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/revisiondelete/RevDelRevisionList.php
includes/search/SearchIndexFieldDefinition.php
includes/search/SqlSearchResultSet.php
includes/session/SessionManagerInterface.php
includes/session/SessionProvider.php
includes/skins/BaseTemplate.php
includes/skins/Skin.php
includes/skins/SkinTemplate.php
includes/specialpage/ChangesListSpecialPage.php
includes/specialpage/ImageQueryPage.php
includes/specialpage/LoginSignupSpecialPage.php
includes/specialpage/PageQueryPage.php
includes/specialpage/QueryPage.php
includes/specialpage/SpecialPageFactory.php
includes/specialpage/WantedQueryPage.php
includes/specials/SpecialBlock.php
includes/specials/SpecialBrokenRedirects.php
includes/specials/SpecialContributions.php
includes/specials/SpecialDoubleRedirects.php
includes/specials/SpecialEditWatchlist.php
includes/specials/SpecialExpandTemplates.php
includes/specials/SpecialExport.php
includes/specials/SpecialLinkSearch.php
includes/specials/SpecialListDuplicatedFiles.php
includes/specials/SpecialListredirects.php
includes/specials/SpecialLog.php
includes/specials/SpecialMediaStatistics.php
includes/specials/SpecialMostcategories.php
includes/specials/SpecialMostinterwikis.php
includes/specials/SpecialMostlinked.php
includes/specials/SpecialMostlinkedcategories.php
includes/specials/SpecialMostlinkedtemplates.php
includes/specials/SpecialMovepage.php
includes/specials/SpecialPrefixindex.php
includes/specials/SpecialProtectedpages.php
includes/specials/SpecialRecentchanges.php
includes/specials/SpecialShortpages.php
includes/specials/SpecialStatistics.php
includes/specials/SpecialUnblock.php
includes/specials/SpecialUndelete.php
includes/specials/SpecialUnusedcategories.php
includes/specials/SpecialUnwatchedpages.php
includes/specials/SpecialUploadStash.php
includes/specials/SpecialUserLogout.php
includes/specials/SpecialUserrights.php
includes/specials/SpecialWantedfiles.php
includes/specials/SpecialWatchlist.php
includes/specials/pagers/AllMessagesTablePager.php
includes/specials/pagers/BlockListPager.php
includes/specials/pagers/ContribsPager.php
includes/specials/pagers/DeletedContribsPager.php
includes/specials/pagers/ImageListPager.php
includes/specials/pagers/ProtectedPagesPager.php [new file with mode: 0644]
includes/specials/pagers/UsersPager.php
includes/tidy/Balancer.php
includes/upload/UploadBase.php
includes/user/PasswordReset.php
includes/user/User.php
includes/user/UserArray.php
includes/user/UserArrayFromResult.php
includes/utils/AutoloadGenerator.php
includes/utils/BatchRowIterator.php
includes/utils/MWCryptHKDF.php
includes/widget/search/SearchFormWidget.php
languages/Language.php
languages/LanguageConverter.php
languages/classes/LanguageAr.php
languages/classes/LanguageKsh.php
languages/classes/LanguageLa.php
languages/classes/LanguageMl.php
languages/classes/LanguageTr.php
languages/data/Names.php
languages/data/ZhConversion.php
languages/i18n/aeb-arab.json
languages/i18n/ar.json
languages/i18n/ast.json
languages/i18n/be-tarask.json
languages/i18n/be.json
languages/i18n/bho.json
languages/i18n/bn.json
languages/i18n/bqi.json
languages/i18n/br.json
languages/i18n/bs.json
languages/i18n/ca.json
languages/i18n/ce.json
languages/i18n/ckb.json
languages/i18n/cu.json
languages/i18n/da.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/el.json
languages/i18n/en-gb.json
languages/i18n/en.json
languages/i18n/es.json
languages/i18n/eu.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/gl.json
languages/i18n/glk.json
languages/i18n/gsw.json
languages/i18n/he.json
languages/i18n/hr.json
languages/i18n/hy.json
languages/i18n/id.json
languages/i18n/inh.json
languages/i18n/it.json
languages/i18n/ka.json
languages/i18n/km.json
languages/i18n/ko.json
languages/i18n/lij.json
languages/i18n/lt.json
languages/i18n/lv.json
languages/i18n/mg.json
languages/i18n/mhr.json
languages/i18n/mk.json
languages/i18n/nb.json
languages/i18n/nl.json
languages/i18n/nn.json
languages/i18n/oc.json
languages/i18n/pl.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/ru.json
languages/i18n/rue.json
languages/i18n/sh.json
languages/i18n/si.json
languages/i18n/sk.json
languages/i18n/sl.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/sv.json
languages/i18n/te.json
languages/i18n/tr.json
languages/i18n/tyv.json
languages/i18n/uk.json
languages/i18n/xmf.json
languages/i18n/yue.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
languages/messages/MessagesArz.php
languages/messages/MessagesCs.php
languages/messages/MessagesEn.php
languages/messages/MessagesEu.php
languages/messages/MessagesGn.php
languages/messages/MessagesKbd_cyrl.php
languages/messages/MessagesLad.php
languages/messages/MessagesLn.php
languages/messages/MessagesNah.php
languages/messages/MessagesPl.php
languages/messages/MessagesPt.php
languages/messages/MessagesQu.php
languages/messages/MessagesQug.php
languages/messages/MessagesSv.php
languages/messages/MessagesSzl.php
languages/messages/MessagesTe.php
languages/messages/MessagesZea.php
maintenance/archives/patch-archive-ar_id.sql
maintenance/archives/patch-categorylinks-better-collation.sql
maintenance/archives/patch-externallinks-el_id.sql
maintenance/archives/patch-up_property.sql
maintenance/benchmarks/bench_utf8_title_check.php
maintenance/cleanupImages.php
maintenance/cleanupRemovedModules.php
maintenance/cleanupTitles.php
maintenance/convertUserOptions.php
maintenance/fixDoubleRedirects.php
maintenance/generateSitemap.php
maintenance/hhvm/makeRepo.php
maintenance/importImages.php
maintenance/initUserPreference.php [new file with mode: 0644]
maintenance/language/zhtable/toCN.manual
maintenance/language/zhtable/toHK.manual
maintenance/language/zhtable/toSimp.manual
maintenance/language/zhtable/toTW.manual
maintenance/language/zhtable/tradphrases.manual
maintenance/language/zhtable/tradphrases_exclude.manual
maintenance/migrateUserGroup.php
maintenance/mssql/tables.sql
maintenance/namespaceDupes.php
maintenance/populateRevisionLength.php
maintenance/populateRevisionSha1.php
maintenance/purgeChangedPages.php
maintenance/purgeModuleDeps.php [new file with mode: 0644]
maintenance/rebuildFileCache.php
maintenance/refreshLinks.php
maintenance/sql.php
maintenance/sqlite/archives/initial-indexes.sql
maintenance/storage/fixBug20757.php [deleted file]
maintenance/storage/fixT22757.php [new file with mode: 0644]
maintenance/storage/trackBlobs.php
maintenance/tables.sql
maintenance/update.php
maintenance/userDupes.inc
mw-config/config.css
resources/Resources.php
resources/lib/oojs-ui/i18n/bqi.json
resources/lib/oojs-ui/i18n/br.json
resources/lib/oojs-ui/i18n/mg.json
resources/lib/oojs-ui/i18n/nn.json
resources/lib/oojs-ui/i18n/pnb.json
resources/lib/oojs-ui/i18n/yi.json
resources/lib/oojs-ui/oojs-ui-apex.js
resources/lib/oojs-ui/oojs-ui-core-apex.css
resources/lib/oojs-ui/oojs-ui-core-mediawiki.css
resources/lib/oojs-ui/oojs-ui-core.js
resources/lib/oojs-ui/oojs-ui-mediawiki.js
resources/lib/oojs-ui/oojs-ui-toolbars-apex.css
resources/lib/oojs-ui/oojs-ui-toolbars-mediawiki.css
resources/lib/oojs-ui/oojs-ui-toolbars.js
resources/lib/oojs-ui/oojs-ui-widgets-apex.css
resources/lib/oojs-ui/oojs-ui-widgets-mediawiki.css
resources/lib/oojs-ui/oojs-ui-widgets.js
resources/lib/oojs-ui/oojs-ui-windows-apex.css
resources/lib/oojs-ui/oojs-ui-windows-mediawiki.css
resources/lib/oojs-ui/oojs-ui-windows.js
resources/lib/oojs-ui/themes/apex/icons-editing-advanced.json
resources/lib/oojs-ui/themes/apex/icons-interactions.json
resources/lib/oojs-ui/themes/apex/images/icons/case-sensitive.svg
resources/lib/oojs-ui/themes/apex/images/icons/diacritic.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/diacritic.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr-invert.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr-invert.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl-invert.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl-invert.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/icons-editing-advanced.json
resources/lib/oojs-ui/themes/mediawiki/icons-interactions.json
resources/lib/oojs-ui/themes/mediawiki/images/icons/case-sensitive-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/case-sensitive-progressive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/case-sensitive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic-invert.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic-invert.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic-progressive.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic-progressive.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr-invert.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr-invert.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr-progressive.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr-progressive.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl-invert.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl-invert.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl-progressive.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl-progressive.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl.svg [new file with mode: 0644]
resources/src/dom-level2-skip.js [deleted file]
resources/src/jquery/jquery.tablesorter.less
resources/src/mediawiki.action/mediawiki.action.edit.collapsibleFooter.js
resources/src/mediawiki.action/mediawiki.action.edit.styles.css
resources/src/mediawiki.action/mediawiki.action.history.css
resources/src/mediawiki.action/mediawiki.action.view.categoryPage.less
resources/src/mediawiki.action/mediawiki.action.view.postEdit.css
resources/src/mediawiki.action/mediawiki.action.view.redirectPage.css
resources/src/mediawiki.legacy/commonPrint.css
resources/src/mediawiki.legacy/shared.css
resources/src/mediawiki.less/mediawiki.mixins.less
resources/src/mediawiki.less/mediawiki.mixins.rotation.less
resources/src/mediawiki.less/mediawiki.ui/mixins.less
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ChangesListViewModel.js
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterItem.js
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js
resources/src/mediawiki.rcfilters/images/marker-ltr.svg [new file with mode: 0644]
resources/src/mediawiki.rcfilters/images/marker-rtl.svg [new file with mode: 0644]
resources/src/mediawiki.rcfilters/images/pending.gif [new file with mode: 0644]
resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
resources/src/mediawiki.rcfilters/mw.rcfilters.init.js
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.mixins.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.CapsuleItemWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesListWrapperWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterCapsuleMultiselectWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterGroupWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterItemHighlightButton.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterItemWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterWrapperWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FiltersListWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.HighlightColorPickerWidget.less
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.CapsuleItemWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterCapsuleMultiselectWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterGroupWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemHighlightButton.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FiltersListWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FormWrapperWidget.js
resources/src/mediawiki.skinning/content.externallinks.css
resources/src/mediawiki.skinning/content.parsoid.less
resources/src/mediawiki.special/mediawiki.special.apisandbox.js
resources/src/mediawiki.special/mediawiki.special.block.css
resources/src/mediawiki.special/mediawiki.special.comparepages.styles.less
resources/src/mediawiki.special/mediawiki.special.preferences.js
resources/src/mediawiki.special/mediawiki.special.search.interwikiwidget.styles.less
resources/src/mediawiki.toolbar/toolbar.less
resources/src/mediawiki.ui/components/anchors.less
resources/src/mediawiki.ui/components/buttons.less
resources/src/mediawiki.ui/components/checkbox.less
resources/src/mediawiki.ui/components/forms.less
resources/src/mediawiki.ui/components/icons.less
resources/src/mediawiki.ui/components/inputs.less
resources/src/mediawiki.ui/components/radio.less
resources/src/mediawiki.ui/components/text.less
resources/src/mediawiki.ui/default.less
resources/src/mediawiki.widgets.datetime/CalendarWidget.less
resources/src/mediawiki.widgets.datetime/DateTimeInputWidget.less
resources/src/mediawiki.widgets.datetime/mediawiki.widgets.datetime.definitions.less
resources/src/mediawiki.widgets/mw.widgets.CalendarWidget.less
resources/src/mediawiki/htmlform/styles.css
resources/src/mediawiki/mediawiki.diff.styles.css
resources/src/mediawiki/mediawiki.filewarning.less
resources/src/mediawiki/mediawiki.helplink.less
resources/src/mediawiki/mediawiki.hlist.css
resources/src/mediawiki/mediawiki.icon.less
resources/src/mediawiki/mediawiki.inspect.js
resources/src/mediawiki/mediawiki.js
resources/src/mediawiki/mediawiki.pager.tablePager.less
resources/src/mediawiki/mediawiki.requestIdleCallback.js
resources/src/mediawiki/mediawiki.storage.js
resources/src/mediawiki/mediawiki.user.js
resources/src/mediawiki/page/gallery-slideshow.js
resources/src/polyfill-nodeTypes.js [deleted file]
tests/browser/features/step_definitions/login_steps.rb
tests/browser/features/step_definitions/preferences_appearance_steps.rb
tests/browser/features/step_definitions/preferences_editing_steps.rb
tests/browser/features/step_definitions/preferences_user_profile_steps.rb
tests/browser/features/support/pages/login_page.rb
tests/parser/ParserTestRunner.php
tests/parser/extraParserTests.txt
tests/phpunit/autoload.ide.php
tests/phpunit/includes/MWNamespaceTest.php
tests/phpunit/includes/MessageTest.php
tests/phpunit/includes/content/ContentHandlerTest.php
tests/phpunit/includes/db/LBFactoryTest.php
tests/phpunit/includes/deferred/DeferredUpdatesTest.php
tests/phpunit/includes/http/HttpTest.php
tests/phpunit/includes/libs/time/ConvertibleTimestampTest.php [deleted file]
tests/phpunit/includes/objectcache/RESTBagOStuffTest.php
tests/phpunit/includes/parser/ParserMethodsTest.php
tests/phpunit/includes/parser/ParserPreloadTest.php
tests/phpunit/includes/parser/TagHooksTest.php
tests/phpunit/includes/search/SearchIndexFieldTest.php
tests/phpunit/includes/tidy/BalancerTest.php
tests/phpunit/includes/utils/UIDGeneratorTest.php
tests/phpunit/suite.xml
tests/qunit/QUnitTestResources.php
tests/qunit/suites/resources/mediawiki.rcfilters/dm.FilterItem.test.js [new file with mode: 0644]
tests/qunit/suites/resources/mediawiki/mediawiki.inspect.test.js [new file with mode: 0644]
tests/qunit/suites/resources/mediawiki/mediawiki.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.user.test.js
thumb.php

index 5a7b29f..27e289d 100644 (file)
@@ -1,15 +1,8 @@
 {
        "extends": "stylelint-config-wikimedia",
        "rules": {
-               "declaration-no-important": null,
-
                "no-descending-specificity": null,
 
-               "selector-no-id": null,
-               "selector-pseudo-element-colon-notation": null,
-
-               "string-quotes": null,
-
-               "value-keyword-case": null
+               "selector-no-id": null
        }
 }
diff --git a/CREDITS b/CREDITS
index b37edf2..e8af23c 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -169,6 +169,7 @@ The following list can be found parsed under Special:Version/Credits -->
 * Ed Sanders
 * Edward Chernenko
 * Edward Z. Yang
+* Eddie Greiner-Petter
 * Elisabeth Bauer
 * Elliott Eggleston
 * Elvis Stansvik
diff --git a/Gemfile b/Gemfile
index 8bbd00f..ee0cec0 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -1,5 +1,5 @@
 source 'https://rubygems.org'
 
-gem 'mediawiki_selenium', '~> 1.7', '>= 1.7.4'
+gem 'mediawiki_selenium', '~> 1.8'
 gem 'rake', '~> 11.1', '>= 11.1.1'
 gem 'rubocop', '~> 0.32.1', require: false
index 8243874..4992303 100644 (file)
@@ -4,8 +4,8 @@ GEM
     ast (2.0.0)
     astrolabe (1.3.0)
       parser (>= 2.2.0.pre.3, < 3.0)
-    builder (3.2.2)
-    childprocess (0.5.9)
+    builder (3.2.3)
+    childprocess (0.6.2)
       ffi (~> 1.0, >= 1.0.11)
     cucumber (1.3.20)
       builder (>= 2.1.2)
@@ -16,40 +16,40 @@ GEM
     data_magic (1.0)
       faker (>= 1.1.2)
       yml_reader (>= 0.6)
-    diff-lcs (1.2.5)
-    domain_name (0.5.20161129)
+    diff-lcs (1.3)
+    domain_name (0.5.20170223)
       unf (>= 0.0.5, < 1.0.0)
-    faker (1.7.1)
+    faker (1.7.3)
       i18n (~> 0.5)
-    faraday (0.10.0)
+    faraday (0.11.0)
       multipart-post (>= 1.2, < 3)
     faraday-cookie_jar (0.0.6)
       faraday (>= 0.7.4)
       http-cookie (~> 1.0.0)
-    faraday_middleware (0.10.1)
+    faraday_middleware (0.11.0.1)
       faraday (>= 0.7.4, < 1.0)
-    ffi (1.9.14)
+    ffi (1.9.17)
     gherkin (2.12.2)
       multi_json (~> 1.3)
     headless (2.3.1)
     http-cookie (1.0.3)
       domain_name (~> 0.5)
-    i18n (0.7.0)
-    json (2.0.2)
-    mediawiki_api (0.7.0)
+    i18n (0.8.1)
+    json (2.0.3)
+    mediawiki_api (0.7.1)
       faraday (~> 0.9, >= 0.9.0)
       faraday-cookie_jar (~> 0.0, >= 0.0.6)
       faraday_middleware (~> 0.10, >= 0.10.0)
-    mediawiki_selenium (1.7.4)
+    mediawiki_selenium (1.8.0)
       cucumber (~> 1.3, >= 1.3.20)
       headless (~> 2.0, >= 2.1.0)
       json (~> 2.0, >= 2.0.2)
       mediawiki_api (~> 0.7, >= 0.7.0)
-      page-object (~> 1.0)
+      page-object (~> 2.0)
       rest-client (~> 1.6, >= 1.6.7)
       rspec-core (~> 2.14, >= 2.14.4)
       rspec-expectations (~> 2.14, >= 2.14.4)
-      selenium-webdriver (< 3)
+      selenium-webdriver (~> 3.1.0)
       syntax (~> 1.2, >= 1.2.0)
       thor (~> 0.19, >= 0.19.1)
     mime-types (2.99.3)
@@ -58,11 +58,11 @@ GEM
     multipart-post (2.0.0)
     net-http-persistent (2.9.4)
     netrc (0.11.0)
-    page-object (1.2.2)
+    page-object (2.0.0)
       net-http-persistent (~> 2.9.4)
       page_navigation (>= 0.9)
-      selenium-webdriver (>= 2.53.0)
-      watir-webdriver (>= 0.6.11, < 0.9.9)
+      selenium-webdriver (~> 3.0)
+      watir (~> 6.0)
     page_navigation (0.10)
       data_magic (>= 0.22)
     parser (2.2.2.6)
@@ -84,8 +84,8 @@ GEM
       rainbow (>= 1.99.1, < 3.0)
       ruby-progressbar (~> 1.4)
     ruby-progressbar (1.7.5)
-    rubyzip (1.2.0)
-    selenium-webdriver (2.53.4)
+    rubyzip (1.2.1)
+    selenium-webdriver (3.1.0)
       childprocess (~> 0.5)
       rubyzip (~> 1.0)
       websocket (~> 1.0)
@@ -94,18 +94,18 @@ GEM
     unf (0.1.4)
       unf_ext
     unf_ext (0.0.7.2)
-    watir-webdriver (0.9.3)
-      selenium-webdriver (>= 2.46.2)
-    websocket (1.2.3)
+    watir (6.2.0)
+      selenium-webdriver (~> 3.0)
+    websocket (1.2.4)
     yml_reader (0.7)
 
 PLATFORMS
   ruby
 
 DEPENDENCIES
-  mediawiki_selenium (~> 1.7, >= 1.7.4)
+  mediawiki_selenium (~> 1.8)
   rake (~> 11.1, >= 11.1.1)
   rubocop (~> 0.32.1)
 
 BUNDLED WITH
-   1.13.7
+   1.14.5
index a1ce9d9..9883474 100644 (file)
@@ -58,6 +58,7 @@ production.
 === External library changes in 1.29 ===
 
 ==== Upgraded external libraries ====
+* Added wikimedia/timestamp v1.0.0.
 * Updated QUnit from v1.22.0 to v1.23.1.
 * Updated cssjanus from v1.1.2 to 1.1.3.
 * Updated psr/log from v1.0.0 to v1.0.2.
@@ -105,6 +106,8 @@ production.
 * Added action=validatepassword to validate passwords for the account creation
   and password change forms.
 * action=purge now requires a POST.
+* There is a new `languagevariants` siprop for action=query&meta=siteinfo,
+  which returns a list of languages with active LanguageConverter instances.
 
 === Action API internal changes in 1.29 ===
 * New methods were added to ApiBase to handle errors and warnings using i18n
diff --git a/api.php b/api.php
index 6e75fb7..a6ce3b2 100644 (file)
--- a/api.php
+++ b/api.php
@@ -63,7 +63,7 @@ RequestContext::getMain()->setTitle( $wgTitle );
 try {
        /* Construct an ApiMain with the arguments passed via the URL. What we get back
         * is some form of an ApiMain, possibly even one that produces an error message,
-        * but we don't care here, as that is handled by the ctor.
+        * but we don't care here, as that is handled by the constructor.
         */
        $processor = new ApiMain( RequestContext::getMain(), $wgEnableWriteAPI );
 
index e56b681..8c63d4f 100644 (file)
@@ -289,7 +289,6 @@ $wgAutoloadLocalClasses = [
        'ConvertLinks' => __DIR__ . '/maintenance/convertLinks.php',
        'ConvertUserOptions' => __DIR__ . '/maintenance/convertUserOptions.php',
        'ConverterRule' => __DIR__ . '/languages/ConverterRule.php',
-       'ConvertibleTimestamp' => __DIR__ . '/includes/libs/time/ConvertibleTimestamp.php',
        'Cookie' => __DIR__ . '/includes/libs/Cookie.php',
        'CookieJar' => __DIR__ . '/includes/libs/CookieJar.php',
        'CopyFileBackend' => __DIR__ . '/maintenance/copyFileBackend.php',
@@ -487,10 +486,10 @@ $wgAutoloadLocalClasses = [
        'FindHooks' => __DIR__ . '/maintenance/findHooks.php',
        'FindMissingFiles' => __DIR__ . '/maintenance/findMissingFiles.php',
        'FindOrphanedFiles' => __DIR__ . '/maintenance/findOrphanedFiles.php',
-       'FixBug20757' => __DIR__ . '/maintenance/storage/fixBug20757.php',
        'FixDefaultJsonContentPages' => __DIR__ . '/maintenance/fixDefaultJsonContentPages.php',
        'FixDoubleRedirects' => __DIR__ . '/maintenance/fixDoubleRedirects.php',
        'FixExtLinksProtocolRelative' => __DIR__ . '/maintenance/fixExtLinksProtocolRelative.php',
+       'FixT22757' => __DIR__ . '/maintenance/storage/fixT22757.php',
        'FixTimestamps' => __DIR__ . '/maintenance/fixTimestamps.php',
        'FixUserRegistration' => __DIR__ . '/maintenance/fixUserRegistration.php',
        'ForeignAPIFile' => __DIR__ . '/includes/filerepo/file/ForeignAPIFile.php',
@@ -629,6 +628,7 @@ $wgAutoloadLocalClasses = [
        'InfoAction' => __DIR__ . '/includes/actions/InfoAction.php',
        'InitEditCount' => __DIR__ . '/maintenance/initEditCount.php',
        'InitSiteStats' => __DIR__ . '/maintenance/initSiteStats.php',
+       'InitUserPreference' => __DIR__ . '/maintenance/initUserPreference.php',
        'InstallDocFormatter' => __DIR__ . '/includes/installer/InstallDocFormatter.php',
        'Installer' => __DIR__ . '/includes/installer/Installer.php',
        'InstallerOverrides' => __DIR__ . '/includes/installer/InstallerOverrides.php',
@@ -974,7 +974,6 @@ $wgAutoloadLocalClasses = [
        'MovePage' => __DIR__ . '/includes/MovePage.php',
        'MovePageForm' => __DIR__ . '/includes/specials/SpecialMovepage.php',
        'MssqlInstaller' => __DIR__ . '/includes/installer/MssqlInstaller.php',
-       'MssqlResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/MssqlResultWrapper.php',
        'MssqlUpdater' => __DIR__ . '/includes/installer/MssqlUpdater.php',
        'MultiConfig' => __DIR__ . '/includes/config/MultiConfig.php',
        'MultiHttpClient' => __DIR__ . '/includes/libs/MultiHttpClient.php',
@@ -1046,7 +1045,7 @@ $wgAutoloadLocalClasses = [
        'PackedImageGallery' => __DIR__ . '/includes/gallery/PackedImageGallery.php',
        'PackedOverlayImageGallery' => __DIR__ . '/includes/gallery/PackedOverlayImageGallery.php',
        'Page' => __DIR__ . '/includes/page/Page.php',
-       'PageArchive' => __DIR__ . '/includes/specials/SpecialUndelete.php',
+       'PageArchive' => __DIR__ . '/includes/page/PageAcrhive.php',
        'PageExists' => __DIR__ . '/maintenance/pageExists.php',
        'PageLangLogFormatter' => __DIR__ . '/includes/logging/PageLangLogFormatter.php',
        'PageProps' => __DIR__ . '/includes/PageProps.php',
@@ -1118,7 +1117,7 @@ $wgAutoloadLocalClasses = [
        'Protect' => __DIR__ . '/maintenance/protect.php',
        'ProtectAction' => __DIR__ . '/includes/actions/ProtectAction.php',
        'ProtectLogFormatter' => __DIR__ . '/includes/logging/ProtectLogFormatter.php',
-       'ProtectedPagesPager' => __DIR__ . '/includes/specials/SpecialProtectedpages.php',
+       'ProtectedPagesPager' => __DIR__ . '/includes/specials/pagers/ProtectedPagesPager.php',
        'ProtectedTitlesPager' => __DIR__ . '/includes/specials/pagers/ProtectedTitlesPager.php',
        'ProtectionForm' => __DIR__ . '/includes/ProtectionForm.php',
        'ProxyLookup' => __DIR__ . '/includes/ProxyLookup.php',
@@ -1129,6 +1128,7 @@ $wgAutoloadLocalClasses = [
        'PurgeChangedPages' => __DIR__ . '/maintenance/purgeChangedPages.php',
        'PurgeJobUtils' => __DIR__ . '/includes/jobqueue/utils/PurgeJobUtils.php',
        'PurgeList' => __DIR__ . '/maintenance/purgeList.php',
+       'PurgeModuleDeps' => __DIR__ . '/maintenance/purgeModuleDeps.php',
        'PurgeOldText' => __DIR__ . '/maintenance/purgeOldText.php',
        'PurgeParserCache' => __DIR__ . '/maintenance/purgeParserCache.php',
        'QueryPage' => __DIR__ . '/includes/specialpage/QueryPage.php',
@@ -1438,7 +1438,6 @@ $wgAutoloadLocalClasses = [
        'ThumbnailRenderJob' => __DIR__ . '/includes/jobqueue/jobs/ThumbnailRenderJob.php',
        'TidyUpBug37714' => __DIR__ . '/maintenance/tidyUpBug37714.php',
        'TiffHandler' => __DIR__ . '/includes/media/Tiff.php',
-       'TimestampException' => __DIR__ . '/includes/libs/time/TimestampException.php',
        'Timing' => __DIR__ . '/includes/libs/Timing.php',
        'Title' => __DIR__ . '/includes/Title.php',
        'TitleArray' => __DIR__ . '/includes/TitleArray.php',
@@ -1583,6 +1582,7 @@ $wgAutoloadLocalClasses = [
        'Wikimedia\\Rdbms\\ConnectionManager' => __DIR__ . '/includes/libs/rdbms/connectionmanager/ConnectionManager.php',
        'Wikimedia\\Rdbms\\DBMasterPos' => __DIR__ . '/includes/libs/rdbms/database/position/DBMasterPos.php',
        'Wikimedia\\Rdbms\\DatabaseDomain' => __DIR__ . '/includes/libs/rdbms/database/DatabaseDomain.php',
+       'Wikimedia\\Rdbms\\FakeResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/FakeResultWrapper.php',
        'Wikimedia\\Rdbms\\Field' => __DIR__ . '/includes/libs/rdbms/field/Field.php',
        'Wikimedia\\Rdbms\\IBlob' => __DIR__ . '/includes/libs/rdbms/encasing/IBlob.php',
        'Wikimedia\\Rdbms\\ILBFactory' => __DIR__ . '/includes/libs/rdbms/lbfactory/ILBFactory.php',
@@ -1601,10 +1601,12 @@ $wgAutoloadLocalClasses = [
        'Wikimedia\\Rdbms\\LoadMonitorNull' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitorNull.php',
        'Wikimedia\\Rdbms\\MssqlBlob' => __DIR__ . '/includes/libs/rdbms/encasing/MssqlBlob.php',
        'Wikimedia\\Rdbms\\MssqlField' => __DIR__ . '/includes/libs/rdbms/field/MssqlField.php',
+       'Wikimedia\\Rdbms\\MssqlResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/MssqlResultWrapper.php',
        'Wikimedia\\Rdbms\\MySQLField' => __DIR__ . '/includes/libs/rdbms/field/MySQLField.php',
        'Wikimedia\\Rdbms\\MySQLMasterPos' => __DIR__ . '/includes/libs/rdbms/database/position/MySQLMasterPos.php',
        'Wikimedia\\Rdbms\\PostgresBlob' => __DIR__ . '/includes/libs/rdbms/encasing/PostgresBlob.php',
        'Wikimedia\\Rdbms\\PostgresField' => __DIR__ . '/includes/libs/rdbms/field/PostgresField.php',
+       'Wikimedia\\Rdbms\\ResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/ResultWrapper.php',
        'Wikimedia\\Rdbms\\SQLiteField' => __DIR__ . '/includes/libs/rdbms/field/SQLiteField.php',
        'Wikimedia\\Rdbms\\SessionConsistentConnectionManager' => __DIR__ . '/includes/libs/rdbms/connectionmanager/SessionConsistentConnectionManager.php',
        'Wikimedia\\Rdbms\\TransactionProfiler' => __DIR__ . '/includes/libs/rdbms/TransactionProfiler.php',
index 3520dc3..fe68a61 100644 (file)
@@ -25,7 +25,7 @@
                "ext-xml": "*",
                "liuggio/statsd-php-client": "1.0.18",
                "mediawiki/at-ease": "1.1.0",
-               "oojs/oojs-ui": "0.19.2",
+               "oojs/oojs-ui": "0.19.4",
                "oyejorge/less.php": "1.7.0.10",
                "php": ">=5.5.9",
                "psr/log": "1.0.2",
@@ -41,6 +41,7 @@
                "wikimedia/running-stat": "1.1.0",
                "wikimedia/scoped-callback": "1.0.0",
                "wikimedia/utfnormal": "1.1.0",
+               "wikimedia/timestamp": "1.0.0",
                "wikimedia/wait-condition-loop": "1.0.1",
                "wikimedia/wrappedstring": "2.2.0",
                "zordius/lightncandy": "0.23"
        "autoload": {
                "psr-0": {
                        "ComposerHookHandler": "includes/composer"
-               }
+               },
+               "files": [
+                       "includes/compat/Timestamp.php"
+               ]
        },
        "autoload-dev": {
                "files": [
index dedb3a6..9db4c54 100644 (file)
@@ -26,7 +26,7 @@
 
                /** second table. Try to emulate child selector */
                table.childemu th,
-               table.childemu td {
+               table.childemu td {
                        border: 1px red solid;
                        background-color:white;
                        padding:1em;
index fa1609f..2052809 100644 (file)
@@ -68,7 +68,7 @@ function wfImageAuthMain() {
                $path = "/" . $path;
        }
 
-       // Check for bug 28235: QUERY_STRING overriding the correct extension
+       // Check for T30235: QUERY_STRING overriding the correct extension
        $whitelist = [];
        $extension = FileBackend::extensionFromPath( $path, 'rawcase' );
        if ( $extension != '' ) {
index 66b9ff0..1f4041b 100644 (file)
@@ -265,7 +265,7 @@ class Block {
                }
 
                # Be aware that the != '' check is explicit, since empty values will be
-               # passed by some callers (bug 29116)
+               # passed by some callers (T31116)
                if ( $vagueTarget != '' ) {
                        list( $target, $type ) = self::parseTarget( $vagueTarget );
                        switch ( $type ) {
@@ -358,7 +358,7 @@ class Block {
                if ( $end === null ) {
                        $end = $start;
                }
-               # Per bug 14634, we want to include relevant active rangeblocks; for
+               # Per T16634, we want to include relevant active rangeblocks; for
                # rangeblocks, we want to include larger ranges which enclose the given
                # range. We know that all blocks must be smaller than $wgBlockCIDRLimit,
                # so we can improve performance by filtering on a LIKE clause
@@ -553,7 +553,7 @@ class Block {
                $affected = $dbw->affectedRows();
 
                if ( $this->isAutoblocking() ) {
-                       // update corresponding autoblock(s) (bug 48813)
+                       // update corresponding autoblock(s) (T50813)
                        $dbw->update(
                                'ipblocks',
                                $this->getAutoblockUpdateArray(),
@@ -1117,7 +1117,7 @@ class Block {
                } elseif ( $target === null && $vagueTarget == '' ) {
                        # We're not going to find anything useful here
                        # Be aware that the == '' check is explicit, since empty values will be
-                       # passed by some callers (bug 29116)
+                       # passed by some callers (T31116)
                        return null;
 
                } elseif ( in_array(
@@ -1142,7 +1142,7 @@ class Block {
         * Get all blocks that match any IP from an array of IP addresses
         *
         * @param array $ipChain List of IPs (strings), usually retrieved from the
-        *         X-Forwarded-For header of the request
+        *     X-Forwarded-For header of the request
         * @param bool $isAnon Exclude anonymous-only blocks if false
         * @param bool $fromMaster Whether to query the master or replica DB
         * @return array Array of Blocks
@@ -1223,9 +1223,9 @@ class Block {
         *
         * @param array $blocks Array of Block objects
         * @param array $ipChain List of IPs (strings). This is used to determine how "close"
-        *        a block is to the server, and if a block matches exactly, or is in a range.
-        *        The order is furthest from the server to nearest e.g., (Browser, proxy1, proxy2,
-        *        local-squid, ...)
+        *     a block is to the server, and if a block matches exactly, or is in a range.
+        *     The order is furthest from the server to nearest e.g., (Browser, proxy1, proxy2,
+        *     local-squid, ...)
         * @throws MWException
         * @return Block|null The "best" block from the list
         */
index d558dbc..ece32ea 100644 (file)
@@ -96,7 +96,7 @@ class Category {
                $this->mSubcats = $row->cat_subcats;
                $this->mFiles = $row->cat_files;
 
-               # (bug 13683) If the count is negative, then 1) it's obviously wrong
+               # (T15683) If the count is negative, then 1) it's obviously wrong
                # and should not be kept, and 2) we *probably* don't have to scan many
                # rows to obtain the correct figure, so let's risk a one-time recount.
                if ( $this->mPages < 0 || $this->mSubcats < 0 || $this->mFiles < 0 ) {
index c64f550..a3d68c6 100644 (file)
@@ -1337,7 +1337,7 @@ $wgXMLMimeTypes = [
  * to reduce disk usage, limits can only be selected from a list.
  * The user preference is saved as an array offset in the database, by default
  * the offset is set with $wgDefaultUserOptions['imagesize']. Make sure you
- * change it if you alter the array (see bug 8858).
+ * change it if you alter the array (see T10858).
  * This is the list of settings the user can choose from:
  */
 $wgImageLimits = [
@@ -1442,14 +1442,19 @@ $wgUseTinyRGBForJPGThumbnails = false;
  * Default parameters for the "<gallery>" tag
  */
 $wgGalleryOptions = [
-       'imagesPerRow' => 0, // Default number of images per-row in the gallery. 0 -> Adapt to screensize
-       'imageWidth' => 120, // Width of the cells containing images in galleries (in "px")
-       'imageHeight' => 120, // Height of the cells containing images in galleries (in "px")
-       'captionLength' => true, // Deprecated @since 1.28
-                                // Length to truncate filename to in caption when using "showfilename".
-                                // A value of 'true' will truncate the filename to one line using CSS
-                                // and will be the behaviour after deprecation.
-       'showBytes' => true, // Show the filesize in bytes in categories
+       // Default number of images per-row in the gallery. 0 -> Adapt to screensize
+       'imagesPerRow' => 0,
+       // Width of the cells containing images in galleries (in "px")
+       'imageWidth' => 120,
+       // Height of the cells containing images in galleries (in "px")
+       'imageHeight' => 120,
+       // Length to truncate filename to in caption when using "showfilename".
+       // A value of 'true' will truncate the filename to one line using CSS
+       // and will be the behaviour after deprecation.
+       // @deprecated since 1.28
+       'captionLength' => true,
+       // Show the filesize in bytes in categories
+       'showBytes' => true,
        'mode' => 'traditional',
 ];
 
@@ -3357,7 +3362,7 @@ $wgDisableOutputCompression = false;
  *
  * Currently this appears to work fine in all browsers, but it's disabled by
  * default because it normalizes id's a bit too aggressively, breaking preexisting
- * content (particularly Cite).  See bug 27733, bug 27694, bug 27474.
+ * content (particularly Cite).  See T29733, T29694, T29474.
  */
 $wgExperimentalHtmlIds = false;
 
@@ -4081,7 +4086,7 @@ $wgMaxRedirects = 1;
  * Attempting to create a redirect to any of the pages in this array
  * will make the redirect fail.
  * Userlogout is hard-coded, so it does not need to be listed here.
- * (bug 10569) Disallow Mypage and Mytalk as well.
+ * (T12569) Disallow Mypage and Mytalk as well.
  *
  * As of now, this only checks special pages. Redirects to pages in
  * other namespaces cannot be invalidated by this variable.
@@ -4565,8 +4570,8 @@ $wgAuthManagerAutoConfig = [
                ],
                // Linking during login is experimental, enable at your own risk - T134952
                // MediaWiki\Auth\ConfirmLinkSecondaryAuthenticationProvider::class => [
-               //      'class' => MediaWiki\Auth\ConfirmLinkSecondaryAuthenticationProvider::class,
-               //      'sort' => 100,
+               //   'class' => MediaWiki\Auth\ConfirmLinkSecondaryAuthenticationProvider::class,
+               //   'sort' => 100,
                // ],
                MediaWiki\Auth\EmailNotificationSecondaryAuthenticationProvider::class => [
                        'class' => MediaWiki\Auth\EmailNotificationSecondaryAuthenticationProvider::class,
@@ -4865,9 +4870,7 @@ $wgDefaultUserOptions = [
 /**
  * An array of preferences to not show for the user
  */
-$wgHiddenPrefs = [
-       'rcenhancedfilters',
-];
+$wgHiddenPrefs = [];
 
 /**
  * Characters to prevent during new account creations.
@@ -8372,7 +8375,7 @@ $wgPagePropsHaveSortkey = true;
 /**
  * Port where you have HTTPS running
  * Supports HTTPS on non-standard ports
- * @see bug 65184
+ * @see T67184
  * @since 1.24
  */
 $wgHttpsPort = 443;
@@ -8560,6 +8563,7 @@ $wgCSPFalsePositiveUrls = [
        'https://atpixel.alephd.com' => true,
        'https://rtb.metrigo.com' => true,
        'https://d5p.de17a.com' => true,
+       'https://ad.lkqd.net/vpaid/vpaid.js' => true,
 ];
 
 /**
index 35c2a2d..bd92ff0 100644 (file)
@@ -21,7 +21,6 @@
  */
 
 require_once __DIR__ . '/libs/mime/defines.php';
-require_once __DIR__ . '/libs/time/defines.php';
 require_once __DIR__ . '/libs/rdbms/defines.php';
 require_once __DIR__ . '/compat/normal/UtfNormalDefines.php';
 
index 814da6a..c22125a 100644 (file)
@@ -363,8 +363,8 @@ class EditPage {
        /** @var bool */
        public $bot = true;
 
-       /** @var null|string */
-       public $contentModel = null;
+       /** @var string */
+       public $contentModel;
 
        /** @var null|string */
        public $contentFormat = null;
@@ -993,7 +993,7 @@ class EditPage {
                        $this->recreate = false;
 
                        // When creating a new section, we can preload a section title by passing it as the
-                       // preloadtitle parameter in the URL (Bug 13100)
+                       // preloadtitle parameter in the URL (T15100)
                        if ( $this->section == 'new' && $request->getVal( 'preloadtitle' ) ) {
                                $this->sectiontitle = $request->getVal( 'preloadtitle' );
                                // Once wpSummary isn't being use for setting section titles, we should delete this.
@@ -1255,11 +1255,7 @@ class EditPage {
                }
                $revision = $this->mArticle->getRevisionFetched();
                if ( $revision === null ) {
-                       if ( !$this->contentModel ) {
-                               throw new RuntimeException( 'EditPage contentModel was false' );
-                       }
                        $handler = ContentHandler::getForModelID( $this->contentModel );
-
                        return $handler->makeEmptyContent();
                }
                $content = $revision->getContent( Revision::FOR_THIS_USER, $user );
@@ -1299,11 +1295,7 @@ class EditPage {
                $content = $rev ? $rev->getContent( Revision::RAW ) : null;
 
                if ( $content === false || $content === null ) {
-                       if ( !$this->contentModel ) {
-                               throw new RuntimeException( 'EditPage contentModel was false' );
-                       }
                        $handler = ContentHandler::getForModelID( $this->contentModel );
-
                        return $handler->makeEmptyContent();
                } elseif ( !$this->undidRev ) {
                        // Content models should always be the same since we error
@@ -1911,7 +1903,7 @@ class EditPage {
 
                        // Don't save a new page if it's blank or if it's a MediaWiki:
                        // message with content equivalent to default (allow empty pages
-                       // in this case to disable messages, see bug 50124)
+                       // in this case to disable messages, see T52124)
                        $defaultMessageText = $this->mTitle->getDefaultMessageText();
                        if ( $this->mTitle->getNamespace() === NS_MEDIAWIKI && $defaultMessageText !== false ) {
                                $defaultText = $defaultMessageText;
@@ -2618,7 +2610,7 @@ class EditPage {
                        return;
                }
 
-               $this->showHeader();
+               $this->showHeader();
 
                $wgOut->addHTML( $this->editFormPageTop );
 
@@ -2731,7 +2723,7 @@ class EditPage {
                if ( $this->hasPresetSummary ) {
                        // If a summary has been preset using &summary= we don't want to prompt for
                        // a different summary. Only prompt for a summary if the summary is blanked.
-                       // (Bug 17416)
+                       // (T19416)
                        $this->autoSumm = md5( '' );
                }
 
@@ -3565,7 +3557,7 @@ HTML
                }
        }
 
-       private function incrementConflictStats() {
+       protected function incrementConflictStats() {
                $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
                $stats->increment( 'edit.failures.conflict' );
                // Only include 'standard' namespaces to avoid creating unknown numbers of statsd metrics
index e143a4c..3268291 100644 (file)
@@ -189,7 +189,7 @@ class FeedUtils {
 
                        if ( $html === null ) {
 
-                               // Omit large new page diffs, bug 29110
+                               // Omit large new page diffs, T31110
                                // Also use diff link for non-textual content
                                $diffText = self::getDiffLink( $title, $newid );
                        } else {
index af5d5fa..3747c23 100644 (file)
@@ -222,18 +222,18 @@ function wfAppendToArrayIfNotDefault( $key, $value, $default, &$changed ) {
 /**
  * Merge arrays in the style of getUserPermissionsErrors, with duplicate removal
  * e.g.
- *     wfMergeErrorArrays(
- *             [ [ 'x' ] ],
- *             [ [ 'x', '2' ] ],
- *             [ [ 'x' ] ],
- *             [ [ 'y' ] ]
- *     );
+ *     wfMergeErrorArrays(
+ *       [ [ 'x' ] ],
+ *       [ [ 'x', '2' ] ],
+ *       [ [ 'x' ] ],
+ *       [ [ 'y' ] ]
+ *     );
  * returns:
- *             [
- *             [ 'x', '2' ],
- *             [ 'x' ],
- *             [ 'y' ]
- *     ]
+ *     [
+ *       [ 'x', '2' ],
+ *       [ 'x' ],
+ *       [ 'y' ]
+ *     ]
  *
  * @param array $array1,...
  * @return array
@@ -2573,8 +2573,8 @@ function wfInitShellLocale() {
  * @param string $script MediaWiki cli script path
  * @param array $parameters Arguments and options to the script
  * @param array $options Associative array of options:
- *             'php': The path to the php executable
- *             'wrapper': Path to a PHP wrapper to handle the maintenance script
+ *     'php': The path to the php executable
+ *     'wrapper': Path to a PHP wrapper to handle the maintenance script
  * @return string
  */
 function wfShellWikiCmd( $script, array $parameters = [], array $options = [] ) {
index 3d86201..56cf815 100644 (file)
@@ -590,7 +590,7 @@ class DiffHistoryBlob implements HistoryBlob {
 
        /**
         * Compute a binary "Adler-32" checksum as defined by LibXDiff, i.e. with
-        * the bytes backwards and initialised with 0 instead of 1. See bug 34428.
+        * the bytes backwards and initialised with 0 instead of 1. See T36428.
         *
         * @param string $s
         * @return string|bool False if the hash extension is not available
index b46ea81..8fe4dbe 100644 (file)
@@ -220,8 +220,10 @@ class Html {
         * Identical to rawElement(), but HTML-escapes $contents (like
         * Xml::element()).
         *
-        * @param string $element
-        * @param array $attribs
+        * @param string $element Name of the element, e.g., 'a'
+        * @param array $attribs Associative array of attributes, e.g., [
+        *   'href' => 'https://www.mediawiki.org/' ]. See expandAttributes() for
+        *   further documentation.
         * @param string $contents
         *
         * @return string
@@ -239,8 +241,10 @@ class Html {
         * Identical to rawElement(), but has no third parameter and omits the end
         * tag (and the self-closing '/' in XML mode for empty elements).
         *
-        * @param string $element
-        * @param array $attribs
+        * @param string $element Name of the element, e.g., 'a'
+        * @param array $attribs Associative array of attributes, e.g., [
+        *   'href' => 'https://www.mediawiki.org/' ]. See expandAttributes() for
+        *   further documentation.
         *
         * @return string
         */
@@ -459,7 +463,7 @@ class Html {
         *
         * @param array $attribs Associative array of attributes, e.g., [
         *   'href' => 'https://www.mediawiki.org/' ].  Values will be HTML-escaped.
-        *   A value of false means to omit the attribute.  For boolean attributes,
+        *   A value of false or null means to omit the attribute.  For boolean attributes,
         *   you can omit the key, e.g., [ 'checked' ] instead of
         *   [ 'checked' => 'checked' ] or such.
         *
@@ -759,7 +763,7 @@ class Html {
                $attribs['name'] = $name;
 
                if ( substr( $value, 0, 1 ) == "\n" ) {
-                       // Workaround for bug 12130: browsers eat the initial newline
+                       // Workaround for T14130: browsers eat the initial newline
                        // assuming that it's just for show, but they do keep the later
                        // newlines, which we may want to preserve during editing.
                        // Prepending a single newline
index 05e3abb..0c8d1c6 100644 (file)
@@ -590,7 +590,7 @@ class Linker {
 
                # ThumbnailImage::toHtml() already adds page= onto the end of DjVu URLs
                # So we don't need to pass it here in $query. However, the URL for the
-               # zoom icon still needs it, so we make a unique query for it. See bug 14771
+               # zoom icon still needs it, so we make a unique query for it. See T16771
                $url = $title->getLocalURL( $query );
                if ( $page ) {
                        $url = wfAppendQuery( $url, [ 'page' => $page ] );
@@ -892,7 +892,7 @@ class Linker {
                        if ( $altUserName === false ) {
                                $altUserName = IP::prettifyIP( $userName );
                        }
-                       $classes .= ' mw-anonuserlink'; // Separate link class for anons (bug 43179)
+                       $classes .= ' mw-anonuserlink'; // Separate link class for anons (T45179)
                } else {
                        $page = Title::makeTitle( NS_USER, $userName );
                }
@@ -1096,7 +1096,7 @@ class Linker {
        ) {
                # Sanitize text a bit:
                $comment = str_replace( "\n", " ", $comment );
-               # Allow HTML entities (for bug 13815)
+               # Allow HTML entities (for T15815)
                $comment = Sanitizer::escapeHtmlAllowEntities( $comment );
 
                # Render autocomments and make links:
@@ -1165,7 +1165,7 @@ class Linker {
                                                $section = str_replace( '[[', '', $section );
                                                $section = str_replace( ']]', '', $section );
 
-                                               $section = Sanitizer::normalizeSectionNameWhitespace( $section ); # bug 22784
+                                               $section = Sanitizer::normalizeSectionNameWhitespace( $section ); # T24784
                                                if ( $local ) {
                                                        $sectionTitle = Title::newFromText( '#' . $section );
                                                } else {
@@ -1374,7 +1374,7 @@ class Linker {
                        } else {
                                $suffix = '';
                        }
-                       # bug 7425
+                       # T9425
                        $target = trim( $target );
                        # Look at the first character
                        if ( $target != '' && $target[0] === '/' ) {
@@ -1797,7 +1797,7 @@ class Linker {
 
                if ( $context->getRequest()->getBool( 'bot' ) ) {
                        $query['bot'] = '1';
-                       $query['hidediff'] = '1'; // bug 15999
+                       $query['hidediff'] = '1'; // T17999
                }
 
                $disableRollbackEditCount = false;
index c1e5cc4..7f3649e 100644 (file)
@@ -21,6 +21,7 @@
  * @since 1.20
  * @author Tyler Romeo, 2012
  */
+use Wikimedia\Timestamp\ConvertibleTimestamp;
 
 /**
  * Library for creating and parsing MW-style timestamps. Based on the JS
index 09317d7..ee95918 100644 (file)
@@ -46,8 +46,8 @@
  * $magicWords = [];
  *
  * $magicWords['en'] = [
- *     'magicwordkey' => [ 0, 'case_insensitive_magic_word' ],
- *     'magicwordkey2' => [ 1, 'CASE_sensitive_magic_word2' ],
+ *   'magicwordkey' => [ 0, 'case_insensitive_magic_word' ],
+ *   'magicwordkey2' => [ 1, 'CASE_sensitive_magic_word2' ],
  * ];
  * @endcode
  *
@@ -502,7 +502,7 @@ class MagicWord {
                        # multiple matched parts (variable match); some will be empty because of
                        # synonyms. The variable will be the second non-empty one so remove any
                        # blank elements and re-sort the indices.
-                       # See also bug 6526
+                       # See also T8526
 
                        $matches = array_values( array_filter( $matches ) );
 
index cfe4965..521c02c 100644 (file)
@@ -73,7 +73,7 @@ class MediaWiki {
                if ( $request->getCheck( 'search' ) ) {
                        // Compatibility with old search URLs which didn't use Special:Search
                        // Just check for presence here, so blank requests still
-                       // show the search page when using ugly URLs (bug 8054).
+                       // show the search page when using ugly URLs (T10054).
                        $ret = SpecialPage::getTitleFor( 'Search' );
                } elseif ( $curid ) {
                        // URLs like this are generated by RC, because rc_title isn't always accurate
@@ -183,7 +183,7 @@ class MediaWiki {
                $unused = null; // To pass it by reference
                Hooks::run( 'BeforeInitialize', [ &$title, &$unused, &$output, &$user, $request, $this ] );
 
-               // Invalid titles. Bug 21776: The interwikis must redirect even if the page name is empty.
+               // Invalid titles. T23776: The interwikis must redirect even if the page name is empty.
                if ( is_null( $title ) || ( $title->getDBkey() == '' && !$title->isExternal() )
                        || $title->isSpecial( 'Badtitle' )
                ) {
@@ -203,7 +203,7 @@ class MediaWiki {
                        ? [] // relies on HMAC key signature alone
                        : $title->getUserPermissionsErrors( 'read', $user );
                if ( count( $permErrors ) ) {
-                       // Bug 32276: allowing the skin to generate output with $wgTitle or
+                       // T34276: allowing the skin to generate output with $wgTitle or
                        // $this->context->title set to the input title would allow anonymous users to
                        // determine whether a page exists, potentially leaking private data. In fact, the
                        // curid and oldid request  parameters would allow page titles to be enumerated even
@@ -520,7 +520,7 @@ class MediaWiki {
                        try {
                                $this->main();
                        } catch ( ErrorPageError $e ) {
-                               // Bug 62091: while exceptions are convenient to bubble up GUI errors,
+                               // T64091: while exceptions are convenient to bubble up GUI errors,
                                // they are not internal application faults. As with normal requests, this
                                // should commit, print the output, do deferred updates, jobs, and profiling.
                                $this->doPreOutputCommit();
index e57f880..8cf3af1 100644 (file)
@@ -24,6 +24,7 @@
  *
  * @file
  */
+use Wikimedia\Timestamp\TimestampException;
 
 /**
  * Handles the backend logic of merging the histories of two
index ae12ba5..9a83d35 100644 (file)
@@ -501,7 +501,7 @@ class MovePage {
                $defaultContentModelChanging = ( $oldDefault !== $newDefault
                        && $oldDefault === $contentModel );
 
-               // bug 57084: log_page should be the ID of the *moved* page
+               // T59084: log_page should be the ID of the *moved* page
                $oldid = $this->oldTitle->getArticleID();
                $logTitle = clone $this->oldTitle;
 
@@ -550,13 +550,13 @@ class MovePage {
                );
 
                if ( !$redirectContent ) {
-                       // Clean up the old title *before* reset article id - bug 45348
+                       // Clean up the old title *before* reset article id - T47348
                        WikiPage::onArticleDelete( $this->oldTitle );
                }
 
                $this->oldTitle->resetArticleID( 0 ); // 0 == non existing
                $nt->resetArticleID( $oldid );
-               $newpage->loadPageData( WikiPage::READ_LOCKING ); // bug 46397
+               $newpage->loadPageData( WikiPage::READ_LOCKING ); // T48397
 
                $newpage->updateRevisionOn( $dbw, $nullRevision );
 
@@ -581,7 +581,7 @@ class MovePage {
                # Recreate the redirect, this time in the other direction.
                if ( $redirectContent ) {
                        $redirectArticle = WikiPage::factory( $this->oldTitle );
-                       $redirectArticle->loadFromRow( false, WikiPage::READ_LOCKING ); // bug 46397
+                       $redirectArticle->loadFromRow( false, WikiPage::READ_LOCKING ); // T48397
                        $newid = $redirectArticle->insertOn( $dbw );
                        if ( $newid ) { // sanity
                                $this->oldTitle->resetArticleID( $newid );
index b0a6b7b..50950ef 100644 (file)
@@ -20,7 +20,7 @@
  * @file
  */
 
-# bug 30219 : can not use pathinfo() on URLs since slashes do not match
+# T32219 : can not use pathinfo() on URLs since slashes do not match
 $matches = [];
 $ext = 'php';
 $path = '/';
index eb2f7e7..9ecfa23 100644 (file)
@@ -781,7 +781,7 @@ class OutputPage extends ContextSource {
                        'epoch' => $config->get( 'CacheEpoch' )
                ];
                if ( $config->get( 'UseSquid' ) ) {
-                       // bug 44570: the core page itself may not change, but resources might
+                       // T46570: the core page itself may not change, but resources might
                        $modifiedTimes['sepoch'] = wfTimestamp( TS_MW, time() - $config->get( 'SquidMaxage' ) );
                }
                Hooks::run( 'OutputPageCheckLastModified', [ &$modifiedTimes, $this ] );
@@ -1466,7 +1466,7 @@ class OutputPage extends ContextSource {
                        ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL
                );
 
-               // Site-wide styles are controlled by a config setting, see bug 71621
+               // Site-wide styles are controlled by a config setting, see T73621
                // for background on why. User styles are never allowed.
                if ( $this->getConfig()->get( 'AllowSiteCSSOnRestrictedPages' ) ) {
                        $styleOrigin = ResourceLoaderModule::ORIGIN_USER_SITEWIDE;
@@ -2502,7 +2502,7 @@ class OutputPage extends ContextSource {
                ) {
                        $displayReturnto = null;
 
-                       # Due to bug 32276, if a user does not have read permissions,
+                       # Due to T34276, if a user does not have read permissions,
                        # $this->getTitle() will just give Special:Badtitle, which is
                        # not especially useful as a returnto parameter. Use the title
                        # from the request instead, if there was one.
@@ -3084,7 +3084,7 @@ class OutputPage extends ContextSource {
 
                $curRevisionId = 0;
                $articleId = 0;
-               $canonicalSpecialPageName = false; # bug 21115
+               $canonicalSpecialPageName = false; # T23115
 
                $title = $this->getTitle();
                $ns = $title->getNamespace();
@@ -3094,7 +3094,7 @@ class OutputPage extends ContextSource {
 
                $sk = $this->getSkin();
                // Get the relevant title so that AJAX features can use the correct page name
-               // when making API requests from certain special pages (bug 34972).
+               // when making API requests from certain special pages (T36972).
                $relevantTitle = $sk->getRelevantTitle();
                $relevantUser = $sk->getRelevantUser();
 
@@ -3855,7 +3855,7 @@ class OutputPage extends ContextSource {
         *    $wgOut->addWikiText( "<div class='error'>\n"
         *        . wfMessage( 'some-error' )->plain() . "\n</div>" );
         *
-        * The newline after the opening div is needed in some wikitext. See bug 19226.
+        * The newline after the opening div is needed in some wikitext. See T21226.
         *
         * @param string $wrap
         */
index e6e96c7..c56931e 100644 (file)
@@ -75,16 +75,17 @@ class PHPVersionCheck {
         * @return $this
         */
        function checkRequiredPHPVersion() {
-               if ( !function_exists( 'version_compare' )
-                    || version_compare( $this->getPHPImplVersion(), $this->minimumVersionPHP ) < 0
+               if (
+                       !function_exists( 'version_compare' )
+                       || version_compare( $this->getPHPImplVersion(), $this->minimumVersionPHP ) < 0
                ) {
                        $shortText = "MediaWiki $this->mwVersion requires at least PHP version"
-                                    . " $this->minimumVersionPHP, you are using PHP {$this->getPHPImplVersion()}.";
+                               . " $this->minimumVersionPHP, you are using PHP {$this->getPHPImplVersion()}.";
 
                        $longText = "Error: You might be using on older PHP version. \n"
-                                   . "MediaWiki $this->mwVersion needs PHP $this->minimumVersionPHP or higher.\n\n"
-                                   . "Check if you have a newer php executable with a different name, "
-                                   . "such as php5.\n\n";
+                               . "MediaWiki $this->mwVersion needs PHP $this->minimumVersionPHP or higher.\n\n"
+                               . "Check if you have a newer php executable with a different name, "
+                               . "such as php5.\n\n";
 
                        $longHtml = <<<HTML
                        Please consider <a href="http://www.php.net/downloads.php">upgrading your copy of PHP</a>.
@@ -112,10 +113,10 @@ HTML;
                        $shortText = "Installing some external dependencies (e.g. via composer) is required.";
 
                        $longText = "Error: You are missing some external dependencies. \n"
-                                   . "MediaWiki now also has some external dependencies that need to be installed\n"
-                                   . "via composer or from a separate git repo. Please see\n"
-                                   . "https://www.mediawiki.org/wiki/Download_from_Git#Fetch_external_libraries\n"
-                                   . "for help on installing the required components.";
+                               . "MediaWiki now also has some external dependencies that need to be installed\n"
+                               . "via composer or from a separate git repo. Please see\n"
+                               . "https://www.mediawiki.org/wiki/Download_from_Git#Fetch_external_libraries\n"
+                               . "for help on installing the required components.";
 
                        $longHtml = <<<HTML
                MediaWiki now also has some external dependencies that need to be installed via
@@ -150,12 +151,12 @@ HTML;
                        foreach ( $missingExtensions as $ext ) {
                                $missingExtText .= " * $ext <$baseUrl/$ext>\n";
                                $missingExtHtml .= "<li><b>$ext</b> "
-                                                  . "(<a href=\"$baseUrl/$ext\">more information</a>)</li>";
+                                       . "(<a href=\"$baseUrl/$ext\">more information</a>)</li>";
                        }
 
                        $cliText = "Error: Missing one or more required components of PHP.\n"
-                                  . "You are missing a required extension to PHP that MediaWiki needs.\n"
-                                  . "Please install:\n" . $missingExtText;
+                               . "You are missing a required extension to PHP that MediaWiki needs.\n"
+                               . "Please install:\n" . $missingExtText;
 
                        $longHtml = <<<HTML
                You are missing a required extension to PHP that MediaWiki
@@ -198,7 +199,7 @@ HTML;
                }
                $encLogo =
                        htmlspecialchars( str_replace( '//', '/', $dirname . '/' ) .
-                                         'resources/assets/mediawiki.png' );
+                               'resources/assets/mediawiki.png' );
                $shortHtml = htmlspecialchars( $shortText );
 
                header( 'Content-type: text/html; charset=UTF-8' );
index 6d15c1e..b428e87 100644 (file)
@@ -120,7 +120,7 @@ class Preferences {
                        }
                }
 
-               # # Make sure that form fields have their parent set. See bug 41337.
+               # # Make sure that form fields have their parent set. See T43337.
                $dummyForm = new HTMLForm( [], $context );
 
                $disable = !$user->isAllowed( 'editmyoptions' );
@@ -1201,8 +1201,7 @@ class Preferences {
 
                if ( $dateopts ) {
                        if ( !in_array( 'default', $dateopts ) ) {
-                               $dateopts[] = 'default'; // Make sure default is always valid
-                                                                               // Bug 19237
+                               $dateopts[] = 'default'; // Make sure default is always valid T21237
                        }
 
                        // FIXME KLUGE: site default might not be valid for user language
index 48b1d72..62ee5c6 100644 (file)
@@ -231,7 +231,7 @@ abstract class PrefixSearch {
                        }
                }
 
-               # normalize searchKey, so aliases with spaces can be found - bug 25675
+               # normalize searchKey, so aliases with spaces can be found - T27675
                $searchKey = str_replace( ' ', '_', $searchKey );
                $searchKey = $wgContLang->caseFold( $searchKey );
 
@@ -243,7 +243,7 @@ abstract class PrefixSearch {
                }
 
                foreach ( $wgContLang->getSpecialPageAliases() as $page => $aliases ) {
-                       if ( !in_array( $page, SpecialPageFactory::getNames() ) ) {# bug 20885
+                       if ( !in_array( $page, SpecialPageFactory::getNames() ) ) {# T22885
                                continue;
                        }
 
@@ -256,7 +256,7 @@ abstract class PrefixSearch {
                $matches = [];
                foreach ( $keys as $pageKey => $page ) {
                        if ( $searchKey === '' || strpos( $pageKey, $searchKey ) === 0 ) {
-                               // bug 27671: Don't use SpecialPage::getTitleFor() here because it
+                               // T29671: Don't use SpecialPage::getTitleFor() here because it
                                // localizes its input leading to searches for e.g. Special:All
                                // returning Spezial:MediaWiki-Systemnachrichten and returning
                                // Spezial:Alle_Seiten twice when $wgLanguageCode == 'de'
index d9e42ff..4b9435a 100644 (file)
@@ -21,6 +21,8 @@
  */
 use MediaWiki\Linker\LinkTarget;
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\FakeResultWrapper;
 
 /**
  * @todo document
@@ -216,7 +218,7 @@ class Revision implements IDBAccessObject {
                        // Pre-1.5 ar_text row
                        $attribs['text'] = self::getRevisionText( $row, 'ar_' );
                        if ( $attribs['text'] === false ) {
-                               throw new MWException( 'Unable to load text from archive row (possibly bug 22624)' );
+                               throw new MWException( 'Unable to load text from archive row (possibly T24624)' );
                        }
                }
                return new self( $attribs );
@@ -1781,6 +1783,7 @@ class Revision implements IDBAccessObject {
         *
         * @param Title $title
         * @param int $id
+        * @param int $flags
         * @return string|bool False if not found
         */
        static function getTimestampFromId( $title, $id, $flags = 0 ) {
index 53cf699..d909a65 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\ResultWrapper;
 
 /**
  * List for revision table items for a single page
index 42b166d..5f6abee 100644 (file)
@@ -344,12 +344,12 @@ class Sanitizer {
                        $space = '[\x09\x0a\x0c\x0d\x20]';
                        self::$attribsRegex =
                                "/(?:^|$space)({$attribFirst}{$attrib}*)
-                                 ($space*=$space*
+                                       ($space*=$space*
                                        (?:
-                                        # The attribute value: quoted or alone
-                                         \"([^\"]*)(?:\"|\$)
-                                        | '([^']*)(?:'|\$)
-                                         (((?!$space|>).)*)
+                                               # The attribute value: quoted or alone
+                                               \"([^\"]*)(?:\"|\$)
+                                               | '([^']*)(?:'|\$)
+                                               | (((?!$space|>).)*)
                                        )
                                )?(?=$space|\$)/sx";
                }
@@ -545,7 +545,7 @@ class Sanitizer {
                                                        $badtag = true;
                                                } elseif ( in_array( $t, $tagstack ) && !isset( $htmlnest[$t] ) ) {
                                                        $badtag = true;
-                                               #  Is it a self closed htmlpair ? (bug 5487)
+                                               #  Is it a self closed htmlpair ? (T7487)
                                                } elseif ( $brace == '/>' && isset( $htmlpairs[$t] ) ) {
                                                        // Eventually we'll just remove the self-closing
                                                        // slash, in order to be consistent with HTML5
@@ -922,7 +922,7 @@ class Sanitizer {
 
                // Normalize Halfwidth and Fullwidth Unicode block that IE6 might treat as ascii
                $value = preg_replace_callback(
-                       '/[!-[]-z]/u', // U+FF01 to U+FF5A, excluding U+FF3C (bug 58088)
+                       '/[!-[]-z]/u', // U+FF01 to U+FF5A, excluding U+FF3C (T60088)
                        function ( $matches ) {
                                $cp = UtfNormal\Utils::utf8ToCodepoint( $matches[0] );
                                if ( $cp === false ) {
@@ -1508,7 +1508,7 @@ class Sanitizer {
 
        /**
         * Decode any character references, numeric or named entities,
-        * in the next and normalize the resulting string. (bug 14952)
+        * in the next and normalize the resulting string. (T16952)
         *
         * This is useful for page titles, not for text to be displayed,
         * MediaWiki allows HTML entities to escape normalization as a feature.
@@ -1926,7 +1926,7 @@ class Sanitizer {
         *   3.5.
         *
         * This function is an implementation of the specification as requested in
-        * bug 22449.
+        * T24449.
         *
         * Client-side forms will use the same standard validation rules via JS or
         * HTML 5 validation; additional restrictions can be enforced server-side
@@ -1949,7 +1949,7 @@ class Sanitizer {
 
                // Please note strings below are enclosed in brackets [], this make the
                // hyphen "-" a range indicator. Hence it is double backslashed below.
-               // See bug 26948
+               // See T28948
                $rfc5322_atext = "a-z0-9!#$%&'*+\\-\/=?^_`{|}~";
                $rfc1034_ldh_str = "a-z0-9\\-";
 
index 72ed1fd..b61de73 100644 (file)
@@ -329,7 +329,7 @@ if ( $wgEnableEmail ) {
        $wgUseEnotif = $wgEnotifUserTalk || $wgEnotifWatchlist;
 } else {
        // Disable all other email settings automatically if $wgEnableEmail
-       // is set to false. - bug 63678
+       // is set to false. - T65678
        $wgAllowHTMLEmail = false;
        $wgEmailAuthentication = false; // do not require auth if you're not sending email anyway
        $wgEnableUserEmail = false;
index 3ce775b..3ed6b8b 100644 (file)
@@ -134,7 +134,7 @@ class Title implements LinkTarget {
 
        /**
         * @var int Namespace index when there is no namespace. Don't change the
-        *   following default, NS_MAIN is hardcoded in several places. See bug 696.
+        *   following default, NS_MAIN is hardcoded in several places. See T2696.
         *   Zero except in {{transclusion}} tags.
         */
        public $mDefaultNamespace = NS_MAIN;
@@ -307,7 +307,7 @@ class Title implements LinkTarget {
                        }
                }
 
-               // Convert things like &eacute; &#257; or &#x3017; into normalized (bug 14952) text
+               // Convert things like &eacute; &#257; or &#x3017; into normalized (T16952) text
                $filteredText = Sanitizer::decodeCharReferencesAndNormalize( $text );
 
                $t = new Title();
@@ -2549,6 +2549,29 @@ class Title implements LinkTarget {
         *   protection, or false if there's none.
         */
        public function getTitleProtection() {
+               $protection = $this->getTitleProtectionInternal();
+               if ( $protection ) {
+                       if ( $protection['permission'] == 'sysop' ) {
+                               $protection['permission'] = 'editprotected'; // B/C
+                       }
+                       if ( $protection['permission'] == 'autoconfirmed' ) {
+                               $protection['permission'] = 'editsemiprotected'; // B/C
+                       }
+               }
+               return $protection;
+       }
+
+       /**
+        * Fetch title protection settings
+        *
+        * To work correctly, $this->loadRestrictions() needs to have access to the
+        * actual protections in the database without munging 'sysop' =>
+        * 'editprotected' and 'autoconfirmed' => 'editsemiprotected'. Other
+        * callers probably want $this->getTitleProtection() instead.
+        *
+        * @return array|bool
+        */
+       protected function getTitleProtectionInternal() {
                // Can't protect pages in special namespaces
                if ( $this->getNamespace() < 0 ) {
                        return false;
@@ -2576,12 +2599,6 @@ class Title implements LinkTarget {
                        // fetchRow returns false if there are no rows.
                        $row = $dbr->fetchRow( $res );
                        if ( $row ) {
-                               if ( $row['permission'] == 'sysop' ) {
-                                       $row['permission'] = 'editprotected'; // B/C
-                               }
-                               if ( $row['permission'] == 'autoconfirmed' ) {
-                                       $row['permission'] = 'editsemiprotected'; // B/C
-                               }
                                $row['expiry'] = $dbr->decodeExpiry( $row['expiry'] );
                        }
                        $this->mTitleProtection = $row;
@@ -2979,7 +2996,7 @@ class Title implements LinkTarget {
 
                        $this->loadRestrictionsFromRows( $rows, $oldFashionedRestrictions );
                } else {
-                       $title_protection = $this->getTitleProtection();
+                       $title_protection = $this->getTitleProtectionInternal();
 
                        if ( $title_protection ) {
                                $now = wfTimestampNow();
@@ -3741,14 +3758,14 @@ class Title implements LinkTarget {
                        }
                        $newPageName = preg_replace(
                                        '#^' . preg_quote( $this->getDBkey(), '#' ) . '#',
-                                       StringUtils::escapeRegexReplacement( $nt->getDBkey() ), # bug 21234
+                                       StringUtils::escapeRegexReplacement( $nt->getDBkey() ), # T23234
                                        $oldSubpage->getDBkey() );
                        if ( $oldSubpage->isTalkPage() ) {
                                $newNs = $nt->getTalkPage()->getNamespace();
                        } else {
                                $newNs = $nt->getSubjectPage()->getNamespace();
                        }
-                       # Bug 14385: we need makeTitleSafe because the new page names may
+                       # T16385: we need makeTitleSafe because the new page names may
                        # be longer than 255 characters.
                        $newSubpage = Title::makeTitleSafe( $newNs, $newPageName );
 
@@ -3865,7 +3882,7 @@ class Title implements LinkTarget {
         * categories' names.
         *
         * @return array Array of parents in the form:
-        *        $parent => $currentarticle
+        *     $parent => $currentarticle
         */
        public function getParentCategories() {
                global $wgContLang;
index 5a28b85..bf2344b 100644 (file)
@@ -24,6 +24,8 @@
  * @file
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * The TitleArray class only exists to provide the newFromResult method at pre-
  * sent.
index 668ea54..189fb40 100644 (file)
@@ -24,6 +24,8 @@
  * @file
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 class TitleArrayFromResult extends TitleArray implements Countable {
        /** @var ResultWrapper */
        public $res;
index 2b8147a..bc57049 100644 (file)
@@ -505,7 +505,7 @@ class WatchedItemQueryService {
                        $conds[] = 'rc_user_text != ' . $db->addQuotes( $options['notByUser'] );
                }
 
-               // Avoid brute force searches (bug 17342)
+               // Avoid brute force searches (T19342)
                $bitmask = 0;
                if ( !$user->isAllowed( 'deletedhistory' ) ) {
                        $bitmask = Revision::DELETED_USER;
index 8fcf131..6301576 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * Extension mechanism for WatchedItemQueryService
  *
index 78d7444..3d5e372 100644 (file)
@@ -216,7 +216,7 @@ class WebRequest {
 
                        $host = $parts[0];
                        if ( $wgAssumeProxiesUseDefaultProtocolPorts && isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) ) {
-                               // Bug 70021: Assume that upstream proxy is running on the default
+                               // T72021: Assume that upstream proxy is running on the default
                                // port based on the protocol. We have no reliable way to determine
                                // the actual port in use upstream.
                                $port = $stdPort;
@@ -308,7 +308,7 @@ class WebRequest {
         * available variant URLs.
         */
        public function interpolateTitle() {
-               // bug 16019: title interpolation on API queries is useless and sometimes harmful
+               // T18019: title interpolation on API queries is useless and sometimes harmful
                if ( defined( 'MW_API' ) ) {
                        return;
                }
@@ -1229,7 +1229,7 @@ HTML;
                                if (
                                        IP::isPublic( $ipchain[$i + 1] ) ||
                                        $wgUsePrivateIPs ||
-                                       $proxyLookup->isConfiguredProxy( $curIP ) // bug 48919; treat IP as sane
+                                       $proxyLookup->isConfiguredProxy( $curIP ) // T50919; treat IP as sane
                                ) {
                                        // Follow the next IP according to the proxy
                                        $nextIP = IP::canonicalize( $ipchain[$i + 1] );
index 861e532..15804c7 100644 (file)
@@ -30,7 +30,7 @@ if ( ini_get( 'mbstring.func_overload' ) ) {
        die( 'MediaWiki does not support installations where mbstring.func_overload is non-zero.' );
 }
 
-# bug 15461: Make IE8 turn off content sniffing. Everybody else should ignore this
+# T17461: Make IE8 turn off content sniffing. Everybody else should ignore this
 # We're adding it here so that it's *always* set, even for alternate entry
 # points and when $wgOut gets disabled or overridden.
 header( 'X-Content-Type-Options: nosniff' );
index 8f18046..d24a27c 100644 (file)
@@ -59,8 +59,8 @@ class Xml {
         * Given an array of ('attributename' => 'value'), it generates the code
         * to set the XML attributes : attributename="value".
         * The values are passed to Sanitizer::encodeAttribute.
-        * Return null if no attributes given.
-        * @param array $attribs Array of attributes for an XML element
+        * Returns null or empty string if no attributes given.
+        * @param array|null $attribs Array of attributes for an XML element
         * @throws MWException
         * @return null|string
         */
index b381edc..d1be7d4 100644 (file)
@@ -24,6 +24,8 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\FakeResultWrapper;
 
 /**
  * This class handles printing the history page for an article. In order to
index e249810..c03faf0 100644 (file)
@@ -700,7 +700,7 @@ abstract class ApiBase extends ContextSource {
         * @return array
         */
        public function extractRequestParams( $parseLimit = true ) {
-               // Cache parameters, for performance and to avoid bug 24564.
+               // Cache parameters, for performance and to avoid T26564.
                if ( !isset( $this->mParamCache[$parseLimit] ) ) {
                        $params = $this->getFinalParams();
                        $results = [];
@@ -1326,7 +1326,7 @@ abstract class ApiBase extends ContextSource {
                }
 
                if ( !$allowMultiple && count( $valuesList ) != 1 ) {
-                       // Bug 33482 - Allow entries with | in them for non-multiple values
+                       // T35482 - Allow entries with | in them for non-multiple values
                        if ( in_array( $value, $allowedValues, true ) ) {
                                return $value;
                        }
index 58e3d1c..8577ad2 100644 (file)
@@ -46,7 +46,7 @@ class ApiBlock extends ApiBase {
 
                $this->requireOnlyOneParameter( $params, 'user', 'userid' );
 
-               # bug 15810: blocked admins should have limited access here
+               # T17810: blocked admins should have limited access here
                if ( $user->isBlocked() ) {
                        $status = SpecialBlock::checkUnblockSelf( $params['user'], $user );
                        if ( $status !== true ) {
@@ -69,7 +69,7 @@ class ApiBlock extends ApiBase {
                } else {
                        $target = User::newFromName( $params['user'] );
 
-                       // Bug 38633 - if the target is a user (not an IP address), but it
+                       // T40633 - if the target is a user (not an IP address), but it
                        // doesn't exist or is unusable, error.
                        if ( $target instanceof User &&
                                ( $target->isAnon() /* doesn't exist */ || !User::isUsableName( $target->getName() ) )
index e0e50ed..0b04c8c 100644 (file)
@@ -57,7 +57,7 @@ class ApiFeedRecentChanges extends ApiBase {
 
                $this->getMain()->setCacheMode( 'public' );
                if ( !$this->getMain()->getParameter( 'smaxage' ) ) {
-                       // bug 63249: This page gets hit a lot, cache at least 15 seconds.
+                       // T65249: This page gets hit a lot, cache at least 15 seconds.
                        $this->getMain()->setCacheMaxAge( 15 );
                }
 
index 67f54a8..83c348b 100644 (file)
@@ -186,7 +186,7 @@ abstract class ApiFormatBase extends ApiBase {
 
                $this->getMain()->getRequest()->response()->header( "Content-Type: $mime; charset=utf-8" );
 
-               // Set X-Frame-Options API results (bug 39180)
+               // Set X-Frame-Options API results (T41180)
                $apiFrameOptions = $this->getConfig()->get( 'ApiFrameOptions' );
                if ( $apiFrameOptions ) {
                        $this->getMain()->getRequest()->response()->header( "X-Frame-Options: $apiFrameOptions" );
@@ -269,7 +269,7 @@ abstract class ApiFormatBase extends ApiBase {
                                        false, FormatJson::ALL_OK
                                );
 
-                               // Bug 66776: wfMangleFlashPolicy() is needed to avoid a nasty bug in
+                               // T68776: wfMangleFlashPolicy() is needed to avoid a nasty bug in
                                // Flash, but what it does isn't friendly for the API, so we need to
                                // work around it.
                                if ( preg_match( '/\<\s*cross-domain-policy\s*\>/i', $json ) ) {
index 8ebfe48..e5dafae 100644 (file)
@@ -91,7 +91,7 @@ class ApiFormatJson extends ApiFormatBase {
                $data = $this->getResult()->getResultData( null, $transform );
                $json = FormatJson::encode( $data, $this->getIsHtml(), $opt );
 
-               // Bug 66776: wfMangleFlashPolicy() is needed to avoid a nasty bug in
+               // T68776: wfMangleFlashPolicy() is needed to avoid a nasty bug in
                // Flash, but what it does isn't friendly for the API, so we need to
                // work around it.
                if ( preg_match( '/\<\s*cross-domain-policy(?=\s|\>)/i', $json ) ) {
@@ -103,7 +103,7 @@ class ApiFormatJson extends ApiFormatBase {
                if ( isset( $params['callback'] ) ) {
                        $callback = preg_replace( "/[^][.\\'\\\"_A-Za-z0-9]/", '', $params['callback'] );
                        # Prepend a comment to try to avoid attacks against content
-                       # sniffers, such as bug 68187.
+                       # sniffers, such as T70187.
                        $this->printText( "/**/$callback($json)" );
                } else {
                        $this->printText( $json );
index a744f57..671f356 100644 (file)
@@ -60,7 +60,7 @@ class ApiFormatPhp extends ApiFormatBase {
                }
                $text = serialize( $this->getResult()->getResultData( null, $transforms ) );
 
-               // Bug 66776: wfMangleFlashPolicy() is needed to avoid a nasty bug in
+               // T68776: wfMangleFlashPolicy() is needed to avoid a nasty bug in
                // Flash, but what it does isn't friendly for the API. There's nothing
                // we can do here that isn't actively broken in some manner, so let's
                // just be broken in a useful manner.
index e017eda..d64aeb7 100644 (file)
@@ -202,7 +202,7 @@ class ApiLogin extends ApiBase {
 
                        case 'Aborted':
                                $result['reason'] = 'Authentication requires user interaction, ' .
-                                  'which is not supported by action=login.';
+                                       'which is not supported by action=login.';
                                if ( $this->getConfig()->get( 'EnableBotPasswords' ) ) {
                                        $result['reason'] .= ' To be able to login with action=login, see [[Special:BotPasswords]].';
                                        $result['reason'] .= ' To continue using main-account login, see action=clientlogin.';
index 9e00830..604fdf9 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 use MediaWiki\Logger\LoggerFactory;
+use Wikimedia\Timestamp\TimestampException;
 
 /**
  * This is the main API class, used for both external and internal processing.
@@ -574,7 +575,7 @@ class ApiMain extends ApiBase {
         * @param Exception $e
         */
        protected function handleException( Exception $e ) {
-               // Bug 63145: Rollback any open database transactions
+               // T65145: Rollback any open database transactions
                if ( !( $e instanceof ApiUsageException || $e instanceof UsageException ) ) {
                        // UsageExceptions are intentional, so don't rollback if that's the case
                        try {
@@ -1668,7 +1669,7 @@ class ApiMain extends ApiBase {
                $ret = $this->getRequest()->getVal( $name );
                if ( $ret === null ) {
                        if ( $this->getRequest()->getArray( $name ) !== null ) {
-                               // See bug 10262 for why we don't just implode( '|', ... ) the
+                               // See T12262 for why we don't just implode( '|', ... ) the
                                // array.
                                $this->addWarning( [ 'apiwarn-unsupportedarray', $name ] );
                        }
index ab7199f..566f778 100644 (file)
@@ -103,7 +103,7 @@ class ApiMove extends ApiBase {
                // a redirect to the new title. This is not safe, but what we did before was
                // even worse: we just determined whether a redirect should have been created,
                // and reported that it was created if it should have, without any checks.
-               // Also note that isRedirect() is unreliable because of bug 37209.
+               // Also note that isRedirect() is unreliable because of T39209.
                $r['redirectcreated'] = $fromTitle->exists();
 
                $r['moveoverredirect'] = $toTitleExists;
index d42e306..7d16af8 100644 (file)
@@ -24,6 +24,7 @@
  * @file
  */
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\ResultWrapper;
 
 /**
  * This class contains a list of pages that the client has requested.
@@ -64,6 +65,7 @@ class ApiPageSet extends ApiBase {
        private $mMissingPageIDs = [];
        private $mRedirectTitles = [];
        private $mSpecialTitles = [];
+       private $mAllSpecials = []; // separate from mAllPages to avoid breaking getAllTitlesByNamespace()
        private $mNormalizedTitles = [];
        private $mInterwikiTitles = [];
        /** @var Title[] */
@@ -1061,7 +1063,7 @@ class ApiPageSet extends ApiBase {
         * @return LinkBatch
         */
        private function getRedirectTargets() {
-               $lb = new LinkBatch();
+               $titlesToResolve = [];
                $db = $this->getDB();
 
                $res = $db->select(
@@ -1088,8 +1090,8 @@ class ApiPageSet extends ApiBase {
                        unset( $this->mPendingRedirectIDs[$rdfrom] );
                        if ( $to->isExternal() ) {
                                $this->mInterwikiTitles[$to->getPrefixedText()] = $to->getInterwiki();
-                       } elseif ( !isset( $this->mAllPages[$row->rd_namespace][$row->rd_title] ) ) {
-                               $lb->add( $row->rd_namespace, $row->rd_title );
+                       } elseif ( !isset( $this->mAllPages[$to->getNamespace()][$to->getDBkey()] ) ) {
+                               $titlesToResolve[] = $to;
                        }
                        $this->mRedirectTitles[$from] = $to;
                }
@@ -1104,7 +1106,11 @@ class ApiPageSet extends ApiBase {
                                        // What the hell. Let's just ignore this
                                        continue;
                                }
-                               $lb->addObj( $rt );
+                               if ( $rt->isExternal() ) {
+                                       $this->mInterwikiTitles[$rt->getPrefixedText()] = $rt->getInterwiki();
+                               } elseif ( !isset( $this->mAllPages[$rt->getNamespace()][$rt->getDBkey()] ) ) {
+                                       $titlesToResolve[] = $rt;
+                               }
                                $from = $title->getPrefixedText();
                                $this->mResolvedRedirectTitles[$from] = $title;
                                $this->mRedirectTitles[$from] = $rt;
@@ -1112,7 +1118,7 @@ class ApiPageSet extends ApiBase {
                        }
                }
 
-               return $lb;
+               return $this->processTitlesArray( $titlesToResolve );
        }
 
        /**
@@ -1151,12 +1157,14 @@ class ApiPageSet extends ApiBase {
                                        $titleObj = Title::newFromTextThrow( $title, $this->mDefaultNamespace );
                                } catch ( MalformedTitleException $ex ) {
                                        // Handle invalid titles gracefully
-                                       $this->mAllPages[0][$title] = $this->mFakePageId;
-                                       $this->mInvalidTitles[$this->mFakePageId] = [
-                                               'title' => $title,
-                                               'invalidreason' => $this->getErrorFormatter()->formatException( $ex, [ 'bc' => true ] ),
-                                       ];
-                                       $this->mFakePageId--;
+                                       if ( !isset( $this->mAllPages[0][$title] ) ) {
+                                               $this->mAllPages[0][$title] = $this->mFakePageId;
+                                               $this->mInvalidTitles[$this->mFakePageId] = [
+                                                       'title' => $title,
+                                                       'invalidreason' => $this->getErrorFormatter()->formatException( $ex, [ 'bc' => true ] ),
+                                               ];
+                                               $this->mFakePageId--;
+                                       }
                                        continue; // There's nothing else we can do
                                }
                        } else {
@@ -1184,8 +1192,13 @@ class ApiPageSet extends ApiBase {
                                if ( $titleObj->getNamespace() < 0 ) {
                                        // Handle Special and Media pages
                                        $titleObj = $titleObj->fixSpecialName();
-                                       $this->mSpecialTitles[$this->mFakePageId] = $titleObj;
-                                       $this->mFakePageId--;
+                                       $ns = $titleObj->getNamespace();
+                                       $dbkey = $titleObj->getDBkey();
+                                       if ( !isset( $this->mAllSpecials[$ns][$dbkey] ) ) {
+                                               $this->mAllSpecials[$ns][$dbkey] = $this->mFakePageId;
+                                               $this->mSpecialTitles[$this->mFakePageId] = $titleObj;
+                                               $this->mFakePageId--;
+                                       }
                                } else {
                                        // Regular page
                                        $linkBatch->addObj( $titleObj );
@@ -1384,7 +1397,7 @@ class ApiPageSet extends ApiBase {
         * @return array
         */
        private static function getPositiveIntegers( $array ) {
-               // bug 25734 API: possible issue with revids validation
+               // T27734 API: possible issue with revids validation
                // It seems with a load of revision rows, MySQL gets upset
                // Remove any < 0 integers, as they can't be valid
                foreach ( $array as $i => $int ) {
index b09b977..020df6d 100644 (file)
@@ -230,7 +230,7 @@ class ApiQueryAllDeletedRevisions extends ApiQueryRevisionsBase {
                }
 
                if ( !is_null( $params['user'] ) || !is_null( $params['excludeuser'] ) ) {
-                       // Paranoia: avoid brute force searches (bug 17342)
+                       // Paranoia: avoid brute force searches (T19342)
                        // (shouldn't be able to get here without 'deletedhistory', but
                        // check it again just in case)
                        if ( !$user->isAllowed( 'deletedhistory' ) ) {
index b64b2c8..7b43efc 100644 (file)
@@ -131,7 +131,7 @@ class ApiQueryAllRevisions extends ApiQueryRevisionsBase {
                }
 
                if ( $params['user'] !== null || $params['excludeuser'] !== null ) {
-                       // Paranoia: avoid brute force searches (bug 17342)
+                       // Paranoia: avoid brute force searches (T19342)
                        if ( !$this->getUser()->isAllowed( 'deletedhistory' ) ) {
                                $bitmask = Revision::DELETED_USER;
                        } elseif ( !$this->getUser()->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
index 136f60e..9e7ad67 100644 (file)
@@ -186,7 +186,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
                                ],
                        ] ] );
 
-                       // Actually count the actions using a subquery (bug 64505 and bug 64507)
+                       // Actually count the actions using a subquery (T66505 and T66507)
                        $timestamp = $db->timestamp( wfTimestamp( TS_UNIX ) - $activeUserSeconds );
                        $this->addFields( [
                                'recentactions' => '(' . $db->selectSQLText(
index 613589e..b3ac606 100644 (file)
@@ -152,7 +152,7 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
                if ( $this->params['filterredir'] == 'redirects' ) {
                        $this->addWhereFld( 'page_is_redirect', 1 );
                } elseif ( $this->params['filterredir'] == 'nonredirects' && !$this->redirect ) {
-                       // bug 22245 - Check for !redirect, as filtering nonredirects, when
+                       // T24245 - Check for !redirect, as filtering nonredirects, when
                        // getting what links to them is contradictory
                        $this->addWhereFld( 'page_is_redirect', 0 );
                }
index 2d21865..87bb6a7 100644 (file)
@@ -24,6 +24,8 @@
  * @file
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * This is a base class for all Query modules.
  * It provides some common functionality such as constructing various SQL
index d0b8214..471aed6 100644 (file)
@@ -123,7 +123,7 @@ class ApiQueryDeletedRevisions extends ApiQueryRevisionsBase {
                }
 
                if ( !is_null( $params['user'] ) || !is_null( $params['excludeuser'] ) ) {
-                       // Paranoia: avoid brute force searches (bug 17342)
+                       // Paranoia: avoid brute force searches (T19342)
                        // (shouldn't be able to get here without 'deletedhistory', but
                        // check it again just in case)
                        if ( !$user->isAllowed( 'deletedhistory' ) ) {
index 6a259cd..2959151 100644 (file)
@@ -203,7 +203,7 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                }
 
                if ( !is_null( $params['user'] ) || !is_null( $params['excludeuser'] ) ) {
-                       // Paranoia: avoid brute force searches (bug 17342)
+                       // Paranoia: avoid brute force searches (T19342)
                        // (shouldn't be able to get here without 'deletedhistory', but
                        // check it again just in case)
                        if ( !$user->isAllowed( 'deletedhistory' ) ) {
index c9dae8d..e5e45b3 100644 (file)
@@ -509,7 +509,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
                                if ( $mto && !$mto->isError() ) {
                                        $vals['thumburl'] = wfExpandUrl( $mto->getUrl(), PROTO_CURRENT );
 
-                                       // bug 23834 - If the URL's are the same, we haven't resized it, so shouldn't give the wanted
+                                       // T25834 - If the URLs are the same, we haven't resized it, so shouldn't give the wanted
                                        // thumbnail sizes for the thumbnail actual size
                                        if ( $mto->getUrl() !== $file->getUrl() ) {
                                                $vals['thumbwidth'] = intval( $mto->getWidth() );
index 4d84aad..8a13fef 100644 (file)
@@ -198,7 +198,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
                        $this->addWhere( 'log_title ' . $db->buildLike( $title->getDBkey(), $db->anyString() ) );
                }
 
-               // Paranoia: avoid brute force searches (bug 17342)
+               // Paranoia: avoid brute force searches (T19342)
                if ( $params['namespace'] !== null || !is_null( $title ) || !is_null( $user ) ) {
                        if ( !$this->getUser()->isAllowed( 'deletedhistory' ) ) {
                                $titleBits = LogPage::DELETED_ACTION;
index 2c76e97..26581a6 100644 (file)
@@ -147,7 +147,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
 
                /* Build our basic query. Namely, something along the lines of:
                 * SELECT * FROM recentchanges WHERE rc_timestamp > $start
-                *              AND rc_timestamp < $end AND rc_namespace = $namespace
+                *   AND rc_timestamp < $end AND rc_namespace = $namespace
                 */
                $this->addTables( 'recentchanges' );
                $this->addTimestampWhereRange( 'rc_timestamp', $params['dir'], $params['start'], $params['end'] );
@@ -320,7 +320,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                        $this->addWhereFld( 'ct_tag', $params['tag'] );
                }
 
-               // Paranoia: avoid brute force searches (bug 17342)
+               // Paranoia: avoid brute force searches (T19342)
                if ( !is_null( $params['user'] ) || !is_null( $params['excludeuser'] ) ) {
                        if ( !$user->isAllowed( 'deletedhistory' ) ) {
                                $bitmask = Revision::DELETED_USER;
index 48f6046..c47de9d 100644 (file)
@@ -244,7 +244,7 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
                                }
                        }
                        if ( $params['user'] !== null || $params['excludeuser'] !== null ) {
-                               // Paranoia: avoid brute force searches (bug 17342)
+                               // Paranoia: avoid brute force searches (T19342)
                                if ( !$this->getUser()->isAllowed( 'deletedhistory' ) ) {
                                        $bitmask = Revision::DELETED_USER;
                                } elseif ( !$this->getUser()->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
index 5093608..cc302dc 100644 (file)
@@ -88,6 +88,9 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                                case 'languages':
                                        $fit = $this->appendLanguages( $p );
                                        break;
+                               case 'languagevariants':
+                                       $fit = $this->appendLanguageVariants( $p );
+                                       break;
                                case 'skins':
                                        $fit = $this->appendSkins( $p );
                                        break;
@@ -713,6 +716,49 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                return $this->getResult()->addValue( 'query', $property, $data );
        }
 
+       // Export information about which page languages will trigger
+       // language conversion. (T153341)
+       public function appendLanguageVariants( $property ) {
+               $langNames = LanguageConverter::$languagesWithVariants;
+               if ( $this->getConfig()->get( 'DisableLangConversion' ) ) {
+                       // Ensure result is empty if language conversion is disabled.
+                       $langNames = [];
+               }
+               sort( $langNames );
+
+               $data = [];
+               foreach ( $langNames as $langCode ) {
+                       $lang = Language::factory( $langCode );
+                       if ( $lang->getConverter() instanceof FakeConverter ) {
+                               // Only languages which do not return instances of
+                               // FakeConverter implement language conversion.
+                               continue;
+                       }
+                       $data[$langCode] = [];
+                       ApiResult::setIndexedTagName( $data[$langCode], 'variant' );
+                       ApiResult::setArrayType( $data[$langCode], 'kvp', 'code' );
+
+                       $variants = $lang->getVariants();
+                       sort( $variants );
+                       foreach ( $variants as $v ) {
+                               $fallbacks = $lang->getConverter()->getVariantFallbacks( $v );
+                               if ( !is_array( $fallbacks ) ) {
+                                       $fallbacks = [ $fallbacks ];
+                               }
+                               $data[$langCode][$v] = [
+                                       'fallbacks' => $fallbacks,
+                               ];
+                               ApiResult::setIndexedTagName(
+                                       $data[$langCode][$v]['fallbacks'], 'variant'
+                               );
+                       }
+               }
+               ApiResult::setIndexedTagName( $data, 'lang' );
+               ApiResult::setArrayType( $data, 'kvp', 'code' );
+
+               return $this->getResult()->addValue( 'query', $property, $data );
+       }
+
        public function appendSkins( $property ) {
                $data = [];
                $allowed = Skin::getAllowedSkins();
@@ -772,7 +818,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
        }
 
        public function appendProtocols( $property ) {
-               // Make a copy of the global so we don't try to set the _element key of it - bug 45130
+               // Make a copy of the global so we don't try to set the _element key of it - T47130
                $protocols = array_values( $this->getConfig()->get( 'UrlProtocols' ) );
                ApiResult::setArrayType( $protocols, 'BCarray' );
                ApiResult::setIndexedTagName( $protocols, 'p' );
@@ -851,6 +897,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                                        'rightsinfo',
                                        'restrictions',
                                        'languages',
+                                       'languagevariants',
                                        'skins',
                                        'extensiontags',
                                        'functionhooks',
index e27cf7d..6734740 100644 (file)
@@ -364,7 +364,7 @@ class ApiResult implements ApiSerializable {
                        }
                }
                if ( is_array( $value ) ) {
-                       // Work around PHP bug 45959 by copying to a temporary
+                       // Work around https://bugs.php.net/bug.php?id=45959 by copying to a temporary
                        // (in this case, foreach gets $k === "1" but $tmp[$k] assigns as if $k === 1)
                        $tmp = [];
                        foreach ( $value as $k => $v ) {
index 3eeb7a4..bfb0324 100644 (file)
@@ -44,7 +44,7 @@ class ApiUnblock extends ApiBase {
                if ( !$user->isAllowed( 'block' ) ) {
                        $this->dieWithError( 'apierror-permissiondenied-unblock', 'permissiondenied' );
                }
-               # bug 15810: blocked admins should have limited access here
+               # T17810: blocked admins should have limited access here
                if ( $user->isBlocked() ) {
                        $status = SpecialBlock::checkUnblockSelf( $params['user'], $user );
                        if ( $status !== true ) {
index 341c68f..491a1b0 100644 (file)
        "apihelp-query+search-param-limit": "Wie viele Seiten insgesamt zurückgegeben werden sollen.",
        "apihelp-query+search-example-simple": "Nach <kbd>meaning</kbd> suchen.",
        "apihelp-query+search-example-text": "Texte nach <kbd>meaning</kbd> durchsuchen.",
+       "apihelp-query+siteinfo-paramvalue-prop-languagevariants": "Gibt eine Liste für die Sprachcodes zurück, bei denen der [[mw:LanguageConverter|Sprachkonverter]] aktiviert ist und die unterstützten Varianten für jede Sprache.",
        "apihelp-query+siteinfo-example-simple": "Websiteinformationen abrufen",
        "apihelp-query+stashimageinfo-param-sessionkey": "Alias für $1filekey, für die Rückwärtskompatibilität.",
        "apihelp-query+stashimageinfo-example-simple": "Gibt Informationen für eine gespeicherte Datei zurück.",
index f9de725..ab8a8a5 100644 (file)
        "apihelp-query+siteinfo-paramvalue-prop-rightsinfo": "Returns wiki rights (license) information if available.",
        "apihelp-query+siteinfo-paramvalue-prop-restrictions": "Returns information on available restriction (protection) types.",
        "apihelp-query+siteinfo-paramvalue-prop-languages": "Returns a list of languages MediaWiki supports (optionally localised by using <var>$1inlanguagecode</var>).",
+       "apihelp-query+siteinfo-paramvalue-prop-languagevariants": "Returns a list of language codes for which [[mw:LanguageConverter|LanguageConverter]] is enabled, and the variants supported for each.",
        "apihelp-query+siteinfo-paramvalue-prop-skins": "Returns a list of all enabled skins (optionally localised by using <var>$1inlanguagecode</var>, otherwise in the content language).",
        "apihelp-query+siteinfo-paramvalue-prop-extensiontags": "Returns a list of parser extension tags.",
        "apihelp-query+siteinfo-paramvalue-prop-functionhooks": "Returns a list of parser function hooks.",
        "apierror-invalidexpiry": "Invalid expiry time \"$1\".",
        "apierror-invalid-file-key": "Not a valid file key.",
        "apierror-invalidlang": "Invalid language code for parameter <var>$1</var>.",
-       "apierror-invalidoldimage": "The oldimage parameter has invalid format.",
+       "apierror-invalidoldimage": "The <var>oldimage</var> parameter has an invalid format.",
        "apierror-invalidparammix-cannotusewith": "The <kbd>$1</kbd> parameter cannot be used with <kbd>$2</kbd>.",
        "apierror-invalidparammix-mustusewith": "The <kbd>$1</kbd> parameter may only be used with <kbd>$2</kbd>.",
        "apierror-invalidparammix-parse-new-section": "<kbd>section=new</kbd> cannot be combined with the <var>oldid</var>, <var>pageid</var> or <var>page</var> parameters. Please use <var>title</var> and <var>text</var>.",
        "apierror-invalidparammix": "The {{PLURAL:$2|parameters}} $1 can not be used together.",
-       "apierror-invalidsection": "The section parameter must be a valid section ID or <kbd>new</kbd>.",
+       "apierror-invalidsection": "The <var>section</var> parameter must be a valid section ID or <kbd>new</kbd>.",
        "apierror-invalidsha1base36hash": "The SHA1Base36 hash provided is not valid.",
        "apierror-invalidsha1hash": "The SHA1 hash provided is not valid.",
        "apierror-invalidtitle": "Bad title \"$1\".",
index bf10140..a2fbb48 100644 (file)
        "apihelp-xmlfm-description": "Producir los datos de salida en formato XML (con resaltado sintáctico en HTML).",
        "api-format-title": "Resultado de la API de MediaWiki",
        "api-format-prettyprint-header": "Esta es la representación en HTML del formato $1. HTML es adecuado para realizar tareas de depuración, pero no para utilizarlo en aplicaciones.\n\nUtiliza el parámetro <var>format</var> para modificar el formato de salida. Para ver la representación no HTML del formato $1, emplea <kbd>format=$2</kbd>.\n\nPara obtener más información, consulta la [[mw:API|documentación completa]] o la [[Special:ApiHelp/main|ayuda de API]].",
+       "api-format-prettyprint-header-only-html": "Esta es una representación en HTML destinada a la depuración, y no es adecuada para el uso de la aplicación.\n\nVéase la [[mw:API|documentación completa]] o la [[Special:ApiHelp/main|página de ayuda de la API]] para más información.",
        "api-format-prettyprint-status": "Esta respuesta se devolvería con el estado HTTP $1 $2.",
        "api-pageset-param-titles": "Una lista de títulos en los que trabajar.",
        "api-pageset-param-pageids": "Una lista de identificadores de páginas en las que trabajar.",
        "api-pageset-param-generator": "Obtener la lista de páginas en las que trabajar mediante la ejecución del módulo de consulta especificado.\n\n<strong>Nota:</strong> Los nombres de los parámetros del generador deben prefijarse con una «g», véanse los ejemplos.",
        "api-pageset-param-redirects-generator": "Resolver automáticamente las redirecciones en <var>$1titles</var>, <var>$1pageids</var>, y <var>$1revids</var> y en las páginas devueltas por <var>$1generator</var>.",
        "api-pageset-param-redirects-nogenerator": "Resolver automáticamente las redirecciones en <var>$1titles</var>, <var>$1pageids</var> y <var>$1revids</var>.",
+       "api-pageset-param-converttitles": "Convertir los títulos a otras variantes, si es necesario. Solo funciona si el idioma del contenido del wiki admite la conversión entre variantes. La conversión entre variantes está habilitada en idiomas tales como $1.",
        "api-help-title": "Ayuda de la API de MediaWiki",
        "api-help-lead": "Esta es una página de documentación autogenerada de la API de MediaWiki.\n\nDocumentación y ejemplos: https://www.mediawiki.org/wiki/API",
        "api-help-main-header": "Módulo principal",
        "apierror-changeauth-norequest": "No se ha podido crear la petición de modificación.",
        "apierror-compare-inputneeded": "Se necesita un título, un identificador de página o un número de revisión tanto para el parámetro <var>from</var> como para el parámetro <var>to</var>.",
        "apierror-contentserializationexception": "La serialización de contenido falló: $1",
+       "apierror-contenttoobig": "El contenido que has suministrado supera el tamaño máximo de archivo de $1 {{PLURAL:$1|kilobytes|kilobytes}}.",
        "apierror-create-titleexists": "Los títulos existentes no se pueden proteger con <kbd>create</kbd>.",
        "apierror-csp-report": "Error de procesamiento del informe CSP: $1.",
        "apierror-databaseerror": "[$1] Error en la consulta de la base de datos.",
        "apierror-invalidparammix-mustusewith": "El parámetro <kbd>$1</kbd> solo se puede utilizar junto con <kbd>$2</kbd>.",
        "apierror-invalidparammix-parse-new-section": "<kbd>section=new</kbd> no se puede combinar con los parámetros <var>oldid</var>, <var>pageid</var> y <var>page</var>. Por favor, utiliza <var>title</var> y <var>text</var>.",
        "apierror-invalidparammix": "{{PLURAL:$2|Los parámetros}} $1 no se pueden utilizar juntos.",
-       "apierror-invalidsection": "El parámetro de sección debe ser un ID de sección válido, o bien <kbd>new</kbd>.",
+       "apierror-invalidsection": "El parámetro <var>section</var> debe ser un identificador de sección válido, o bien <kbd>new</kbd>.",
        "apierror-invalidsha1base36hash": "El hash SHA1Base36 proporcionado no es válido.",
        "apierror-invalidsha1hash": "El hash SHA1 proporcionado no es válido.",
        "apierror-invalidtitle": "Título incorrecto \"$1\".",
index 9fbc104..da85e64 100644 (file)
        "apihelp-query+deletedrevs-param-namespace": "Lister uniquement les pages dans cet espace de noms.",
        "apihelp-query+deletedrevs-param-limit": "Le nombre maximal de révisions à lister.",
        "apihelp-query+deletedrevs-param-prop": "Quelles propriétés obtenir :\n;revid:Ajoute l’ID de la révision supprimée.\n;parentid:Ajoute l’ID de la révision précédente de la page.\n;user:Ajoute l’utilisateur ayant fait la révision.\n;userid:Ajoute l’ID de l’utilisateur qui a fait la révision.\n;comment:Ajoute le commentaire de la révision.\n;parsedcomment:Ajoute le commentaire analysé de la révision.\n;minor:Marque si la révision est mineure.\n;len:Ajoute la longueur (en octets) de la révision.\n;sha1:Ajoute le SHA-1 (base 16) de la révision.\n;content:Ajoute le contenu de la révision.\n;token:<span class=\"apihelp-deprecated\">Obsolète.</span> Fournit le jeton de modification.\n;tags:Balises pour la révision.",
-       "apihelp-query+deletedrevs-example-mode1": "Lister les dernières révisions supprimées de des pages <kbd>Main Page</kbd> et <kbd>Talk:Main Page</kbd>, avec le contenu (mode 1).",
+       "apihelp-query+deletedrevs-example-mode1": "Lister les dernières révisions supprimées des pages <kbd>Main Page</kbd> et <kbd>Talk:Main Page</kbd>, avec le contenu (mode 1).",
        "apihelp-query+deletedrevs-example-mode2": "Lister les 50 dernières contributions de <kbd>Bob</kbd> supprimées (mode 2).",
        "apihelp-query+deletedrevs-example-mode3-main": "Lister les 50 premières révisions supprimées dans l’espace de noms principal (mode 3)",
        "apihelp-query+deletedrevs-example-mode3-talk": "Lister les 50 premières pages supprimées dans l’espace de noms {{ns:talk}} (mode 3).",
        "apihelp-query+imageinfo-paramvalue-prop-bitdepth": "Ajoute la profondeur de bits de la version.",
        "apihelp-query+imageinfo-paramvalue-prop-uploadwarning": "Utilisé par la page Special:Upload pour obtenir de l’information sur un fichier existant. Non prévu pour être utilisé en dehors du cœur de MédiaWiki.",
        "apihelp-query+imageinfo-paramvalue-prop-badfile": "Ajoute l'indication que le fichier est sur [[MediaWiki:Bad image list]]",
-       "apihelp-query+imageinfo-param-limit": "Combien de révision de fichier renvoyer par fichier.",
+       "apihelp-query+imageinfo-param-limit": "Combien de révisions de fichier renvoyer par fichier.",
        "apihelp-query+imageinfo-param-start": "Horodatage auquel démarrer la liste.",
        "apihelp-query+imageinfo-param-end": "Horodatage auquel arrêter la liste.",
        "apihelp-query+imageinfo-param-urlwidth": "Si $2prop=url est défini, une URL vers une image à l’échelle de cette largeur sera renvoyée.\nPour des raisons de performance si cette option est utilisée, pas plus de $1 images mises à l’échelle seront renvoyées.",
        "apihelp-query+siteinfo-paramvalue-prop-rightsinfo": "Renvoie l’information sur les droits du wiki (sa licence), si elle est disponible.",
        "apihelp-query+siteinfo-paramvalue-prop-restrictions": "Renvoie l’information sur les types de restriction disponibles (protection).",
        "apihelp-query+siteinfo-paramvalue-prop-languages": "Renvoie une liste des langues que MédiaWiki prend en charge (éventuellement localisée en utilisant <var>$1inlanguagecode</var>).",
+       "apihelp-query+siteinfo-paramvalue-prop-languagevariants": "Renvoie une liste de codes de langue pour lesquels [[mw:LanguageConverter|LanguageConverter]] est activé, et les variantes supportées pour chacun.",
        "apihelp-query+siteinfo-paramvalue-prop-skins": "Renvoie une liste de tous les habillages activés (éventuellement localisé en utilisant <var>$1inlanguagecode</var>, sinon dans la langue du contenu).",
        "apihelp-query+siteinfo-paramvalue-prop-extensiontags": "Renvoie une liste des balises d’extension de l’analyseur.",
        "apihelp-query+siteinfo-paramvalue-prop-functionhooks": "Renvoie une liste des accroches de fonction de l’analyseur.",
        "apierror-invalidexpiry": "Heure d'expiration invalide \"$1\".",
        "apierror-invalid-file-key": "Ne correspond pas à une clé valide de fichier.",
        "apierror-invalidlang": "Code de langue non valide pour le paramètre <var>$1</var>.",
-       "apierror-invalidoldimage": "Le paramètre oldimage a un format non valide.",
+       "apierror-invalidoldimage": "Le paramètre <var>oldimage</var> a un format non valide.",
        "apierror-invalidparammix-cannotusewith": "Le paramètre <kbd>$1</kbd> ne peut pas être utilisé avec <kbd>$2</kbd>.",
        "apierror-invalidparammix-mustusewith": "Le paramètre <kbd>$1</kbd> ne peut être utilisé qu’avec <kbd>$2</kbd>.",
        "apierror-invalidparammix-parse-new-section": "<kbd>section=new</kbd> ne peut pas être combiné avec le paramètre <var>oldid</var>, <var>pageid</var> ou <var>page</var>. Veuillez utiliser <var>title</var> et <var>text</var>.",
        "apierror-invalidparammix": "{{PLURAL:$2|Les paramètres}} $1 ne peuvent pas être utilisés ensemble.",
-       "apierror-invalidsection": "Le paramètre section doit être un ID de section valide ou <kbd>new</kbd>.",
+       "apierror-invalidsection": "Le paramètre <var>section</var> doit être un ID de section valide ou <kbd>new</kbd>.",
        "apierror-invalidsha1base36hash": "Le hachage SHA1Base36 fourni n’est pas valide.",
        "apierror-invalidsha1hash": "Le hachage SHA1 fourni n’est pas valide.",
        "apierror-invalidtitle": "Mauvais titre « $1 ».",
index f8e3f05..24cb77c 100644 (file)
        "apierror-invalidexpiry": "Hora de caducidade incorrecta \"$1\".",
        "apierror-invalid-file-key": "Non se corresponde cunha clave válida de ficheiro.",
        "apierror-invalidlang": "Código de lingua incorrecto para o parámetro <var>$1</var>.",
-       "apierror-invalidoldimage": "O parámetro oldimage ten un formato incorrecto.",
+       "apierror-invalidoldimage": "O parámetro <var>oldimage</var> ten un formato incorrecto.",
        "apierror-invalidparammix-cannotusewith": "O parámetro <kbd>$1</kbd> non pode usarse xunto con <kbd>$2</kbd>.",
        "apierror-invalidparammix-mustusewith": "O parámetro <kbd>$1</kbd> só pode usarse xunto con <kbd>$2</kbd>.",
        "apierror-invalidparammix-parse-new-section": "<kbd>section=new</kbd> non se pode combinar cos parámetros <var>oldid</var>, <var>pageid</var> e <var>page</var>. Por favor, utilice <var>title</var> e <var>text</var>.",
        "apierror-invalidparammix": "{{PLURAL:$2|Os parámetros}} $1 non poden usarse xuntos.",
-       "apierror-invalidsection": "O parámetro sección debe ser un ID de sección válido ou <kbd>new</kbd>.",
+       "apierror-invalidsection": "O parámetro <var>section</var> debe ser un ID de sección válido ou <kbd>new</kbd>.",
        "apierror-invalidsha1base36hash": "O código hash SHA1Base36 proporcionado non é correcto.",
        "apierror-invalidsha1hash": "O código hash SHA1 proporcionado non é correcto.",
        "apierror-invalidtitle": "Título incorrecto \"$1\".",
        "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-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-validationfailed-badpref": "non é unha preferencia válida.",
        "apiwarn-validationfailed-cannotset": "non pode ser establecido por este módulo.",
index 682f9fc..f10334a 100644 (file)
@@ -13,7 +13,8 @@
                        "Macofe",
                        "MojoMann",
                        "Mikey641",
-                       "Esh77"
+                       "Esh77",
+                       "שמזן"
                ]
        },
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|תיעוד]]\n* [[mw:API:FAQ|שו\"ת]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api רשימת דיוור]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce הודעות על API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R באגים ובקשות]\n</div>\n<strong>מצב:</strong> כל האפשרויות שמוצגות בדף הזה אמורות לעבוד, אבל ה־API עדיין בפיתוח פעיל, ויכול להשתנות בכל זמן. עשו מינוי ל[https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ רשימת הדיוור mediawiki-api-announce] להודעות על עדכונים.\n\n<strong>בקשות שגויות:</strong> כשבקשות שגויות נשלחות ל־API, תישלח כותרת HTTP עם המפתח \"MediaWiki-API-Error\" ואז גם הערך של הכותרת וגם קוד השגיאה יוגדרו לאותו ערך. למידע נוסף ר' [[mw:API:Errors_and_warnings|API: שגיאות ואזהרות]].\n\n<strong>בדיקה:</strong> לבדיקה קלה יותר של בקשות ר' [[Special:ApiSandbox]].",
        "apihelp-query+siteinfo-paramvalue-prop-rightsinfo": "החזרת הזכויות (הרישיון) של הוויקי, אם זמין.",
        "apihelp-query+siteinfo-paramvalue-prop-restrictions": "החזרת מידע על ההגבלות (ההגנות) הזמינות.",
        "apihelp-query+siteinfo-paramvalue-prop-languages": "החזרת השפות שמדיה־ויקי תומכת בהן (זה יכול להיות מותאם מקומים עם <var>$1inlanguagecode</var>).",
+       "apihelp-query+siteinfo-paramvalue-prop-languagevariants": "מחזיר רשימת קודי שפה שמופעל עבורם ממיר שפה ([[mw:LanguageConverter|LanguageConverter]]), וההגוונים הנתמכים עבור כל אחת מהן.",
        "apihelp-query+siteinfo-paramvalue-prop-skins": "החזרת רשימת כל העיצובים הזמינים (זה יכול להיות מותאם מקומית באמצעות <var>$1inlanguagecode</var>, אחרת זה יהיה בשפת התוכן).",
        "apihelp-query+siteinfo-paramvalue-prop-extensiontags": "החזרת רשימת תגי הרחבת מפענח.",
        "apihelp-query+siteinfo-paramvalue-prop-functionhooks": "החזרת hook־ים של הרחבות מפענח.",
        "apihelp-setpagelanguage-description": "שנה את השפה של דף",
        "apihelp-setpagelanguage-description-disabled": "שינוי השפה של דף לא מורשה בוויקי זה.\n\nהפעל את <var>[[mw:Manual:$wgPageLanguageUseDB|$wgPageLanguageUseDB]]</var> על מנת להשתמש בפעולה זו",
        "apihelp-setpagelanguage-param-title": "כותרת הדף שאת שפתו ברצונך לשנות. לא אפשרי להשתמש באפשרות עם <var>$1pageid</var>.",
+       "apihelp-setpagelanguage-param-pageid": "מזהה הדף שאת שפתו ברצונך לשנות. לא אפשרי להשתמש באפשרות עם <var>$1title</var>.",
+       "apihelp-setpagelanguage-param-lang": "קוד השפה של השפה שאליה צריך לשנות את הדף. יש להשתמש ב־<kbd>default</kbd> כדי לאתחל את הדף לשפת בררת המחדל של הוויקי.",
        "apihelp-setpagelanguage-param-reason": "הסיבה לשינוי.",
        "apihelp-setpagelanguage-param-tags": "אילו תגי שינוי להחיל על העיול ביומן שמתבצע כתוצאה מהפעולה הזאת.",
        "apihelp-setpagelanguage-example-language": "שינוי השפה של <kbd>Main Page</kbd> לבסקית.",
        "apihelp-upload-param-sessionkey": "אותו דבר כמו $1filekey, מושאר לצור תאימות אחורה.",
        "apihelp-upload-param-stash": "אם זה מוגדר, השרת יסליק זמנית את הקובץ במקום להוסיף אותו למאגר.",
        "apihelp-upload-param-filesize": "גודל הקובץ של כל ההעלאה.",
-       "apihelp-upload-param-offset": "×\94×\99ס×\98 ×\94×\97ת×\99×\9b×\94 ×\91×\91×\99×\99×\98ים.",
+       "apihelp-upload-param-offset": "×\94×\99ס×\98 ×\94פ×\9c×\97 ×\91×\91תים.",
        "apihelp-upload-param-chunk": "תוכן החתיכה.",
        "apihelp-upload-param-async": "להפוך פעולות קבצים גדולות לאסינכרוניות כשאפשר.",
        "apihelp-upload-param-checkstatus": "לאחזר רק מצב העלאה עבור מפתח הקובץ שניתן.",
        "apihelp-userrights-param-user": "שם משתמש.",
        "apihelp-userrights-param-userid": "מזהה משתמש.",
        "apihelp-userrights-param-add": "הוספת המשתמש לקבוצות האלו, ואם הוא כבר חבר, עדכון זמן התפוגה של החברות בקבוצה הזאת.",
+       "apihelp-userrights-param-expiry": "חותמי־זמן תפוגה. יכולים להיות יחסיים (למשל <kbd>5 months</kbd> או <kbd>2 weeks</kbd>) או מוחלטים (למשל <kbd>2014-09-18T12:34:56Z</kbd>). אם מוגדר רק חותם־זמן אחד, הוא ישמש לכל הקבוצות שהועברו לפרמטר <var>$1add</var>. יש להשתמש ב־<kbd>infinite</kbd>‏, <kbd>indefinite</kbd>‏, <kbd>infinity</kbd>, או <kbd>never</kbd> בשביל קבוצת משתמשים שאינה פגה לעולם.",
        "apihelp-userrights-param-remove": "הסרת משתמש מהקבוצות האלו.",
        "apihelp-userrights-param-reason": "סיבה לשינוי.",
        "apihelp-userrights-param-tags": "לשנות את התגים שיוחלו על העיול ביומן הרשאות המשתמש.",
        "apihelp-userrights-example-user": "הוספת המשתמש <kbd>FooBot</kbd> לקבוצה <kbd>bot</kbd> והסרתו מהקבוצות <kbd>sysop</kbd> ו־<kbd>bureaucrat</kbd>.",
        "apihelp-userrights-example-userid": "הוספת המשתמש עם המזהה <kbd>123</kbd> לקבוצה <kbd>bot</kbd> והסרתו מהקבוצות <kbd>sysop</kbd> ו־<kbd>bureaucrat</kbd>.",
+       "apihelp-userrights-example-expiry": "להוסיף את <kbd>SometimeSysop</kbd> לקבוצה <kbd>sysop</kbd> לחודש אחד.",
        "apihelp-validatepassword-description": "לבדוק תקינות ססמה אל מול מדיניות הססמאות של הוויקי.\n\nהתקינות מדווחת כ־<samp>Good</samp> אם הססמה קבילה, <samp>Change</samp> אם הססמה יכולה לשמש לכניסה, אבל צריכה להשתנות, או <samp>Invalid</samp> אם הססמה אינה שמישה.",
        "apihelp-validatepassword-param-password": "ססמה שתקינותה תיבדק.",
        "apihelp-validatepassword-param-user": "שם משתמש, לשימוש בעת בדיקת יצירת חשבון. המשתמש ששמו ניתן צריך לא להיות קיים.",
        "apierror-blockedfrommail": "נחסמת משליחת דוא״ל.",
        "apierror-blocked": "נחסמת מעריכה.",
        "apierror-botsnotsupported": "הממשק הזה לא נתמך עבור בוטים.",
+       "apierror-cannot-async-upload-file": "הפרמטרים  <var>async</var> ו־<var>file</var> אינם יכולים להיות משולבים. אם ברצונך לבצע עיבוד אסינכרוני של הקובץ המועלה שלך, יש להעלות אותו תחילה לסליק (באמצעות הפרמטר <var>stash</var>) ואז לפרסם את הקובץ המוסלק באופן אסינכרוני (באמצעות <var>filekey</var> ו־<var>async</var>).",
        "apierror-cannotreauthenticate": "הפעולה הזאת אינה זמינה, כי הזהות שלך לא יכולה להיות מאומתת.",
        "apierror-cannotviewtitle": "אין לך הרשאה להציג את $1.",
        "apierror-cantblock-email": "אין לך הרשאה לחסום משתמשים משליחת דואר אלקטרוני דרך הוויקי.",
        "apierror-integeroutofrange-abovemax": "<var>$1</var> אינו יכול להיות גדול מ־$2 (עכשיו מוגדר $3) עבור משתמשים.",
        "apierror-integeroutofrange-belowminimum": "<var>$1</var> אינו יכול להיות גדול מ־$2 (עכשיו מוגדר $3).",
        "apierror-invalidcategory": "שם הקטגוריה שהזנת אינו תקין.",
+       "apierror-invalid-chunk": "ההיסט בתוספת הפלח הנוכחי גדולים מגודל הקובץ כפי שנטען.",
        "apierror-invalidexpiry": "זמן תפוגה בלתי־תקין \"$1\".",
        "apierror-invalid-file-key": "לא מפתח קובץ תקין.",
+       "apierror-invalidlang": "קוד שפה בלתי־תקין לפרמטר <var>$1</var>.",
+       "apierror-invalidoldimage": "הפרמטר <var>oldimage</var> נשלח בתסדיר בלתי־תקין.",
+       "apierror-invalidparammix-cannotusewith": "הפרמטר <kbd>$1</kbd> אינו יכול לשמש עם <kbd>$2</kbd>.",
+       "apierror-invalidparammix-mustusewith": "הפרמטר <kbd>$1</kbd> יכול לשמש רק עם <kbd>$2</kbd>.",
+       "apierror-invalidparammix-parse-new-section": "לא ניתן לשלב את <kbd>section=new</kbd> עם הפרמטרים <var>oldid</var>‏, <var>pageid</var> או <var>page</var>. נא להשתמש ב־<var>title</var> ו־<var>text</var>.",
+       "apierror-invalidparammix": "{{PLURAL:$2|הפרמטרים}} $1 אינם יכולים לשמש יחדיו.",
+       "apierror-invalidsection": "הפרמטר <var>section</var> להיות מזהה מקטע תקין או <kbd>new</kbd>.",
+       "apierror-invalidsha1base36hash": "גיבוב ה־SHA1Base36 שסופק אינו תקין.",
+       "apierror-invalidsha1hash": "גיבוב ה־SHA1 שסופק אינו תקין.",
        "apierror-invalidtitle": "כותרת רעה \"$1\".",
+       "apierror-invalidurlparam": "ערך בלתי־תקין עבור <var>$1urlparam</var> (ערך: <kbd>$2=$3</kbd>).",
        "apierror-invaliduser": "שם משתמש בלתי־תקין \"$1\".",
+       "apierror-invaliduserid": "מזהה המשתמש <var>$1</var> אינו תקין.",
+       "apierror-maxlag-generic": "ממתין לשרת מסד נתונים: עיכוב של {{PLURAL:$1|שנייה אחת|$1 שניות}}.",
        "apierror-maxlag": "ממתין ל־$2: שיהוי של {{PLURAL:$1|שנייה אחת|$1 שניות}}.",
+       "apierror-mimesearchdisabled": "חיפוש MIME כבוי במצב קמצן.",
+       "apierror-missingcontent-pageid": "תוכן חסר עבור מזהה הדף $1.",
+       "apierror-missingparam-at-least-one-of": "דרוש {{PLURAL:$2|הפרמטר|לפחות אחד מהפרמטרים}} $1.",
+       "apierror-missingparam-one-of": "דרוש {{PLURAL:$2|הפרמטר|אחד מהפרמטרים}} $1.",
+       "apierror-missingparam": "הפרמטר <var>$1</var> צריך להיות מוגדר.",
+       "apierror-missingrev-pageid": "אין גרסה נוכחית של דף עם המזהה $1.",
+       "apierror-missingtitle-createonly": "כותרות חסרות יכולות להיות מוגנות עם <kbd>create</kbd>.",
+       "apierror-missingtitle": "הדף שנתת אינו קיים.",
+       "apierror-missingtitle-byname": "הדף $1 אינו קיים.",
+       "apierror-moduledisabled": "המודול <kbd>$1</kbd> כובה.",
+       "apierror-multival-only-one-of": "{{PLURAL:$3|רק הערך|רק אחד מתוך הערכים}} $2 מותר עבור הפרמטר <var>$1</var>.",
+       "apierror-multival-only-one": "רק ערך אחד מותר עבור הפרמטר <var>$1</var>.",
+       "apierror-multpages": "<var>$1</var> יכול לשמש רק בדף בודד.",
+       "apierror-mustbeloggedin-changeauth": "יש להיכנס לחשבון כדי לשנות נתוני אימות.",
        "apierror-mustbeloggedin-generic": "חובה להיכנס.",
        "apierror-mustbeloggedin-linkaccounts": "חובה להיכנס לחשבון כדי לקשר חשבונות.",
        "apierror-mustbeloggedin-removeauth": "חובה להיכנס לחשבון כדי להסיר מידע אימות.",
        "apierror-mustbeloggedin-uploadstash": "סליק ההעלאה זמין רק למשתמשים שנכנסו לחשבון.",
        "apierror-mustbeloggedin": "חובה להיכנס לחשבון כדי $1.",
+       "apierror-mustbeposted": "המודול <kbd>$1</kbd> דורש בקשת POST.",
+       "apierror-mustpostparams": "{{PLURAL:$2|הפרמטר הבא|הפרמטרים הבאים}} נמצאו במחרוזת השאילתה, אבל חייבים להיות ב־POST בגוף: $1.",
+       "apierror-noapiwrite": "עריכת הוויקי הזה דרך ה־API כובתה. נא לוודא שהמשפט <code dir=\"ltr\">$wgEnableWriteAPI=true;</code> כלול בקובץ <code>LocalSettings.php</code> של הוויקי.",
        "apierror-nochanges": "לא התבקשו שינויים.",
        "apierror-nodeleteablefile": "אין גרסה ישנה כזאת של הקובץ.",
        "apierror-no-direct-editing": "עריכה ישירה דרך ה־API אינה נתמכת עבור דגם התוכן $1 שמשמש ב{{GRAMMAR:תחילית|$2}}.",
        "apierror-noedit-anon": "משתמשים אלמוניים אינם יכולים לערוך דפים.",
+       "apierror-noedit": "אין לך הרשאה לערוך דפים.",
+       "apierror-noimageredirect-anon": "משתמשים אלמוניים אינם יכולים ליצור הפניות לתמונות.",
+       "apierror-noimageredirect": "אין לך הרשאה ליצור הפניות לתמונות.",
        "apierror-nosuchlogid": "אין רשומה ביומן עם המזהה $1.",
+       "apierror-nosuchpageid": "אין דף עם המזהה $1.",
+       "apierror-nosuchrcid": "לא נעשה לאחרונה שינוי עם המזהה $1.",
+       "apierror-nosuchrevid": "אין גרסה עם המזהה $1.",
+       "apierror-nosuchsection": "לא קיים מקטע $1.",
+       "apierror-nosuchsection-what": "אין מקטע $1 ב{{GRAMMAR:תחילית|$2}}.",
+       "apierror-nosuchuserid": "אין משתמש עם המזהה $1.",
+       "apierror-notarget": "לא נתת יעד תקין לפעולה הזאת.",
+       "apierror-notpatrollable": "לא ניתן לנטר את הגרסה $1 כי היא ישנה מדי.",
+       "apierror-nouploadmodule": "לא הוגדר מודול העלאה.",
+       "apierror-opensearch-json-warnings": "לא ניתן לייצג את האזהרות בתסדיר JSON של OpenSearch.",
+       "apierror-pagecannotexist": "מרחב השם אינו מתיר דפים אמתיים.",
+       "apierror-pagedeleted": "הדף הזה נמחק מאז שאחזרת את חותם הזמן שלו.",
+       "apierror-pagelang-disabled": "שינוי שפת הדף אסור בוויקי הזה.",
+       "apierror-paramempty": "הפרמטר <var>$1</var> אינו יכול להיות ריק.",
+       "apierror-parsetree-notwikitext": "<kbd>prop=parsetree</kbd> נתמך רק בתוכן קוד ויקי (wikitext).",
+       "apierror-parsetree-notwikitext-title": "<kbd>prop=parsetree</kbd> נתמך רק בתוכן קוד ויקי (wikitext). $1 משתמש במודל התוכן $2.",
+       "apierror-pastexpiry": "זמן התפוגה \"$1\" בעבר.",
+       "apierror-permissiondenied": "אין לך הרשאה $1.",
+       "apierror-permissiondenied-generic": "ההרשאה נדחתה.",
+       "apierror-permissiondenied-patrolflag": "עליך להחזיק בהרשאות <code>patrol</code> או <code>patrolmarks</code> כדי לבקש דגל מנוטר.",
+       "apierror-permissiondenied-unblock": "אין לך הרשאה לשחרר חסימה של משתמשים.",
+       "apierror-prefixsearchdisabled": "חיפוש תחילית כבוי במצב קמצן.",
+       "apierror-promised-nonwrite-api": "כותר <code>Promise-Non-Write-API-Action</code> של HTTP אינו יכול להישלח למודולי API שפועלים במצב כתיבה.",
+       "apierror-protect-invalidaction": "סוג הגנה בלתי־תקין \"$1\".",
+       "apierror-protect-invalidlevel": "קמת הגנה בלתי־תקינה \"$1\".",
+       "apierror-ratelimited": "עברת את מכסת הקצב שלך. נא להמתין זמן־מה ונסות שוב.",
+       "apierror-readapidenied": "יש צורך בהרשאת קריאה כדי להשתמש במודול הזה.",
+       "apierror-readonly": "הוויקי הזה במצב לקריאה בלבד עכשיו.",
+       "apierror-reauthenticate": "לא עברת אימות לאחרונה בשיחה הזאת, נא להתאמת מחדש.",
+       "apierror-redirect-appendonly": "ניסית לערוך במצב מעבר־אחר־הפניות (redirect-following), שצריך לשמש יחד עם <kbd>section=new</kbd>‏, <var>prependtext</var>, או <var>appendtext</var>.",
+       "apierror-revdel-mutuallyexclusive": "אותו השדה אינו יכול לשמש עם <var>hide</var> ועם <var>show</var>.",
+       "apierror-revdel-needtarget": "כותרת יעד נחוצה בשביל סוג ה־RevDel הזה.",
+       "apierror-revdel-paramneeded": "לפחות ערך אחד נחוץ בשביל <var>hide</var> או <var>show</var>.",
+       "apierror-revisions-norevids": "הפרמטר <var>revids</var> אינו יכול לשמש עם אפשרויות הרשימה (<var>$1limit</var>‏, <var>$1startid</var>‏, <var>$1endid</var>‏, <kbd>$1dir=newer</kbd>‏, <var>$1user</var>‏, <var>$1excludeuser</var>‏, <var>$1start</var>, ו־<var>$1end</var>).",
+       "apierror-revisions-singlepage": "<var>titles</var>‏, <var>pageids</var> או מחולל שימשו לאספקת דפים מרובים, אבל הפרמטרים <var>$1limit</var>‏, <var>$1startid</var>‏, <var>$1endid</var>‏, <kbd>$1dir=newer</kbd>‏, <var>$1user</var>‏, <var>$1excludeuser</var>‏, <var>$1start</var>, ו־<var>$1end</var> יכולים לשמש רק בדף בודד.",
+       "apierror-revwrongpage": "הגרסה $1 אינה גרסה של $2.",
+       "apierror-searchdisabled": "חיפוש <var>$1</var> כבוי.",
+       "apierror-sectionreplacefailed": "לא היה אפשר למזג את המקטע המעודכן.",
+       "apierror-sectionsnotsupported": "מקטעים אינם נתמכים במודל התוכן $1.",
+       "apierror-sectionsnotsupported-what": "מקטעים אינם נתמכים ב־$1.",
+       "apierror-show": "פרמטר לא נכון – אי־אפשר לספק ערכים שמבטלים זה את זה.",
+       "apierror-siteinfo-includealldenied": "לא ניתן להציג את המידע של כל השרתים אלא אם <var dir=\"ltr\">$wgShowHostNames</var> מוגדר להיות true.",
+       "apierror-sizediffdisabled": "ההבדל בגודל כבוי במצב קמצן.",
+       "apierror-spamdetected": "העריכה שלך סורבה כי הכילה חלק ספאם: <code>$1</code>.",
+       "apierror-specialpage-cantexecute": "אין לך הרשאה להציג את התוצאות של הדף המיוחד הזה.",
+       "apierror-stashedfilenotfound": "לא היה אפשר למצור את הקובץ בסליק: $1.",
+       "apierror-stashedit-missingtext": "לא נמצא טקסט מוסלק עם הגיבוב שניתן.",
+       "apierror-stashfailed-complete": "העלאה מפולחת הושלמה, יש לבדוק את המצב בשביל לראות פרטים.",
+       "apierror-stashfailed-nosession": "אין שיחת העלאה מפולחת עם המפתח הזה.",
+       "apierror-stashfilestorage": "לא היה אפשר לאחסן את ההעלאה בסליק: $1",
        "apierror-stashinvalidfile": "קובץ מוסלק בלתי־תקין.",
        "apierror-stashnosuchfilekey": "אין מפתח קובץ כזה: $1.",
        "apierror-stashpathinvalid": "מפתח קובץ מתסדיר בלתי־הולם או בלתי־תקין באופן אחר: $1.",
        "apierror-stashwrongowner": "בעלים בלתי־תקין: $1",
        "apierror-stashzerolength": "קובץ באורך אפס, ואל יכול משוחזר בסליק: $1.",
        "apierror-systemblocked": "נחסמת אוטומטית על־ידי מדיה־ויקי.",
+       "apierror-templateexpansion-notwikitext": "הרחבת תבניות נתמכת רק בתוכן קוד ויקי (wikitext). $1 משתמש במודל התוכן $2.",
+       "apierror-toofewexpiries": "{{PLURAL:$1|ניתן חותם זמן תפוגה אחד|ניתנו $1 חותמי זמן תפוגה}} כאשר {{PLURAL:$2|היה נחוץ אחד|היו נחוצים $1}}.",
+       "apierror-unknownaction": "הפעולה שניתנה, <kbd>$1</kbd>, אינה מוכרת.",
+       "apierror-unknownerror-editpage": "שגיאת EditPage בלתי־ידועה: $1.",
        "apierror-unknownerror-nocode": "שגיאה בלתי־ידועה.",
        "apierror-unknownerror": "שגיאה בלתי ידועה: \"$1\".",
        "apierror-unknownformat": "תסדיר בלתי־ידוע \"$1\".",
+       "apierror-unrecognizedparams": "{{PLURAL:$2|פרמטר בלתי־מוכר|פרמטרים בלתי־מוכרים}}: $1.",
+       "apierror-unrecognizedvalue": "לפרמטר <var>$1</var> יש ערך בלתי־מוכר: $2.",
+       "apierror-unsupportedrepo": "מאגר קבצים מקומי אינו תומך בשאילתה לכל התמונות.",
        "apierror-upload-filekeyneeded": "חובה לספק <var>filekey</var> כאשר <var>offset</var> אינו אפס.",
        "apierror-upload-filekeynotallowed": "לא ניתן לספק <var>filekey</var> כאשר <var>offset</var> הוא 0.",
+       "apierror-upload-inprogress": "העלאה מתוך סליק כבר התחילה.",
        "apierror-upload-missingresult": "אין תוצאות בנתוני מצב.",
+       "apierror-urlparamnormal": "לא היה אפשר לנרמל את פרמטרי התמונה עבור $1.",
        "apierror-writeapidenied": "אין לך הרשאה לערוך את הוויקי הזה דרך ה־API.",
        "apiwarn-alldeletedrevisions-performance": "לביצועים טובים יותר בעת יצירת כותרת, יש להשתמש ב־<kbd>$1dir=newer</kbd>.",
        "apiwarn-badurlparam": "לא היה אפשר לפענח את <var>$1urlparam</var> עבור $2. משתמשים רק ב־width ו־height.",
        "apiwarn-deprecation-expandtemplates-prop": "מכיוון שלא ניתנו ערכים לפרמטר <var>prop</var>, תסדיר מיושן ישמש לפלט. התסדיר הזה מיושן, ובעתיד יינתן ערך בררת מחדל לפרמטר <var>prop</var>, כך שתמיד ישמש התסדיר החדש.",
        "apiwarn-deprecation-httpsexpected": "משמש HTTP כשהיה צפוי HTTPS.",
        "apiwarn-deprecation-login-botpw": "כניסה לחשבון עיקרי (main-account) דרך <kbd>action=login</kbd> מיושנת ועלולה להפסיק לעבוד ללא אזהרה נוספת. כדי להמשיך להיכנס עם <kbd>action=login</kbd>, ר' [[Special:BotPasswords]]. כדי להמשיך באופן מאובטח באמצעות חשבון עיקרי, ר' <kbd>action=clientlogin</kbd>.",
+       "apiwarn-deprecation-login-nobotpw": "כניסה בחשבון ראשי עם <kbd>action=login</kbd> מיושנת ויכולה להפסיק לעבוד ללא אזהרה. כדי להיכנס באופן מאובטח, ר' <kbd>action=clientlogin</kbd>.",
        "apiwarn-deprecation-login-token": "אחזור אסימון דרך <kbd>action=login</kbd> מיושן. נא להשתמש ב־<kbd>action=query&meta=tokens&type=login</kbd> במקום זה.",
        "apiwarn-deprecation-parameter": "הפרמטר <var>$1</var> מיושן.",
        "apiwarn-deprecation-parse-headitems": "<kbd>prop=headitems</kbd> מיושן מאז מדיה־ויקי 1.28. יש להשתמש ב־<kbd>prop=headhtml</kbd> בעת יצירת מסמכי HTML חדשים, או ב־<kbd>prop=modules|jsconfigvars</kbd> בעת עדכון מסמך בצד הלקוח.",
        "apiwarn-redirectsandrevids": "פתרון הפניות לא יכול לשמש יחד עם הפרמטר <var>revids</var>. הפניות ש־<var>revids</var> מצביע אליהן לא נפתרו.",
        "apiwarn-tokennotallowed": "הפעולה \"$1\" אינה מותרת למשתמש הנוכחי.",
        "apiwarn-tokens-origin": "לא ניתן לקבל אסימונים כשמדיניות המקור הזהה אינה חלה.",
-       "apiwarn-toomanyvalues": "יותר מדי ערכים סופקו לפרמטר <var>$1</var>: המגבלה היא $2.",
+       "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.",
index 61e70f4..d84775f 100644 (file)
        "api-help-authmanagerhelper-returnurl": "URL di ritorno per i flussi di autenticazione di terze parti, deve essere assoluto. E' necessario fornirlo, oppure va fornito <var>$1continue</var>.\n\nAlla ricezione di una risposta <samp>REDIRECT</samp>, in genere si apre un browser o una vista web all'URL specificato <samp>redirecttarget</samp> per un flusso di autenticazione di terze parti. Quando questo è completato, la terza parte invierà il browser o la vista web a questo URL. Dovresti estrarre qualsiasi parametro POST o della richiesta dall'URL e passarli come un request <var>$1continue</var> a questo modulo API.",
        "api-help-authmanagerhelper-continue": "Questa richiesta è una continuazione dopo una precedente risposta <samp>UI</samp> o <samp>REDIRECT</samp>. È necessario fornirlo, oppure fornire <var>$1returnurl</var>.",
        "api-help-authmanagerhelper-additional-params": "Questo modulo accetta parametri aggiuntivi a seconda delle richieste di autenticazione disponibili. Utilizza <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> con <kbd>amirequestsfor=$1</kbd> (o una precedente risposta da questo modulo, se applicabile) per determinare le richieste disponibili e i campi usati da queste.",
+       "apierror-invalidoldimage": "Il parametro <var>oldimage</var> ha un formato non valido.",
        "apierror-invaliduserid": "L'ID utente <var>$1</var> non è valido.",
        "apierror-nosuchuserid": "Non c'è alcun utente con ID $1.",
        "api-credits-header": "Crediti"
index 258a3d4..30dec54 100644 (file)
@@ -84,6 +84,8 @@
        "apihelp-createaccount-param-language": "사용자에게 기본으로 설정할 언어 코드. (선택 사항, 기본값으로는 본문의 언어입니다)",
        "apihelp-createaccount-example-pass": "사용자 <kbd>testuser</kbd>를 만들고 비밀번호를 <kbd>test123</kbd>으로 설정합니다.",
        "apihelp-createaccount-example-mail": "사용자 <kbd>testmailuser</kbd>를 만들고 자동 생성된 비밀번호를 이메일로 보냅니다.",
+       "apihelp-cspreport-description": "브라우저가 콘텐츠 보안 정책의 위반을 보고하기 위해 사용합니다. 이 모듈은 SCP를 준수하는 웹 브라우저에 의해 자동으로 사용될 때를 제외하고는 사용해서는 안 됩니다.",
+       "apihelp-cspreport-param-reportonly": "강제적 정책이 아닌, 모니터링 정책에서 나온 보고서인 것으로 표시합니다",
        "apihelp-delete-description": "문서 삭제",
        "apihelp-delete-param-title": "삭제할 문서의 제목. <var>$1pageid</var>과 함께 사용할 수 없습니다.",
        "apihelp-delete-param-pageid": "삭제할 문서의 ID. <var>$1title</var>과 함께 사용할 수 없습니다.",
        "apihelp-feedwatchlist-param-feedformat": "피드 포맷.",
        "apihelp-feedwatchlist-example-default": "주시문서 목록 피드를 보여줍니다.",
        "apihelp-filerevert-description": "파일을 이전 판으로 되돌립니다.",
+       "apihelp-filerevert-param-filename": "파일: 접두어가 없는 대상 파일 이름.",
        "apihelp-filerevert-param-comment": "업로드 댓글입니다.",
        "apihelp-filerevert-example-revert": "<kbd>Wiki.png</kbd>를 <kbd>2011-03-05T15:27:40Z</kbd> 판으로 되돌립니다.",
        "apihelp-help-description": "지정된 모듈의 도움말을 표시합니다.",
+       "apihelp-help-param-modules": "(<var>action</var>, <var>format</var> 변수의 값 또는 <kbd>main</kbd>)에 대한 도움말을 표시하는 모듈입니다. <kbd>+</kbd>로 하위 모듈을 지정할 수 있습니다.",
+       "apihelp-help-param-submodules": "명명된 모듈의 하위 모듈의 도움말을 포함합니다.",
+       "apihelp-help-param-recursivesubmodules": "하위 모듈의 도움말을 반복하여 포함합니다.",
        "apihelp-help-param-helpformat": "도움말 출력 포맷.",
+       "apihelp-help-param-wrap": "표준 API 응답 구조로 출력을 감쌉니다.",
+       "apihelp-help-param-toc": "HTML 출력에 목차를 포함합니다.",
        "apihelp-help-example-main": "메인 모듈의 도움말입니다.",
        "apihelp-help-example-recursive": "모든 도움말을 한 페이지로 모읍니다.",
+       "apihelp-help-example-help": "도움말 모듈 자체에 대한 도움말입니다.",
+       "apihelp-help-example-query": "2개의 쿼리 하위 모듈의 도움말입니다.",
        "apihelp-imagerotate-description": "하나 이상의 그림을 회전합니다.",
        "apihelp-imagerotate-param-rotation": "시계 방향으로 회전할 그림의 각도.",
        "apihelp-import-param-xml": "업로드한 XML 파일.",
        "apihelp-parse-example-page": "페이지의 구문을 분석합니다.",
        "apihelp-parse-example-text": "위키텍스트의 구문을 분석합니다.",
        "apihelp-parse-example-summary": "요약을 구문 분석합니다.",
+       "apihelp-patrol-param-rcid": "점검할 최근 바뀜 ID입니다.",
+       "apihelp-patrol-param-revid": "점검할 판 ID입니다.",
+       "apihelp-patrol-example-rcid": "최근의 변경사항을 점검합니다.",
        "apihelp-patrol-example-revid": "판을 점검합니다.",
        "apihelp-protect-description": "문서의 보호 수준을 변경합니다.",
        "apihelp-protect-param-reason": "보호 또는 보호 해제의 이유.",
        "apihelp-query+allusers-description": "등록된 모든 사용자를 열거합니다.",
        "apihelp-query+allusers-param-dir": "정렬 방향.",
        "apihelp-query+allusers-param-prop": "포함할 정보:",
+       "apihelp-query+allusers-paramvalue-prop-blockinfo": "현재 차단된 사용자의 정보를 추가함.",
        "apihelp-query+allusers-paramvalue-prop-editcount": "사용자의 편집 수를 추가합니다.",
        "apihelp-query+allusers-param-witheditsonly": "편집을 한 사용자만 나열합니다.",
        "apihelp-query+allusers-example-Y": "<kbd>Y</kbd>로 시작하는 사용자를 나열합니다.",
        "apihelp-query+watchlist-paramvalue-prop-flags": "편집에 대한 플래그를 추가합니다.",
        "apihelp-query+watchlist-paramvalue-prop-loginfo": "적절한 곳에 로그 정보를 추가합니다.",
        "apihelp-removeauthenticationdata-description": "현재 사용자의 인증 데이터를 제거합니다.",
+       "apihelp-resetpassword-description": "비밀번호 재설정 이메일을 사용자에게 보냅니다.",
+       "apihelp-resetpassword-param-user": "재설정할 사용자입니다.",
+       "apihelp-resetpassword-param-email": "재설정할 사용자의 이메일 주소입니다.",
+       "apihelp-resetpassword-example-user": "사용자 <kbd>Example</kbd>에게 비밀번호 재설정 이메일을 보냅니다.",
+       "apihelp-resetpassword-example-email": "<kbd>user@example.com</kbd> 이메일 주소를 가진 모든 사용자에 대해 비밀번호 재설정 이메일을 보냅니다.",
        "apihelp-revisiondelete-description": "판을 삭제하거나 되살립니다.",
        "apihelp-revisiondelete-param-reason": "삭제 또는 복구 이유.",
        "apihelp-rollback-param-tags": "되돌리기를 적용하기 위해 태그합니다.",
        "apihelp-unblock-param-userid": "차단을 해제할 사용자 ID입니다. <var>$1id</var> 또는 <var>$1user</var>와(과) 함께 사용할 수 없습니다.",
        "apihelp-unblock-param-reason": "차단 해제 이유.",
        "apihelp-unblock-param-tags": "차단 기록의 항목에 적용할 태그를 변경합니다.",
+       "apihelp-upload-param-filename": "대상 파일 이름.",
        "apihelp-upload-param-ignorewarnings": "모든 경고를 무시합니다.",
        "apihelp-userrights-param-user": "사용자 이름.",
        "apihelp-userrights-param-userid": "사용자 ID.",
        "apierror-filenopath": "로컬 파일 경로를 가져올 수 없습니다.",
        "apierror-import-unknownerror": "알 수 없는 가져오기 오류: $1.",
        "apierror-invalidcategory": "입력한 분류 이름이 올바르지 않습니다.",
+       "apierror-invalidexpiry": "잘못된 만료 기한 \"$1\".",
        "apierror-invalid-file-key": "유효한 파일 키가 아닙니다.",
-       "apierror-invalidoldimage": "oldimage 변수에 유효하지 않은 형식이 있습니다.",
+       "apierror-invalidoldimage": "<var>oldimage</var> 변수에 유효하지 않은 형식이 있습니다.",
        "apierror-invalidparammix-cannotusewith": "<kbd>$1</kbd> 변수는 <kbd>$2</kbd>와(과) 함께 사용할 수 없습니다.",
        "apierror-invalidsha1base36hash": "제공된 SHA1Base36 해시가 유효하지 않습니다.",
        "apierror-invalidsha1hash": "제공된 SHA1 해시가 유효하지 않습니다.",
index 3abfdeb..3045332 100644 (file)
@@ -13,8 +13,8 @@
        "apihelp-main-param-maxage": "Задајте му олку секунди на заглавието за контрола HTTP-меѓускладот <code>s-maxage</code>. Грешките никогаш не се чуваат во меѓускладот.",
        "apihelp-main-param-assert": "Провери дали корисникот е најавен ако е зададено <kbd>user</kbd> или дали го има корисничкото право на бот, ако е зададено <kbd>bot</kbd>.",
        "apihelp-main-param-requestid": "Тука внесената вредност ќе биде вклучена во извештајот. Може да се користи за разликување на барањата.",
-       "apihelp-main-param-servedby": "Вклучи го домаќинското име што го услужило барањето во резултатите.",
-       "apihelp-main-param-curtimestamp": "Ð\91клÑ\83Ñ\87и Ñ\82ековно Ð²Ñ\80еме Ð¸ Ð²Ñ\80еме Ð¸ Ð´Ð°Ñ\82Ñ\83м Ð²Ð¾ Ñ\80езÑ\83лÑ\82аÑ\82от.",
+       "apihelp-main-param-servedby": "Вклучи го домаќинското име што го услужило барањето во исходот.",
+       "apihelp-main-param-curtimestamp": "Ð\92клÑ\83Ñ\87и Ñ\82ековно Ð²Ñ\80еме Ð¸ Ð²Ñ\80еме Ð¸ Ð´Ð°Ñ\82Ñ\83м Ð²Ð¾ Ð¸Ñ\81Ñ\85одот.",
        "apihelp-main-param-origin": "Кога му пристапувате на Пирлогот користејќи повеќедоменско AJAX-барање (CORS), задајте му го на ова изворниот домен. Ова мора да се вклучи во секое подготвително барање и затоа мора да биде дел од URI на барањето (не главната содржина во POST). Ова мора точно да се совпаѓа со еден од изворниците на заглавието Origin:, така што мора да е зададен на нешто како <kbd>https://mk.wikipedia.org</kbd>  or <kbd>https://meta.wikimedia.org</kbd>. Ако овој параметар не се совпаѓа со заглавието <code>Origin</code>:, ќе се појави одговор 403. Ако се совпаѓа, а изворникот е на бел список (на допуштени), тогаш ќе се зададе заглавието <code>Access-Control-Allow-Origin</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-block-description": "Блокирај корисник.",
@@ -79,7 +79,7 @@
        "apihelp-edit-param-tags": "Ознаки за измена што се однесуваат на преработката.",
        "apihelp-edit-param-minor": "Ситно уредување.",
        "apihelp-edit-param-notminor": "Неситно уредување.",
-       "apihelp-edit-param-bot": "Означи го уредувањево како ботско.",
+       "apihelp-edit-param-bot": "Означи го уредувањево како ботовско.",
        "apihelp-edit-param-basetimestamp": "Датум и време на преработката на базата, кои се користат за утврдување на спротиставености во уредувањето. Може да се добие преку [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]].",
        "apihelp-edit-param-starttimestamp": "Датум и време кога сте почнало уредувањето, кои се користат за утврдување на спротиставености во уредувањата. Соодветната вредност се добива користејќи <var>[[Special:ApiHelp/main|curtimestamp]]</var> кога ќе почнете со уредување (на пр. кога ќе се вчита содржината што ќе ја уредувате).",
        "apihelp-edit-param-recreate": "Занемари ги грешките што се појавуваат во врска со страницата што е избришана во меѓувреме.",
        "apihelp-expandtemplates-param-title": "Наслов на страница.",
        "apihelp-expandtemplates-param-text": "Викитекст за претворање.",
        "apihelp-expandtemplates-param-revid": "Назнака на преработката, за <nowiki>{{REVISIONID}}</nowiki> и слични променливи.",
-       "apihelp-expandtemplates-param-prop": "Кои информации треба да ги добиете:\n\nИмајте на ум дека ако не изберете никаква вредност, резултатот ќе го содржи викитекстот, но изводот ќе биде во застарен формат.",
+       "apihelp-expandtemplates-param-prop": "Кои информации треба да ги добиете:\n\nИмајте на ум дека ако не изберете никаква вредност, исходот ќе го содржи викитекстот, но изводот ќе биде во застарен формат.",
        "apihelp-expandtemplates-paramvalue-prop-wikitext": "Проширениот викитекст.",
        "apihelp-expandtemplates-param-includecomments": "Дали во изводот да се вклучени HTML-коментари.",
        "apihelp-expandtemplates-param-generatexml": "Создај XML-дрво на расчленување (заменето со $1prop=parsetree).",
        "apihelp-feedcontributions-param-deletedonly": "Прикажувај само избришани придонеси.",
        "apihelp-feedcontributions-param-toponly": "Прикажувај само последни преработки.",
        "apihelp-feedcontributions-param-newonly": "Прикажувај само новосоздадени страници",
+       "apihelp-feedcontributions-param-hideminor": "Сокриј ситни уредувања.",
        "apihelp-feedcontributions-param-showsizediff": "Покажувај ја големинската разлика меѓу преработките.",
        "apihelp-feedcontributions-example-simple": "Покажувај придонеси на <kbd>Пример</kbd>.",
        "apihelp-feedrecentchanges-description": "Дава канал со скорешни промени.",
        "apihelp-feedrecentchanges-param-feedformat": "Форматот на каналот.",
-       "apihelp-feedrecentchanges-param-namespace": "Ð\9dа ÐºÐ¾Ñ\98 Ð¸Ð¼ÐµÐ½Ñ\81ки Ð¿Ñ\80оÑ\81Ñ\82оÑ\80 Ð´Ð° Ñ\81е Ð¾Ð³Ñ\80аниÑ\87аÑ\82 Ñ\80езÑ\83лÑ\82аÑ\82иÑ\82е.",
+       "apihelp-feedrecentchanges-param-namespace": "Ð\9dа ÐºÐ¾Ñ\98 Ð¸Ð¼ÐµÐ½Ñ\81ки Ð¿Ñ\80оÑ\81Ñ\82оÑ\80 Ð´Ð° Ñ\81е Ð¾Ð³Ñ\80аниÑ\87и Ð¸Ñ\81Ñ\85одоÑ\82.",
        "apihelp-feedrecentchanges-param-invert": "Сите именски простори освен избраниот.",
        "apihelp-feedrecentchanges-param-associated": "Вклучи придружни именски простори (разговор или главен).",
-       "apihelp-feedrecentchanges-param-days": "Ð\9dа ÐºÐ¾Ð¸ Ð´ÐµÐ½Ð¾Ð²Ð¸ Ð´Ð° Ñ\81е Ð¾Ð³Ñ\80аниÑ\87аÑ\82 Ñ\80езÑ\83лÑ\82аÑ\82ите.",
+       "apihelp-feedrecentchanges-param-days": "Ð\9dа ÐºÐ¾Ð¸ Ð´ÐµÐ½Ð¾Ð²Ð¸ Ð´Ð° Ñ\81е Ð¾Ð³Ñ\80аниÑ\87аÑ\82 Ñ\81Ñ\82авките.",
        "apihelp-feedrecentchanges-param-limit": "Највеќе ставки во исходот за прикажување.",
        "apihelp-feedrecentchanges-param-from": "Прикажи ги промените оттогаш.",
        "apihelp-feedrecentchanges-param-hideminor": "Скриј ги ситните промени.",
        "apihelp-feedrecentchanges-param-hideliu": "Скриј ги промените направени од регистрирани корисници.",
        "apihelp-feedrecentchanges-param-hidepatrolled": "Скриј ги испатролираните промени.",
        "apihelp-feedrecentchanges-param-hidemyself": "Скриј ги промените на тековниот корисник.",
+       "apihelp-feedrecentchanges-param-hidecategorization": "Сокриј префрлања во други категории.",
        "apihelp-feedrecentchanges-param-tagfilter": "Филтрирање по ознака.",
        "apihelp-feedrecentchanges-param-target": "Прикажи само промени на страници што водат од оваа.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Наместо тоа, прикажи ги промените на страниците поврзани со избраната страница.",
+       "apihelp-feedrecentchanges-param-categories": "Прикажи само промени на страниците во сите овие категории.",
+       "apihelp-feedrecentchanges-param-categories_any": "Прикажи само промени на страниците во било која од категориите.",
        "apihelp-feedrecentchanges-example-simple": "Прикажи скорешни промени",
        "apihelp-feedrecentchanges-example-30days": "Прикажувај скорешни промени 30 дена",
        "apihelp-feedwatchlist-description": "Дава канал од набљудуваните.",
        "apihelp-help-param-wrap": "Обвиткај го изводот како станрадна одѕивна структура од прилотот.",
        "apihelp-help-param-toc": "Вклучи табела со содржина во HTML-изводот.",
        "apihelp-help-example-main": "Помош за главниот модул",
+       "apihelp-help-example-submodules": "Помош за <kbd>action=query</kbd> и сите негови подмодули.",
        "apihelp-help-example-recursive": "Сета помош на една страница",
        "apihelp-help-example-help": "Помош за самиот помошен модул",
        "apihelp-help-example-query": "Помош за два подмодула за барања",
        "apihelp-imagerotate-description": "Сврти една или повеќе слики.",
        "apihelp-imagerotate-param-rotation": "За колку степени да се сврти надесно.",
+       "apihelp-imagerotate-param-tags": "Ознаки за примена врз ставката во дневникот на подигања.",
        "apihelp-imagerotate-example-simple": "Сврти ја <kbd>Податотека:Пример.png</kbd> за <kbd>90</kbd> степени.",
        "apihelp-imagerotate-example-generator": "Сврти ги сите слики во <kbd>Категорија:Некоја</kbd> за <kbd>180</kbd> степени.",
        "apihelp-import-description": "Увези страница од друго вики или од XML-податотека.\n\nИмајте на ум дека POST на HTTP мора да се изведе како подигање на податотеката (т.е. користејќи повеќеделни податоци/податоци од образец) кога ја испраќате податотеката за параметарот <var>xml</var>.",
-       "apihelp-import-param-summary": "Увези Ð¾пис.",
+       "apihelp-import-param-summary": "Ð\9eпиÑ\81 Ð½Ð° Ñ\83возоÑ\82 Ð½Ð° Ð´Ð½ÐµÐ²Ð½Ð¸Ñ\87ки Ð·Ð°пис.",
        "apihelp-import-param-xml": "Подигната XML-податотека.",
        "apihelp-import-param-interwikisource": "За меѓујазични увози: од кое вики да се увезе.",
        "apihelp-import-param-interwikipage": "За меѓујазични увози: страница за увоз.",
        "apihelp-move-example-move": "Премести го <kbd>Badtitle</kbd> на <kbd>Goodtitle</kbd>, неоставајќи пренасочување",
        "apihelp-opensearch-description": "Пребарување на викито со протоколот OpenSearch.",
        "apihelp-opensearch-param-search": "Низа за пребарување.",
-       "apihelp-opensearch-param-limit": "Ð\9dаÑ\98веÑ\9cе Ñ\80езÑ\83лÑ\82аÑ\82и за прикажување.",
+       "apihelp-opensearch-param-limit": "Ð\9dаÑ\98веÑ\9cе Ñ\81Ñ\82авки за прикажување.",
        "apihelp-opensearch-param-namespace": "Именски простори за пребарување.",
        "apihelp-opensearch-param-suggest": "Не прави ништо ако <var>[[mw:Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> е неточно.",
-       "apihelp-opensearch-param-redirects": "Ð\9aако Ð´Ð° Ñ\81е Ñ\80абоÑ\82и Ñ\81о Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\9aа:\n;return: Ð\94аÑ\98 Ð³Ð¾ Ñ\81амоÑ\82о Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\9aе.\n;resolve: Ð\94аÑ\98 Ñ\98а Ñ\86елнаÑ\82а Ñ\81Ñ\82Ñ\80аниÑ\86а. Ð\9cоже Ð´Ð° Ð´Ð°Ð´Ðµ Ð¿Ð¾Ð¼Ð°Ð»ÐºÑ\83 Ð¾Ð´ $1limit Ñ\80езÑ\83лÑ\82аÑ\82и.\nОд историски причини, по основно е „return“ за $1format=json и „resolve“ за други формати.",
+       "apihelp-opensearch-param-redirects": "Ð\9aако Ð´Ð° Ñ\81е Ñ\80абоÑ\82и Ñ\81о Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\9aа:\n;return: Ð\94аÑ\98 Ð³Ð¾ Ñ\81амоÑ\82о Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\9aе.\n;resolve: Ð\94аÑ\98 Ñ\98а Ñ\86елнаÑ\82а Ñ\81Ñ\82Ñ\80аниÑ\86а. Ð\9cоже Ð´Ð° Ð´Ð°Ð´Ðµ Ð¿Ð¾Ð¼Ð°Ð»ÐºÑ\83 Ð¾Ð´ $1limit Ñ\81Ñ\82авки.\nОд историски причини, по основно е „return“ за $1format=json и „resolve“ за други формати.",
        "apihelp-opensearch-param-format": "Формат на изводот.",
        "apihelp-opensearch-example-te": "Најди страници што почнуваат со <kbd>Те</kbd>.",
        "apihelp-options-description": "Смени ги нагодувањата на тековниот корисник.\n\nМожат да се зададат само можностите заведени во јадрото или во едно од воспоставените додатоци, или пак можности со клуч кој ја има претставката <code>userjs-</code> (предвиден за употреба од кориснички скрипти).",
        "apihelp-query+revisions-example-first5-user": "Дај ги првите 5 преработки на <kbd>Главна страница</kbd> кои се направени од корисникот „зададен од МедијаВики“ (<kbd>MediaWiki default</kbd>)",
        "apihelp-query+search-example-simple": "Побарај <kbd>meaning</kbd>.",
        "apihelp-query+search-example-text": "Побарај го <kbd>meaning</kbd> по текстовите.",
-       "apihelp-query+search-example-generator": "Дај информации за страниците што излегуваат во резултатите од пребарувањето на <kbd>meaning</kbd>.",
+       "apihelp-query+search-example-generator": "Дај информации за страниците што излегуваат во исходот од пребарувањето на <kbd>meaning</kbd>.",
        "apihelp-query+siteinfo-description": "Дај општи информации за мрежното место.",
        "apihelp-upload-param-filename": "Целно име на податотеката.",
        "apihelp-upload-param-comment": "Коментар при подигање. Се користи и како првичен текст на страницата за нови податотеки ако не е укажано <var>$1text</var>.",
        "apihelp-xml-param-xslt": "Ако е укажано, ја додава именуваната страница како XSL-стилска страница. Вредноста мора да биде наслов во именскиот простор „{{ns:MediaWiki}}“ што ќе завршува со <code>.xsl</code>.",
        "apihelp-xml-param-includexmlnamespace": "Ако е укажано, додава именски простор XML.",
        "apihelp-xmlfm-description": "Давај го изводот во XML-формат (подобрен испис во HTML).",
-       "api-format-title": "РезÑ\83лÑ\82аÑ\82 од Извршникот на МедијаВики",
+       "api-format-title": "Ð\98Ñ\81Ñ\85од од Извршникот на МедијаВики",
        "api-format-prettyprint-header": "Ова е HTML-претстава на форматот $1. HTML е добар за отстранување на грешки, но не е погоден за употреба во извршник.\n\nУкажете го параметарот <var>format</var> за да го смените изводниот формат. За да ги видите претставите на форматот $1 вон HTML, задајте <kbd>format=$2</kbd>.\n\nПовеќе информации ќе најдете на [[mw:API|целосната документација]], или пак [[Special:ApiHelp/main|помош со извршникот]].",
        "api-pageset-param-titles": "Список на наслови на кои ќе се работи",
        "api-pageset-param-pageids": "Список на назнаки за страници на кои ќе се работи",
        "api-help-param-token": "Шифра „$1“ добиена од [[Special:ApiHelp/query+tokens|action=query&meta=tokens]]",
        "api-help-param-token-webui": "За складност, се прифаќа и шифрата што се користи за обичниот кориснички посредник.",
        "api-help-param-disabled-in-miser-mode": "Исклучено поради [[mw:Manual:$wgMiserMode|скржавиот режим]].",
-       "api-help-param-limited-in-miser-mode": "<strong>Напомена:</strong> Бидејќи сте во [[mw:Manual:$wgMiserMode|скржав режим]], користејќи го ова може да добиете помалку од <var>$1limit</var> резултати пред да продолжите; во крајни случаи може да не добиете ниеден резултат.",
+       "api-help-param-limited-in-miser-mode": "<strong>Напомена:</strong> Бидејќи сте во [[mw:Manual:$wgMiserMode|скржав режим]], користејќи го ова може да добиете помалку од <var>$1limit</var> исходни ставки пред да продолжите; во крајни случаи може да не добиете ниедна ставка.",
        "api-help-param-direction": "Во која насока да се набројува:\n;понови:Прво најстарите. Напомена: $1start мора да биде пред $1end.\n;постари:Прво најновите (по основно). Напомена: $1start мора да биде подоцна од $1end.",
        "api-help-param-continue": "Употребете го ова за да продолжите кога има повеќе расположиви ставки.",
        "api-help-param-no-description": "<span class=\"apihelp-empty\">(нема опис)</span>",
index 86ac582..91e3e50 100644 (file)
        "apihelp-query+iwbacklinks-param-limit": "Łączna liczba stron do zwrócenia.",
        "apihelp-query+iwbacklinks-paramvalue-prop-iwprefix": "Dodaje prefiks interwiki.",
        "apihelp-query+iwbacklinks-paramvalue-prop-iwtitle": "Dodaje tytuł interwiki.",
+       "apihelp-query+iwlinks-description": "Wyświetla wszystkie liki interwiki z danych stron.",
        "apihelp-query+iwlinks-paramvalue-prop-url": "Dodaje pełny adres URL.",
        "apihelp-query+iwlinks-param-limit": "Łączna liczba linków interwiki do zwrócenia.",
        "apihelp-query+langbacklinks-param-limit": "Łączna liczba stron do zwrócenia.",
        "apihelp-query+langbacklinks-paramvalue-prop-lllang": "Dodaje kod języka linku językowego.",
        "apihelp-query+langbacklinks-paramvalue-prop-lltitle": "Dodaje tytuł linku językowego.",
        "apihelp-query+langlinks-paramvalue-prop-url": "Dodaje pełny adres URL.",
+       "apihelp-query+links-description": "Zwraca wszystkie linki z danych stron.",
+       "apihelp-query+links-param-namespace": "Pokaż linki tylko w tych przestrzeniach nazw.",
        "apihelp-query+links-param-limit": "Liczba linków do zwrócenia.",
        "apihelp-query+linkshere-description": "Znajdź wszystkie strony, które linkują do danych stron.",
        "apihelp-query+linkshere-paramvalue-prop-title": "Nazwa każdej strony.",
        "apihelp-query+linkshere-param-limit": "Liczba do zwrócenia.",
        "apihelp-query+logevents-description": "Pobierz eventy z logu.",
        "apihelp-query+logevents-example-simple": "Lista ostatnich zarejestrowanych zdarzeń.",
+       "apihelp-query+pagepropnames-param-limit": "Maksymalna liczba zwracanych nazw.",
        "apihelp-query+pageswithprop-param-prop": "Jakie informacje dołączyć:",
        "apihelp-query+pageswithprop-paramvalue-prop-ids": "Doda ID strony.",
+       "apihelp-query+pageswithprop-paramvalue-prop-value": "Dodaje wartość właściwości strony.",
        "apihelp-query+pageswithprop-param-limit": "Maksymalna liczba zwracanych stron.",
        "apihelp-query+pageswithprop-param-dir": "W jakim kierunku sortować.",
        "apihelp-query+pageswithprop-example-generator": "Pobierz dodatkowe informacje o pierwszych 10 stronach wykorzystując <code>_&#95;NOTOC_&#95;</code>.",
        "apihelp-query+tags-paramvalue-prop-active": "Czy znacznik jest nadal stosowany.",
        "apihelp-query+tags-example-simple": "Lista dostęnych tagów.",
        "apihelp-query+templates-description": "Zwraca wszystkie strony osadzone w danych stronach.",
+       "apihelp-query+templates-param-namespace": "Pokaż szablony tylko w tych przestrzeniach nazw.",
        "apihelp-query+templates-param-limit": "Ile szablonów zwrócić?",
        "apihelp-query+transcludedin-paramvalue-prop-title": "Nazwa każdej strony.",
        "apihelp-query+transcludedin-paramvalue-prop-redirect": "Oznacz, jeśli strona jest przekierowaniem.",
        "apihelp-stashedit-param-title": "Tytuł edytowanej strony.",
        "apihelp-stashedit-param-sectiontitle": "Tytuł nowej sekcji.",
        "apihelp-stashedit-param-text": "Zawartość strony.",
+       "apihelp-stashedit-param-summary": "Opis zmian.",
        "apihelp-tag-param-reason": "Powód zmiany.",
        "apihelp-unblock-description": "Odblokuj użytkownika.",
        "apihelp-unblock-param-user": "Nazwa użytkownika, adres IP albo zakres adresów IP, które chcesz odblokować. Nie można używać jednocześnie z <var>$1id</var> lub <var>$1userid</var>.",
        "apierror-integeroutofrange-belowminimum": "Wartość <var>$1</var> nie może być mniejsza niż $2 (ustawiono $3).",
        "apierror-invalidcategory": "Wprowadzona nazwa kategorii jest nieprawidłowa.",
        "apierror-invalidlang": "Nieprawidłowy kod języka dla parametru <var>$1</var>.",
+       "apierror-invalidoldimage": "Parametr <var>oldimage</var> ma nieprawidłowy format.",
        "apierror-invalidparammix": "{{PLURAL:$2|Parametry}} $1 nie mogą być używane razem.",
        "apierror-invalidtitle": "Zły tytuł „$1”.",
        "apierror-invalidurlparam": "Nieprawidłowa wartość <var>$1urlparam</var> (<kbd>$2=$3</kbd>).",
index b00e30b..cb5997b 100644 (file)
        "apihelp-query+siteinfo-paramvalue-prop-rightsinfo": "Devolve informação sobre os direitos (a licença) da wiki, se disponível.",
        "apihelp-query+siteinfo-paramvalue-prop-restrictions": "Devolve informação sobre os tipos de restrição (proteção) disponíveis.",
        "apihelp-query+siteinfo-paramvalue-prop-languages": "Devolve uma lista das línguas que o MediaWiki suporta (opcionalmente localizada, usando <var>$1inlanguagecode</var>).",
+       "apihelp-query+siteinfo-paramvalue-prop-languagevariants": "Devolve uma lista dos códigos de língua para os quais o [[mw:LanguageConverter|LanguageConverter]] está ativado, e as variantes suportadas para cada código.",
        "apihelp-query+siteinfo-paramvalue-prop-skins": "Devolve uma lista de todos os temas ativados (opcionalmente localizada, usando <var>$1inlanguagecode</var>, ou então na língua do conteúdo).",
        "apihelp-query+siteinfo-paramvalue-prop-extensiontags": "Devolve uma lista dos elementos de extensões do analisador sintático.",
        "apihelp-query+siteinfo-paramvalue-prop-functionhooks": "Devolve uma lista dos ''hooks'' de funções do analisador sintático.",
        "apihelp-upload-param-checkstatus": "Obter só o estado de carregamento para a chave de ficheiro indicada.",
        "apihelp-upload-example-url": "Carregar de um URL.",
        "apihelp-upload-example-filekey": "Prosseguir um carregamento que falhou devido a avisos.",
-       "apihelp-userrights-description": "Alterar os membros de um grupo de utilizadores.",
+       "apihelp-userrights-description": "Alterar os grupos a que um utilizador pertence.",
        "apihelp-userrights-param-user": "O nome de utilizador.",
        "apihelp-userrights-param-userid": "O identificador de utilizador.",
        "apihelp-userrights-param-add": "Adicionar o utilizador a estes grupos ou, se já for membro de um grupo, atualizar a data de expiração da sua pertença a esse grupo.",
index d4380c2..cca3a3c 100644 (file)
        "apihelp-query+siteinfo-paramvalue-prop-rightsinfo": "{{doc-apihelp-paramvalue|query+siteinfo|prop|rightsinfo}}",
        "apihelp-query+siteinfo-paramvalue-prop-restrictions": "{{doc-apihelp-paramvalue|query+siteinfo|prop|restrictions}}",
        "apihelp-query+siteinfo-paramvalue-prop-languages": "{{doc-apihelp-paramvalue|query+siteinfo|prop|languages}}",
+       "apihelp-query+siteinfo-paramvalue-prop-languagevariants": "{{doc-apihelp-paramvalue|query+siteinfo|prop|languagevariants}}",
        "apihelp-query+siteinfo-paramvalue-prop-skins": "{{doc-apihelp-paramvalue|query+siteinfo|prop|skins}}",
        "apihelp-query+siteinfo-paramvalue-prop-extensiontags": "{{doc-apihelp-paramvalue|query+siteinfo|prop|extensiontags}}",
        "apihelp-query+siteinfo-paramvalue-prop-functionhooks": "{{doc-apihelp-paramvalue|query+siteinfo|prop|functionhooks}}",
index 5498449..1396458 100644 (file)
        "api-help-param-multi-separate": "Separera värden med <kbd>|</kbd> eller [[Special:ApiHelp/main#main/datatypes|alternativ]].",
        "apierror-articleexists": "Artikeln du försökte skapa har redan skapats.",
        "apierror-baddiff": "Diff kan inte hämtas. En eller båda sidversioner finns inte eller du har inte behörighet för att visa dem.",
+       "apierror-invalidsection": "Parametern <var>section</var> måste vara ett giltigt avsnitts-ID eller <kbd>new</kbd>.",
        "apierror-nosuchuserid": "Det finns ingen användare med ID $1.",
        "apierror-protect-invalidaction": "Ogiltig skyddstyp \"$1\".",
        "apierror-systemblocked": "Du har blockerats automatiskt av MediaWiki.",
index c4809aa..731a9c0 100644 (file)
        "apihelp-query+siteinfo-paramvalue-prop-rightsinfo": "当可用时返回wiki的版权(许可协议)信息。",
        "apihelp-query+siteinfo-paramvalue-prop-restrictions": "返回可用的编辑限制(保护)类型信息。",
        "apihelp-query+siteinfo-paramvalue-prop-languages": "返回MediaWiki支持的语言列表(可选择使用<var>$1inlanguagecode</var>本地化)。",
+       "apihelp-query+siteinfo-paramvalue-prop-languagevariants": "当启用了[[mw:LanguageConverter|语言转换器]],并且每个语言变体都受支持时,返回语言代码列表。",
        "apihelp-query+siteinfo-paramvalue-prop-skins": "返回所有启用的皮肤列表(可选择使用<var>$1inlanguagecode</var>本地化,否则是内容语言)。",
        "apihelp-query+siteinfo-paramvalue-prop-extensiontags": "返回解析器扩展标签列表。",
        "apihelp-query+siteinfo-paramvalue-prop-functionhooks": "返回解析器函数钩列表。",
        "apierror-invalidexpiry": "无效的过期时间“$1”。",
        "apierror-invalid-file-key": "不是有效的文件关键词。",
        "apierror-invalidlang": "用于参数<var>$1</var>的语言值无效。",
-       "apierror-invalidoldimage": "旧图片参数有无效格式。",
+       "apierror-invalidoldimage": "<var>oldimage</var>参数有无效格式。",
        "apierror-invalidparammix-cannotusewith": "<kbd>$1</kbd>参数不能与<kbd>$2</kbd>一起使用。",
        "apierror-invalidparammix-mustusewith": "<kbd>$1</kbd>参数只能与<kbd>$2</kbd>一起使用。",
        "apierror-invalidparammix-parse-new-section": "<kbd>section=new</kbd>不能连同<var>oldid</var>、<var>pageid</var>或<var>page</var>参数使用。请使用<var>title</var>和<var>text</var>。",
        "apierror-invalidparammix": "{{PLURAL:$2|参数}}$1不能一起使用。",
-       "apierror-invalidsection": "章节参数必须为有效的章节ID或<kbd>new</kbd>。",
+       "apierror-invalidsection": "<var>section</var>参数必须为有效的章节ID或<kbd>new</kbd>。",
        "apierror-invalidsha1base36hash": "提供的SHA1Base36哈希无效。",
        "apierror-invalidsha1hash": "提供的SHA1哈希无效。",
        "apierror-invalidtitle": "错误标题“$1”。",
index 2415721..6f2bcd6 100644 (file)
@@ -9,7 +9,8 @@
                        "Macofe",
                        "Jasonzhuocn",
                        "Winstonyin",
-                       "Arthur2e5"
+                       "Arthur2e5",
+                       "烈羽"
                ]
        },
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|說明文件]]\n* [[mw:API:FAQ|常見問題]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api 郵寄清單]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API公告]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R 報告錯誤及請求功能]\n</div>\n<strong>狀態資訊:</strong>本頁所展示的所有功能都應正常工作,但是API仍在開發當中,將會隨時變化。請訂閱[https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mediawiki-api-announce 郵件清單]以便得到更新通知。\n\n<strong>錯誤的請求:</strong>當API收到錯誤的請求時,會發出以「MediaWiki-API-Error」為鍵的HTTP頭欄位,隨後頭欄位的值與錯誤碼將會被設為相同的值。詳細資訊請參閱[[mw:API:Errors_and_warnings|API: 錯誤與警告]]。\n\n<strong>測試:</strong>要簡化API請求的測試過程,請見[[Special:ApiSandbox]]。",
        "apihelp-expandtemplates-param-text": "要轉換的 Wikitext。",
        "apihelp-feedcontributions-description": "回傳使用者貢獻 Feed。",
        "apihelp-feedcontributions-param-feedformat": "Feed 的格式。",
+       "apihelp-feedcontributions-param-hideminor": "隱藏小修改。",
        "apihelp-feedcontributions-param-showsizediff": "顯示修訂版本之間的差異大小。",
        "apihelp-feedcontributions-example-simple": "返回使用者<kbd>Example</kbd>的貢獻。",
        "apihelp-feedrecentchanges-description": "返回最近變更摘要。",
index 9e6cf1e..0a07a93 100644 (file)
@@ -26,6 +26,9 @@
  * @copyright © 2011, Antoine Musso
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\FakeResultWrapper;
+
 /**
  * Class for fetching backlink lists, approximate backlink counts and
  * partitions. This is a shared cache.
@@ -407,7 +410,7 @@ class BacklinkCache {
 
                // 4) ... finally fetch from the slow database :(
                $cacheEntry = [ 'numRows' => 0, 'batches' => [] ]; // final result
-               // Do the selects in batches to avoid client-side OOMs (bug 43452).
+               // Do the selects in batches to avoid client-side OOMs (T45452).
                // Use a LIMIT that plays well with $batchSize to keep equal sized partitions.
                $selectSize = max( $batchSize, 200000 - ( 200000 % $batchSize ) );
                $start = false;
index d773fff..77ab2d5 100644 (file)
@@ -22,6 +22,7 @@
  */
 use MediaWiki\Linker\LinkTarget;
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\ResultWrapper;
 
 /**
  * Class representing a list of titles
index 90ad241..5d48c03 100644 (file)
@@ -110,9 +110,6 @@ class MessageBlobStore implements LoggerAwareInterface {
                foreach ( $modules as $name => $module ) {
                        $key = $cacheKeys[$name];
                        if ( !isset( $result[$key] ) || $curTTLs[$key] === null || $curTTLs[$key] < 0 ) {
-                               $this->logger->info( 'Message blob cache-miss for {module}',
-                                       [ 'module' => $name, 'cacheKey' => $key ]
-                               );
                                $blobs[$name] = $this->recacheMessageBlob( $key, $module, $lang );
                        } else {
                                // Use unexpired cache
index 15a00c7..cffb59a 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * Feed to Special:RecentChanges and Special:RecentChangesLiked
  *
@@ -152,7 +154,7 @@ class ChangesFeed {
                        if ( $feedAge < $wgFeedCacheTimeout || $feedLastmodUnix > $lastmodUnix ) {
                                wfDebug( "RC: loading feed from cache ($key; $feedLastmod; $lastmod)...\n" );
                                if ( $feedLastmodUnix < $lastmodUnix ) {
-                                       $wgOut->setLastModified( $feedLastmod ); // bug 21916
+                                       $wgOut->setLastModified( $feedLastmod ); // T23916
                                }
                                return $cache->get( $key );
                        } else {
index bc7d721..3f4ad14 100644 (file)
@@ -23,6 +23,7 @@
  */
 use MediaWiki\Linker\LinkRenderer;
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\ResultWrapper;
 
 class ChangesList extends ContextSource {
        /**
index 3c76f32..3aad60e 100644 (file)
@@ -177,7 +177,6 @@ class EnhancedChangesList extends ChangesList {
                        && $block[0]->mAttribs['rc_timestamp'] >= $block[0]->watched
                ) {
                        $tableClasses[] = 'mw-changeslist-line-watched';
-                       $tableClasses = array_merge( $tableClasses, $this->getHTMLClassesForFilters( $block[0] ) );
                } else {
                        $tableClasses[] = 'mw-changeslist-line-not-watched';
                }
@@ -367,7 +366,7 @@ class EnhancedChangesList extends ChangesList {
                if ( $rcObj->watched
                        && $rcObj->mAttribs['rc_timestamp'] >= $rcObj->watched
                ) {
-                       $classes[] = [ 'mw-enhanced-watched' ];
+                       $classes[] = 'mw-enhanced-watched';
                }
                $classes = array_merge( $classes, $this->getHTMLClassesForFilters( $rcObj ) );
 
@@ -532,7 +531,7 @@ class EnhancedChangesList extends ChangesList {
                                $links['total-changes'] = $this->linkRenderer->makeKnownLink(
                                        $block0->getTitle(),
                                        new HtmlArmor( $nchanges[$n] ),
-                                       [],
+                                       [ 'class' => 'mw-changeslist-groupdiff' ],
                                        $queryParams + [
                                                'diff' => $currentRevision,
                                                'oldid' => $last->mAttribs['rc_last_oldid'],
@@ -542,7 +541,7 @@ class EnhancedChangesList extends ChangesList {
                                        $links['total-changes-since-last'] = $this->linkRenderer->makeKnownLink(
                                                        $block0->getTitle(),
                                                        new HtmlArmor( $sinceLastVisitMsg[$sinceLast] ),
-                                                       [],
+                                                       [ 'class' => 'mw-changeslist-groupdiff' ],
                                                        $queryParams + [
                                                                'diff' => $currentRevision,
                                                                'oldid' => $unvisitedOldid,
@@ -564,7 +563,7 @@ class EnhancedChangesList extends ChangesList {
                        $links['history'] = $this->linkRenderer->makeKnownLink(
                                        $block0->getTitle(),
                                        new HtmlArmor( $this->message['enhancedrc-history'] ),
-                                       [],
+                                       [ 'class' => 'mw-changeslist-history' ],
                                        $params
                                );
                }
@@ -719,7 +718,7 @@ class EnhancedChangesList extends ChangesList {
                                        . $this->linkRenderer->makeKnownLink(
                                                $pageTitle,
                                                new HtmlArmor( $this->message['hist'] ),
-                                               [],
+                                               [ 'class' => 'mw-changeslist-history' ],
                                                $query
                                        ) )->escaped();
                return $retVal;
index d862ef4..a5d5191 100644 (file)
@@ -34,7 +34,7 @@ class OldChangesList extends ChangesList {
        public function recentChangesLine( &$rc, $watched = false, $linenumber = null ) {
 
                $classes = $this->getHTMLClasses( $rc, $watched );
-               // use mw-line-even/mw-line-odd class only if linenumber is given (feature from bug 14468)
+               // use mw-line-even/mw-line-odd class only if linenumber is given (feature from T16468)
                if ( $linenumber ) {
                        if ( $linenumber & 1 ) {
                                $classes[] = 'mw-line-odd';
index 2c5c8b1..8ce21f5 100644 (file)
@@ -186,7 +186,7 @@ class RCCacheEntryFactory {
                        $curLink = $curMessage;
                } else {
                        $curUrl = htmlspecialchars( $cacheEntry->getTitle()->getLinkURL( $queryParams ) );
-                       $curLink = "<a href=\"$curUrl\">$curMessage</a>";
+                       $curLink = "<a class=\"mw-changeslist-diff-cur\" href=\"$curUrl\">$curMessage</a>";
                }
 
                return $curLink;
@@ -229,16 +229,18 @@ class RCCacheEntryFactory {
                                return $diffMessage;
                        }
                        $diffUrl = htmlspecialchars( $pageTitle->getLinkURL( $queryParams ) );
-                       $diffLink = "<a href=\"$diffUrl\">$diffMessage</a>";
+                       $diffLink = "<a class=\"mw-changeslist-diff\" href=\"$diffUrl\">$diffMessage</a>";
                } else {
                        $diffUrl = htmlspecialchars( $cacheEntry->getTitle()->getLinkURL( $queryParams ) );
-                       $diffLink = "<a href=\"$diffUrl\">$diffMessage</a>";
+                       $diffLink = "<a class=\"mw-changeslist-diff\" href=\"$diffUrl\">$diffMessage</a>";
                }
 
                return $diffLink;
        }
 
        /**
+        * Builds the link to the previous version
+        *
         * @param RecentChange $cacheEntry
         * @param bool $showDiffLinks
         *
@@ -257,7 +259,7 @@ class RCCacheEntryFactory {
                        $lastLink = $this->linkRenderer->makeKnownLink(
                                $cacheEntry->getTitle(),
                                new HtmlArmor( $lastMessage ),
-                               [],
+                               [ 'class' => 'mw-changeslist-diff' ],
                                $this->buildDiffQueryParams( $cacheEntry )
                        );
                }
index 5dc9fa2..ca7b765 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 /**
- * Workaround for incorrect collation of Estonian language ('et') in ICU (bug 54168).
+ * Workaround for incorrect collation of Estonian language ('et') in ICU (T56168).
  *
  * 'W' and 'V' should not be considered the same letter for the purposes of collation in modern
  * Estonian. We work around this by replacing 'W' and 'w' with 'ᴡ' U+1D21 'LATIN LETTER SMALL
index bc5a209..bf1fe74 100644 (file)
@@ -513,8 +513,12 @@ 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 bug 54561).
-        * This function will return false on older PHPs.
+        * 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.
         *
         * @since 1.21
         * @return string|bool
diff --git a/includes/compat/Timestamp.php b/includes/compat/Timestamp.php
new file mode 100644 (file)
index 0000000..bd25432
--- /dev/null
@@ -0,0 +1,18 @@
+<?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 string concatenation for the alias to avoid being seen by ClassCollector,
+// which would insist on adding 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, 'Timestamp' . 'Exception' );
index 58665bb..bccb147 100644 (file)
@@ -899,7 +899,7 @@ abstract class ContentHandler {
                        $onlyAuthor = $row->rev_user_text;
                        // Try to find a second contributor
                        foreach ( $res as $row ) {
-                               if ( $row->rev_user_text != $onlyAuthor ) { // Bug 22999
+                               if ( $row->rev_user_text != $onlyAuthor ) { // T24999
                                        $onlyAuthor = false;
                                        break;
                                }
@@ -1157,8 +1157,11 @@ abstract class ContentHandler {
         * @return array Map of name=>value for fields
         * @since 1.28
         */
-       public function getDataForSearchIndex( WikiPage $page, ParserOutput $output,
-                                              SearchEngine $engine ) {
+       public function getDataForSearchIndex(
+               WikiPage $page,
+               ParserOutput $output,
+               SearchEngine $engine
+       ) {
                $fieldData = [];
                $content = $page->getContent();
 
index 26f1190..843d540 100644 (file)
@@ -30,8 +30,11 @@ class FileContentHandler extends WikitextContentHandler  {
                return $fields;
        }
 
-       public function getDataForSearchIndex( WikiPage $page, ParserOutput $parserOutput,
-                                              SearchEngine $engine ) {
+       public function getDataForSearchIndex(
+               WikiPage $page,
+               ParserOutput $parserOutput,
+               SearchEngine $engine
+       ) {
                $fields = [];
 
                $title = $page->getTitle();
index 09cdcee..698a37b 100644 (file)
@@ -30,7 +30,7 @@
  */
 class TextContentHandler extends ContentHandler {
 
-       // @codingStandardsIgnoreStart bug 57585
+       // @codingStandardsIgnoreStart T59585
        public function __construct( $modelId = CONTENT_MODEL_TEXT, $formats = [ CONTENT_FORMAT_TEXT ] ) {
                parent::__construct( $modelId, $formats );
        }
@@ -150,8 +150,11 @@ class TextContentHandler extends ContentHandler {
                return $fields;
        }
 
-       public function getDataForSearchIndex( WikiPage $page, ParserOutput $output,
-                                              SearchEngine $engine ) {
+       public function getDataForSearchIndex(
+               WikiPage $page,
+               ParserOutput $output,
+               SearchEngine $engine
+       ) {
                $fields = parent::getDataForSearchIndex( $page, $output, $engine );
                $fields['language'] =
                        $this->getPageLanguage( $page->getTitle(), $page->getContent() )->getCode();
index f4a6dc6..9f79aa8 100644 (file)
@@ -27,26 +27,32 @@ class WikiTextStructure {
         * @var string[] selectors to elements that are excluded entirely from search
         */
        private $excludedElementSelectors = [
-               'audio', 'video',       // "it looks like you don't have javascript enabled..."
-                                       // do not need to index
-               'sup.reference',        // The [1] for references
-               '.mw-cite-backlink',    // The ↑ next to references in the references section
-               'h1', 'h2', 'h3',       // Headings are already indexed in their own field.
-               'h5', 'h6', 'h4',
-               '.autocollapse',        // Collapsed fields are hidden by default so we don't want them
-                                                               // showing up.
+               // "it looks like you don't have javascript enabled..." – do not need to index
+               'audio', 'video',
+               // The [1] for references
+               'sup.reference',
+               // The ↑ next to references in the references section
+               '.mw-cite-backlink',
+               // Headings are already indexed in their own field.
+               'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
+               // Collapsed fields are hidden by default so we don't want them showing up.
+               '.autocollapse',
        ];
 
        /**
         * @var string[] selectors to elements that are considered auxiliary to article text for search
         */
        private $auxiliaryElementSelectors = [
-               '.thumbcaption',        // Thumbnail captions aren't really part of the text proper
-               'table',                // Neither are tables
-               '.rellink',             // Common style for "See also:".
-               '.dablink',             // Common style for calling out helpful links at the top
-                                                               // of the article.
-               '.searchaux',           // New class users can use to mark stuff as auxiliary to searches.
+               // Thumbnail captions aren't really part of the text proper
+               '.thumbcaption',
+               // Neither are tables
+               'table',
+               // Common style for "See also:".
+               '.rellink',
+               // Common style for calling out helpful links at the top of the article.
+               '.dablink',
+               // New class users can use to mark stuff as auxiliary to searches.
+               '.searchaux',
        ];
 
        /**
index 74b2f1a..9c26ae1 100644 (file)
@@ -128,16 +128,20 @@ class WikitextContentHandler extends TextContentHandler {
 
                $fields['opening_text'] =
                        $engine->makeSearchFieldMapping( 'opening_text', SearchIndexField::INDEX_TYPE_TEXT );
-               $fields['opening_text']->setFlag( SearchIndexField::FLAG_SCORING |
-                                                 SearchIndexField::FLAG_NO_HIGHLIGHT );
+               $fields['opening_text']->setFlag(
+                       SearchIndexField::FLAG_SCORING | SearchIndexField::FLAG_NO_HIGHLIGHT
+               );
                // Until we have full first-class content handler for files, we invoke it explicitly here
                $fields = array_merge( $fields, $this->getFileHandler()->getFieldsForSearchIndex( $engine ) );
 
                return $fields;
        }
 
-       public function getDataForSearchIndex( WikiPage $page, ParserOutput $parserOutput,
-                                              SearchEngine $engine ) {
+       public function getDataForSearchIndex(
+               WikiPage $page,
+               ParserOutput $parserOutput,
+               SearchEngine $engine
+       ) {
                $fields = parent::getDataForSearchIndex( $page, $parserOutput, $engine );
 
                $structure = new WikiTextStructure( $parserOutput );
index ecd274b..3dfa456 100644 (file)
@@ -428,7 +428,7 @@ class RequestContext implements IContextSource, MutableContext {
                                }
 
                                // Normalize the key in case the user is passing gibberish
-                               // or has old preferences (bug 69566).
+                               // or has old preferences (T71566).
                                $normalized = Skin::normalizeKey( $userSkin );
 
                                // Skin::normalizeKey will also validate it, so
index 2b394b6..c4921e2 100644 (file)
@@ -79,7 +79,7 @@ class CloneDatabase {
                foreach ( $this->tablesToClone as $tbl ) {
                        if ( $wgSharedDB && in_array( $tbl, $wgSharedTables, true ) ) {
                                // Shared tables don't work properly when cloning due to
-                               // how prefixes are handled (bug 65654)
+                               // how prefixes are handled (T67654)
                                throw new RuntimeException( "Cannot clone shared table $tbl." );
                        }
                        # Clean up from previous aborted run.  So that table escaping
index 344aa3d..ef5a8fe 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup Database
  */
 use Wikimedia\Rdbms\Blob;
+use Wikimedia\Rdbms\ResultWrapper;
 
 /**
  * @ingroup Database
index 87656f2..e67a0b3 100644 (file)
@@ -370,7 +370,7 @@ class MWDebug {
                                | [\xF0-\xF4](?![\x80-\xBF]{3}) # Invalid UTF-8 Sequence Start
                                | (?<=[\x0-\x7F\xF5-\xFF])[\x80-\xBF] # Invalid UTF-8 Sequence Middle
                                | (?<![\xC2-\xDF]|[\xE0-\xEF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4]
-                                  |[\xF0-\xF4][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF]{2})[\x80-\xBF] # Overlong Sequence
+                                       | [\xF0-\xF4][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF]{2})[\x80-\xBF] # Overlong Sequence
                                | (?<=[\xE0-\xEF])[\x80-\xBF](?![\x80-\xBF]) # Short 3 byte sequence
                                | (?<=[\xF0-\xF4])[\x80-\xBF](?![\x80-\xBF]{2}) # Short 4 byte sequence
                                | (?<=[\xF0-\xF4][\x80-\xBF])[\x80-\xBF](?![\x80-\xBF]) # Short 4 byte sequence (2)
index 432a9e1..6670fe9 100644 (file)
@@ -33,12 +33,12 @@ use Psr\Log\LoggerInterface;
  *
  * Constructor options array arguments:
  * * alias: map from monolog channel to kafka topic name. When no
- *       alias exists the topic "monolog_$channel" will be used.
+ *   alias exists the topic "monolog_$channel" will be used.
  * * swallowExceptions: Swallow exceptions that occur while talking to
- *    kafka. Defaults to false.
+ *   kafka. Defaults to false.
  * * logExceptions: Log exceptions talking to kafka here. Either null,
- *    the name of a channel to log to, or an object implementing
- *    FormatterInterface. Defaults to null.
+ *   the name of a channel to log to, or an object implementing
+ *   FormatterInterface. Defaults to null.
  *
  * Requires the nmred/kafka-php library, version >= 1.3.0
  *
index 000b526..0a9755d 100644 (file)
@@ -336,6 +336,21 @@ class DeferredUpdates {
                return count( self::$preSendUpdates ) + count( self::$postSendUpdates );
        }
 
+       /**
+        * @param integer $stage DeferredUpdates constant (PRESEND, POSTSEND, or ALL)
+        * @since 1.29
+        */
+       public static function getPendingUpdates( $stage = self::ALL ) {
+               $updates = [];
+               if ( $stage === self::ALL || $stage === self::PRESEND ) {
+                       $updates = array_merge( $updates, self::$preSendUpdates );
+               }
+               if ( $stage === self::ALL || $stage === self::POSTSEND ) {
+                       $updates = array_merge( $updates, self::$postSendUpdates );
+               }
+               return $updates;
+       }
+
        /**
         * Clear all pending updates without performing them. Generally, you don't
         * want or need to call this. Unit tests need it though.
index 464c908..0133f19 100644 (file)
@@ -145,7 +145,7 @@ class LinksUpdate extends DataUpdate implements EnqueueableDataUpdate {
                        # If the sortkey is longer then 255 bytes,
                        # it truncated by DB, and then doesn't get
                        # matched when comparing existing vs current
-                       # categories, causing bug 25254.
+                       # categories, causing T27254.
                        # Also. substr behaves weird when given "".
                        if ( $sortkey !== '' ) {
                                $sortkey = substr( $sortkey, 0, 255 );
index 5367199..148e50c 100644 (file)
@@ -82,7 +82,7 @@ class DifferenceEngine extends ContextSource {
        /**
         * Set this to true to add debug info to the HTML output.
         * Warning: this may cause RSS readers to spuriously mark articles as "new"
-        * (bug 20601)
+        * (T22601)
         */
        public $enableDebugComment = false;
 
index a26775f..ad80275 100644 (file)
@@ -46,11 +46,9 @@ class WordAccumulator {
        private function flushGroup( $new_tag ) {
                if ( $this->group !== '' ) {
                        if ( $this->tag == 'ins' ) {
-                               $this->line .= "<ins{$this->insClass}>" .
-                                                          htmlspecialchars( $this->group ) . '</ins>';
+                               $this->line .= "<ins{$this->insClass}>" . htmlspecialchars( $this->group ) . '</ins>';
                        } elseif ( $this->tag == 'del' ) {
-                               $this->line .= "<del{$this->delClass}>" .
-                                                          htmlspecialchars( $this->group ) . '</del>';
+                               $this->line .= "<del{$this->delClass}>" . htmlspecialchars( $this->group ) . '</del>';
                        } else {
                                $this->line .= htmlspecialchars( $this->group );
                        }
index 9b5a268..2bed87a 100644 (file)
@@ -39,7 +39,7 @@ class ErrorPageError extends MWException implements ILocalizedException {
                $this->msg = $msg;
                $this->params = $params;
 
-               // Bug 44111: Messages in the log files should be in English and not
+               // T46111: Messages in the log files should be in English and not
                // customized by the local wiki. So get the default English version for
                // passing to the parent constructor. Our overridden report() below
                // makes sure that the page shown to the user is not forced to English.
index 44ab0e4..749be3c 100644 (file)
@@ -342,7 +342,7 @@ TXT;
                                $text .= "{$pad}#{$level} {$frame['file']}({$frame['line']}): ";
                        } else {
                                // 'file' and 'line' are unset for calls via call_user_func
-                               // (bug 55634) This matches behaviour of
+                               // (T57634) This matches behaviour of
                                // Exception::getTraceAsString to instead display "[internal
                                // function]".
                                $text .= "{$pad}#{$level} [internal function]: ";
index 43c5b09..6086d55 100644 (file)
@@ -32,7 +32,7 @@
  * @par Example:
  * @code
  * if( $user->isAnon() ) {
- *     throw new UserNotLoggedIn();
+ *   throw new UserNotLoggedIn();
  * }
  * @endcode
  *
  * @par Example:
  * @code
  * if( $user->isAnon() ) {
- *     throw new UserNotLoggedIn( 'action-require-loggedin' );
+ *   throw new UserNotLoggedIn( 'action-require-loggedin' );
  * }
  * @endcode
  *
- * @see bug 37627
+ * @see T39627
  * @since 1.20
  * @ingroup Exception
  */
index c1f2d59..e41ab54 100644 (file)
@@ -27,6 +27,8 @@
  * @defgroup Dump Dump
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * @ingroup SpecialPage Dump
  */
@@ -343,7 +345,7 @@ class WikiExporter {
                                # query optimization for history stub dumps
                                if ( $this->text == WikiExporter::STUB && $orderRevs ) {
                                        $tables = [ 'revision', 'page' ];
-                                       $opts[] = 'STRAIGHT_JOIN';
+                                       $opts[] = 'STRAIGHT_JOIN';
                                        $opts['ORDER BY'] = [ 'rev_page ASC', 'rev_id ASC' ];
                                        $opts['USE INDEX']['revision'] = 'rev_page_id';
                                        $join['page'] = [ 'INNER JOIN', 'rev_page=page_id' ];
index 0e4b2f0..8edf81f 100644 (file)
@@ -1448,7 +1448,7 @@ class FileRepo {
                                'dst' => $archivePath,
                                // We may have 2+ identical files being deleted,
                                // all of which will map to the same destination file
-                               'overwriteSame' => true // also see bug 31792
+                               'overwriteSame' => true // also see T33792
                        ];
                }
 
index d49ae7b..d5e29ab 100644 (file)
@@ -22,6 +22,8 @@
  * @ingroup FileRepo
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * A repository that stores files in the local filesystem and registers them
  * in the wiki's own database. This is the most commonly used repository class.
index be78462..3b873ea 100644 (file)
@@ -919,7 +919,7 @@ abstract class File implements IDBAccessObject {
                        return $this->iconThumb();
                }
                $hp['width'] = $width;
-               // be sure to ignore any height specification as well (bug 62258)
+               // be sure to ignore any height specification as well (T64258)
                unset( $hp['height'] );
 
                return $this->transform( $hp );
@@ -1039,7 +1039,7 @@ abstract class File implements IDBAccessObject {
                                break; // not a bitmap or renderable image, don't try
                        }
 
-                       // Get the descriptionUrl to embed it as comment into the thumbnail. Bug 19791.
+                       // Get the descriptionUrl to embed it as comment into the thumbnail. T21791.
                        $descriptionUrl = $this->getDescriptionUrl();
                        if ( $descriptionUrl ) {
                                $params['descriptionUrl'] = wfExpandUrl( $descriptionUrl, PROTO_CANONICAL );
index 8c088b9..a1cb0a2 100644 (file)
@@ -891,7 +891,7 @@ class LocalFile extends File {
                                $files[] = $file;
                        }
                } catch ( FileBackendError $e ) {
-               } // suppress (bug 54674)
+               } // suppress (T56674)
 
                return $files;
        }
@@ -1353,7 +1353,7 @@ class LocalFile extends File {
                                }
                        }
 
-                       # (bug 34993) Note: $oldver can be empty here, if the previous
+                       # (T36993) Note: $oldver can be empty here, if the previous
                        # version of the file was broken. Allow registration of the new
                        # version to continue anyway, because that's better than having
                        # an image that's not fixable by user operations.
@@ -2007,7 +2007,7 @@ class LocalFile extends File {
                        $dbw = $this->repo->getMasterDB();
                        $makesTransaction = !$dbw->trxLevel();
                        $dbw->startAtomic( self::ATOMIC_SECTION_LOCK );
-                       // Bug 54736: use simple lock to handle when the file does not exist.
+                       // T56736: use simple lock to handle when the file does not exist.
                        // SELECT FOR UPDATE prevents changes, not other SELECTs with FOR UPDATE.
                        // Also, that would cause contention on INSERT of similarly named rows.
                        $status = $this->acquireFileLock(); // represents all versions of the file
@@ -3035,7 +3035,7 @@ class LocalFileMoveBatch {
                        $status->failCount++;
                }
                $status->successCount += $oldRowCount;
-               // Bug 34934: oldCount is based on files that actually exist.
+               // T36934: oldCount is based on files that actually exist.
                // There may be more DB rows than such files, in which case $affected
                // can be greater than $total. We use max() to avoid negatives here.
                $status->failCount += max( 0, $this->oldCount - $oldRowCount );
index 179f6af..399147b 100644 (file)
@@ -1259,7 +1259,7 @@ class HTMLForm extends ContextSource {
         *
         * @param string|array|Status $elements The set of errors/warnings to process.
         * @param string $elementsType Should warnings or errors be returned.  This is meant
-        *      for Status objects, all other valid types are always considered as errors.
+        *     for Status objects, all other valid types are always considered as errors.
         * @return string
         */
        public function getErrorsOrWarnings( $elements, $elementsType ) {
index 779d606..fa2d5a3 100644 (file)
@@ -46,8 +46,8 @@ class Http {
         *    - caInfo              Provide CA information
         *    - maxRedirects        Maximum number of redirects to follow (defaults to 5)
         *    - followRedirects     Whether to follow redirects (defaults to false).
-        *                                  Note: this should only be used when the target URL is trusted,
-        *                                  to avoid attacks on intranet services accessible by HTTP.
+        *                          Note: this should only be used when the target URL is trusted,
+        *                          to avoid attacks on intranet services accessible by HTTP.
         *    - userAgent           A user agent, if you want to override the default
         *                          MediaWiki/$wgVersion
         *    - logger              A \Psr\Logger\LoggerInterface instance for debug logging
index fac052f..e04402f 100644 (file)
@@ -132,7 +132,7 @@ class MWHttpRequest implements LoggerAwareInterface {
                foreach ( $members as $o ) {
                        if ( isset( $options[$o] ) ) {
                                // ensure that MWHttpRequest::method is always
-                               // uppercased. Bug 36137
+                               // uppercased. T38137
                                if ( $o == 'method' ) {
                                        $options[$o] = strtoupper( $options[$o] );
                                }
@@ -580,7 +580,7 @@ class MWHttpRequest implements LoggerAwareInterface {
         *
         * Note that the multiple Location: headers are an artifact of
         * CURL -- they shouldn't actually get returned this way. Rewrite
-        * this when bug 29232 is taken care of (high-level redirect
+        * this when T31232 is taken care of (high-level redirect
         * handling rewrite).
         *
         * @return string
index 1769924..06b579a 100644 (file)
@@ -546,7 +546,7 @@ class WikiImporter {
        public function doImport() {
                // Calls to reader->read need to be wrapped in calls to
                // libxml_disable_entity_loader() to avoid local file
-               // inclusion attacks (bug 46932).
+               // inclusion attacks (T48932).
                $oldDisable = libxml_disable_entity_loader( true );
                $this->reader->read();
 
index 6a8a99f..f8ab1f2 100644 (file)
@@ -59,6 +59,11 @@ abstract class DatabaseUpdater {
         */
        protected $db;
 
+       /**
+        * @var Maintenance
+        */
+       protected $maintenance;
+
        protected $shared = false;
 
        /**
@@ -485,7 +490,7 @@ abstract class DatabaseUpdater {
        public function updateRowExists( $key ) {
                $row = $this->db->selectRow(
                        'updatelog',
-                       # Bug 65813
+                       # T67813
                        '1 AS X',
                        [ 'ul_key' => $key ],
                        __METHOD__
index 9c87cf0..f03fe6a 100644 (file)
@@ -216,7 +216,7 @@ abstract class Installer {
                '_UpgradeKeySupplied' => false,
                '_ExistingDBSettings' => false,
 
-               // $wgLogo is probably wrong (bug 48084); set something that will work.
+               // $wgLogo is probably wrong (T50084); set something that will work.
                // Single quotes work fine here, as LocalSettingsGenerator outputs this unescaped.
                'wgLogo' => '$wgResourceBasePath/resources/assets/wiki.png',
                'wgAuthenticationTokenVersion' => 1,
@@ -1431,7 +1431,7 @@ abstract class Installer {
                        );
                }
                // Unset everyone else's hooks. Lord knows what someone might be doing
-               // in ParserFirstCallInit (see bug 27171)
+               // in ParserFirstCallInit (see T29171)
                $GLOBALS['wgHooks'] = [ 'LoadExtensionSchemaUpdates' => $hooksWeWant ];
 
                return Status::newGood();
index 49bfac1..3131c3c 100644 (file)
@@ -824,7 +824,7 @@ class MysqlUpdater extends DatabaseUpdater {
        /**
         * Set page_random field to a random value where it is equals to 0.
         *
-        * @see bug 3946
+        * @see T5946
         */
        protected function doPageRandomUpdate() {
                $page = $this->db->tableName( 'page' );
index e041fdd..1a7b208 100644 (file)
@@ -496,8 +496,8 @@ class PostgresUpdater extends DatabaseUpdater {
                $q = <<<END
 SELECT attname, attnum FROM pg_namespace, pg_class, pg_attribute
        WHERE pg_class.relnamespace = pg_namespace.oid
-         AND attrelid=pg_class.oid AND attnum > 0
-         AND relname=%s AND nspname=%s
+               AND attrelid=pg_class.oid AND attnum > 0
+               AND relname=%s AND nspname=%s
 END;
                $res = $this->db->query( sprintf( $q,
                        $this->db->addQuotes( $table ),
@@ -523,9 +523,9 @@ END;
                $q = <<<END
 SELECT indkey, indrelid FROM pg_namespace, pg_class, pg_index
        WHERE nspname=%s
-         AND pg_class.relnamespace = pg_namespace.oid
-         AND relname=%s
-         AND indexrelid=pg_class.oid
+               AND pg_class.relnamespace = pg_namespace.oid
+               AND relname=%s
+               AND indexrelid=pg_class.oid
 END;
                $res = $this->db->query(
                        sprintf(
@@ -551,8 +551,8 @@ END;
                        $query = <<<END
 SELECT attname FROM pg_class, pg_attribute
        WHERE attrelid=$relid
-         AND attnum=%d
-         AND attrelid=pg_class.oid
+               AND attnum=%d
+               AND attrelid=pg_class.oid
 END;
                        $r2 = $this->db->query( sprintf( $query, $rid ) );
                        if ( !$r2 ) {
@@ -572,8 +572,8 @@ END;
                $q = <<<END
 SELECT confdeltype FROM pg_constraint, pg_namespace
        WHERE connamespace=pg_namespace.oid
-         AND nspname=%s
-         AND conname=%s;
+               AND nspname=%s
+               AND conname=%s;
 END;
                $r = $this->db->query(
                        sprintf(
@@ -594,8 +594,8 @@ END;
                $q = <<<END
 SELECT definition FROM pg_rules
        WHERE schemaname = %s
-         AND tablename = %s
-         AND rulename = %s
+               AND tablename = %s
+               AND rulename = %s
 END;
                $r = $this->db->query(
                        sprintf(
@@ -981,10 +981,10 @@ END;
 
        protected function rebuildTextSearch() {
                if ( $this->updateRowExists( 'patch-textsearch_bug66650.sql' ) ) {
-                       $this->output( "...bug 66650 already fixed or not applicable.\n" );
+                       $this->output( "...T68650 already fixed or not applicable.\n" );
                        return;
                };
                $this->applyPatch( 'patch-textsearch_bug66650.sql', false,
-                       'Rebuilding text search for bug 66650' );
+                       'Rebuilding text search for T68650' );
        }
 }
index c5c4a7c..0fe7068 100644 (file)
@@ -244,9 +244,9 @@ class SqliteInstaller extends DatabaseInstaller {
                        $sql =
 <<<EOT
        CREATE TABLE IF NOT EXISTS objectcache (
-         keyname BLOB NOT NULL default '' PRIMARY KEY,
-         value BLOB,
-         exptime TEXT
+               keyname BLOB NOT NULL default '' PRIMARY KEY,
+               value BLOB,
+               exptime TEXT
        )
 EOT;
                        $conn->query( $sql );
index c08212e..c94f0bf 100644 (file)
@@ -1083,7 +1083,7 @@ class WebInstaller extends Installer {
 
                foreach ( $varNames as $name ) {
                        $value = $this->request->getVal( $prefix . $name );
-                       // bug 30524, do not trim passwords
+                       // T32524, do not trim passwords
                        if ( stripos( $name, 'password' ) === false ) {
                                $value = trim( $value );
                        }
index e6deed5..81a107d 100644 (file)
@@ -251,7 +251,7 @@ class WebInstallerName extends WebInstallerPage {
                        $retVal = false;
                }
                // If they asked to subscribe to mediawiki-announce but didn't give
-               // an e-mail, show an error. Bug 29332
+               // an e-mail, show an error. T31332
                if ( !$email && $this->getVar( '_Subscribe' ) ) {
                        $this->parent->showError( 'config-subscribe-noemail' );
                        $retVal = false;
index 62fe785..e4eb255 100644 (file)
@@ -299,9 +299,9 @@ class WebInstallerOutput {
 
 <div id="mw-panel">
        <div class="portal" id="p-logo">
-         <a style="background-image: url(images/installer-logo.png);"
-               href="https://www.mediawiki.org/"
-               title="Main Page"></a>
+               <a style="background-image: url(images/installer-logo.png);"
+                       href="https://www.mediawiki.org/"
+                       title="Main Page"></a>
        </div>
 <?php
        $message = wfMessage( 'config-sidebar' )->plain();
index 2ab0554..7a41ceb 100644 (file)
@@ -92,7 +92,7 @@ abstract class WebInstallerPage {
                }
 
                if ( $continue ) {
-                       // Fake submit button for enter keypress (bug 26267)
+                       // Fake submit button for enter keypress (T28267)
                        // Messages: config-continue, config-restart, config-regenerate
                        $s .= Xml::submitButton(
                                wfMessage( "config-$continue" )->text(),
index 72973e7..bf732a4 100644 (file)
@@ -67,7 +67,7 @@ class WebInstallerUpgrade extends WebInstallerPage {
 
                        if ( $result ) {
                                // If they're going to possibly regenerate LocalSettings, we
-                               // need to create the upgrade/secret keys. Bug 26481
+                               // need to create the upgrade/secret keys. T28481
                                if ( !$this->getVar( '_ExistingDBSettings' ) ) {
                                        $this->parent->generateKeys();
                                }
index 583b80c..3bfa8a6 100644 (file)
@@ -3,7 +3,8 @@
                "authors": [
                        "Asoxor",
                        "Calak",
-                       "Muhammed taha"
+                       "Muhammed taha",
+                       "Lost Whispers"
                ]
        },
        "config-desc": "دامەزرێنەرەکە بۆ میدیاویکی",
@@ -44,6 +45,8 @@
        "config-admin-password": "تێپەڕوشە:",
        "config-admin-password-confirm": "دووبارە تێپەڕوشە:",
        "config-admin-email": "ناونیشانی ئیمەیل:",
+       "config-admin-email-help": "ناونیشانی ئیمەیڵەکەت لێرەدا دابنێ بۆئەوەی بتوانیت ئیمەیڵت لە بەکارھێنەرانی ترەوە پێ بگات، تێپەڕ وشە ڕێک بخەیتەوە و ئاگادار بکرێیتەوە لەو گۆڕانکاریانەی کە لەو پەڕانەدا دەکرێن کە چاودێرییان دەکەیت. دەتوانیت ئەم بۆشاییە بە بەتاڵی جێبھێڵیت.",
+       "config-admin-error-bademail": "تۆ ناونیشانی ئیمەیڵێکی ھەڵەت داخڵ کردووە.",
        "config-profile-wiki": "ویکیی کراوە",
        "config-profile-no-anon": "دروستکردنی ھەژمارە پێویستە",
        "config-profile-fishbowl": "تەنھا دەستکاریکەری ڕێگەپێدراوە",
index 5275548..411b2d0 100644 (file)
        "config-install-subscribe-fail": "قادر تصدیق اعلام مدیاویکی نیست:$1",
        "config-install-subscribe-notpossible": "سی‌یوآر‌ال نصب نشده‌است و <code>allow_url_fopen</code> در دسترس نیست.",
        "config-install-mainpage": "ایجاد صفحهٔ اصلی با محتوای پیش‌فرض",
+       "config-install-mainpage-exists": "صفحهٔ اصلی موجود است، رها شد",
        "config-install-extension-tables": "ایجاد جداول برای افزونه‌های فعال",
        "config-install-mainpage-failed": "قادر به درج صفحهٔ اصلی نمی‌باشد:$1",
        "config-install-done": "'''تبریک!'''\nبا موفقیت مدیاویکی را نصب کردید.\nبرنامه نصب‌کننده پرونده <code>LocalSettings.php</code> را درست کرد.\nکه شامل تمام تنظیمات می‌باشد.\n\nشما نیاز به دریافت آن دارید و آن را در پایهٔ نصب ویکی قرار دهید (همان پوشهٔ index.php). دریافت باید به صورت خودکار شروع شده‌باشد.\n\nاگر دریافت شروع نشد یا اگر آن را لغو کردید با کلیک روی پیوند زیر می‌توانید آن را دریافت کنید:\n\n$3\n\n'''توجه داشته باشید:''' اگر این را الآن انجام ندهید، این پرونده تولیدشده در صورتی که نصب را بدون دریافت آن تمام کردید بعداً در اختیار شما قرار نخواهد گرفت.\n\nوقتی انجام شد شما می‌توانید '''[$2 وارد ویکی شوید]'''.",
        "config-nofile": "پروندهٔ «$1» یافت نشد. آیا حذف شده‌است؟",
        "config-extension-link": "آیا می‌دانستید که ویکی شما [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions extensions] را پشتیبانی می‌کند؟\nشما می‌توانید [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category extensions by category]",
        "mainpagetext": "'''مدیاویکی با موفقیت نصب شد.'''",
-       "mainpagedocfooter": "از [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents]\nبرای اطلاعات بیشتر در مورد به‌کارگیری نرم‌افزار ویکی استفاده کنید.\n\n== آغاز به کار ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings فهرست تنظیمات پیکربندی]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ پرسش‌های متداول مدیاویکی]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce فهرست ایمیلی نسخه‌های مدیاویکی]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources محلی‌سازی مدیاویکی به زبان شما]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam یادگیری روش‌های مقابله با هرزنگاری در ویکی]"
+       "mainpagedocfooter": "از [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents راهنمای کاربری]\nبرای اطلاعات بیشتر در مورد به‌کارگیری نرم‌افزار ویکی استفاده کنید.\n\n== آغاز به کار ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings فهرست تنظیمات پیکربندی]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ پرسش‌های متداول مدیاویکی]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce فهرست ایمیلی نسخه‌های مدیاویکی]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources محلی‌سازی مدیاویکی به زبان شما]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam یادگیری روش‌های مقابله با هرزنگاری در ویکی]"
 }
index e98988c..161c5db 100644 (file)
@@ -9,7 +9,8 @@
                        "Yona b",
                        "Rotemliss",
                        "Macofe",
-                       "Guycn2"
+                       "Guycn2",
+                       "שמזן"
                ]
        },
        "config-desc": "תכנית ההתקנה של מדיה־ויקי",
        "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-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-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-cache-options": "הגדרות למטמון עצמים (object caching):",
        "config-cache-help": "מטמון עצמים משמש לשיפור המהירות של מדיה־ויקי על־ידי שמירה של נתונים שהשימוש בהם נפוץ במטמון.\nלאתרים בינוניים וגדולים כדאי מאוד להפעיל את זה, וגם אתרים קטנים ייהנו מזה.",
        "config-cache-none": "ללא מטמון (שום יכולת אינה מוּסרת, אבל הביצועים באתרים גדולים ייפגעו)",
-       "config-cache-accel": "מטמון עצמים (object caching) של PHP&rlm; (APC&rlm;, XCache או WinCache)",
+       "config-cache-accel": "מטמון עצמים (object caching) של PHP&rlm; (APC,&rlm; APCu,&rlm; XCache או WinCache)",
        "config-cache-memcached": "להשתמש ב־Memcached (דורש התקנות והגדרות נוספות)",
        "config-memcached-servers": "שרתי Memcached:",
        "config-memcached-help": "רשימת כתובות IP ש־Memcached ישתמש בהן.\nיש לרשום כתובת אחת בכל שורה ולציין את הפִּתְחָה (port), למשל:\n 127.0.0.1:11211\n 192.168.1.25:1234",
        "config-install-subscribe-fail": "הרישום ל־mediawiki-announce לא הצליח: $1",
        "config-install-subscribe-notpossible": "cURL אינה מותקנת ו־<code>allow_url_fopen</code> אינה זמינה.",
        "config-install-mainpage": "יצירת דף ראשי עם תוכן התחלתי",
+       "config-install-mainpage-exists": "העמוד הראשי כבר קיים, לדלג",
        "config-install-extension-tables": "יצירת טבלאות להרחבות מופעלות",
        "config-install-mainpage-failed": "לא הצליחה הכנסת דף ראשי: $1.",
        "config-install-done": "<strong>מזל טוב!</strong>\nהתקנת את תוכנת מדיה־ויקי.\n\nתוכנת ההתקנה יצרה את הקובץ <code>LocalSettings.php</code>.\nהוא מכיל את כל ההגדרות שלך.\n\nיש להוריד אותו ולהכניס אותו לתיקיית הבסיס שבה הותקן הוויקי שלך (אותה התיקייה שבה נמצא הקובץ index.php). ההורדה אמורה להתחיל באופן אוטומטי.\n\nאם ההורדה לא התחילה, או אם ביטלת אותה, אפשר להתחיל אותה מחדש באמצעות לחיצה על הקישור הבא:\n\n$3\n\n<strong>לתשומת לבך:</strong> אם ההורדה לא תבוצע כעת, קובץ ההגדרות <strong>לא</strong> יהיה זמין מאוחר יותר אם תוכנת ההתקנה תיסגר לפני שהקובץ יורד.\n\nלאחר שביצעת את הפעולות שלהלן, באפשרותך <strong>[$2 להיכנס לאתר הוויקי שלך]</strong>.",
        "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 הרחבות לפי קטגוריה].",
        "mainpagetext": "<strong>תוכנת מדיה־ויקי הותקנה בהצלחה.</strong>",
-       "mainpagedocfooter": "היעזרו ב[https://meta.wikimedia.org/wiki/Help:Contents מדריך למשתמש] למידע על שימוש בתוכנת הוויקי.\n\n== קישורים שימושיים ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings רשימת ההגדרות]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ שאלות ותשובות על מדיה־ויקי]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce רשימת התפוצה על השקת גרסאות]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources תרגום מדיה־ויקי לשפה שלך]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam איך להיאבק נגד ספאם באתר הוויקי שלך]"
+       "mainpagedocfooter": "היעזרו ב[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents מדריך למשתמש] למידע על שימוש בתוכנת הוויקי.\n\n== קישורים שימושיים ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings רשימת ההגדרות]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ שאלות ותשובות על מדיה־ויקי]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce רשימת התפוצה על השקת גרסאות]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources תרגום מדיה־ויקי לשפה שלך]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam איך להיאבק נגד ספאם באתר הוויקי שלך]"
 }
index e05b700..98af267 100644 (file)
@@ -5,7 +5,8 @@
                        "Vivek Rai",
                        "Phoenix303",
                        "संजीव कुमार",
-                       "Sahilrathod"
+                       "Sahilrathod",
+                       "Shyamal"
                ]
        },
        "config-desc": "साँचा लिए इंस्टॉलर",
@@ -16,7 +17,9 @@
        "config-localsettings-key": "नवीनीकरण कुंजी",
        "config-localsettings-badkey": "आपकी दी गई कुंजी ग़लत है।",
        "config-your-language": "आपकी भाषा:",
+       "config-your-language-help": "स्थापन के लिए भाषा चुनें",
        "config-wiki-language": "विकी भाषा:",
+       "config-wiki-language-help": "भाषा चुनें जिस  में अधिकतर लेख लिखा जाएगा",
        "config-back": "← वापस",
        "config-continue": "आगे बढ़ें →",
        "config-page-language": "भाषा",
index 70ef27a..89f8e55 100644 (file)
        "config-logo-help": "Матичното руво на МедијаВики има простор за лого од 135x160 пиксели над страничникот.\n\nМожете да употребите <code>$wgStylePath</code> или <code>$wgScriptPath</code> ако вашето лого е релативно на тие патеки.\n\nАко не сакате да имате лого, тогаш оставете го ова поле празно.",
        "config-instantcommons": "Овозможи Instant Commons",
        "config-instantcommons-help": "[https://www.mediawiki.org/wiki/InstantCommons Instant Commons] е функција која им овозможува на викијата да користат слики, звучни записи и други мултимедијални содржини од [https://commons.wikimedia.org/ Ризницата].\nЗа да може ова да работи, МедијаВики бара пристап до семрежјето.\n\nЗа повеќе информации за оваа функција и напатствија за нејзино поставување на вики (сите други освен Ризницата), коносултирајте го [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgForeignFileRepos прирачникот].",
-       "config-cc-error": "Изборникот на лиценци од Криејтив комонс не даде резултати.\nВнесете го името на лиценцата рачно.",
+       "config-cc-error": "Изборникот на лиценци од Криејтив комонс не даде лиценца.\nВнесете го името на лиценцата рачно.",
        "config-cc-again": "Одберете повторно...",
        "config-cc-not-chosen": "Одберете ја саканата лиценца од Криејтив комонс и стиснете на „proceed“.",
        "config-advanced-settings": "Напредни нагодувања",
index 0a8ae7f..2f58947 100644 (file)
@@ -346,7 +346,7 @@ class JobQueueDB extends JobQueue {
                                        continue; // try the other direction
                                }
                        } else { // table *may* have >= MAX_OFFSET rows
-                               // Bug 42614: "ORDER BY job_random" with a job_random inequality causes high CPU
+                               // T44614: "ORDER BY job_random" with a job_random inequality causes high CPU
                                // in MySQL if there are many rows for some reason. This uses a small OFFSET
                                // instead of job_random for reducing excess claim retries.
                                $row = $dbw->selectRow( 'job', self::selectFields(), // find a random job
index 25a271c..c2c9d66 100644 (file)
@@ -793,9 +793,9 @@ LUA;
        private function getGlobalKey( $name ) {
                $parts = [ 'global', 'jobqueue', $name ];
                foreach ( $parts as $part ) {
-                   if ( !preg_match( '/[a-zA-Z0-9_-]+/', $part ) ) {
-                       throw new InvalidArgumentException( "Key part characters are out of range." );
-                   }
+                       if ( !preg_match( '/[a-zA-Z0-9_-]+/', $part ) ) {
+                               throw new InvalidArgumentException( "Key part characters are out of range." );
+                       }
                }
 
                return implode( ':', $parts );
index 3cd3448..74c446f 100644 (file)
@@ -137,7 +137,7 @@ class DoubleRedirectJob extends Job {
                        wfDebug( __METHOD__ . " : skipping, already good\n" );
                }
 
-               // Preserve fragment (bug 14904)
+               // Preserve fragment (T16904)
                $newTitle = Title::makeTitle( $newTitle->getNamespace(), $newTitle->getDBkey(),
                        $currentDest->getFragment(), $newTitle->getInterwiki() );
 
@@ -199,7 +199,7 @@ class DoubleRedirectJob extends Job {
                        $seenTitles[$titleText] = true;
 
                        if ( $title->isExternal() ) {
-                               // If the target is interwiki, we have to break early (bug 40352).
+                               // If the target is interwiki, we have to break early (T42352).
                                // Otherwise it will look up a row in the local page table
                                // with the namespace/page of the interwiki target which can cause
                                // unexpected results (e.g. X -> foo:Bar -> Bar -> .. )
index 37e80c2..e89812b 100644 (file)
@@ -128,7 +128,7 @@ class PublishStashedFileJob extends Job {
                        );
                        $this->setLastError( get_class( $e ) . ": " . $e->getMessage() );
                        // To prevent potential database referential integrity issues.
-                       // See bug 32551.
+                       // See T34551.
                        MWExceptionHandler::rollbackMasterChangesAndLog( $e );
 
                        return false;
index 651a332..f9284a5 100644 (file)
@@ -29,7 +29,7 @@ use MediaWiki\MediaWikiServices;
  *   - a) Recursive jobs to update links for backlink pages for a given title.
  *        These jobs have (recursive:true,table:<table>) set.
  *   - b) Jobs to update links for a set of pages (the job title is ignored).
- *           These jobs have (pages:(<page ID>:(<namespace>,<title>),...) set.
+ *        These jobs have (pages:(<page ID>:(<namespace>,<title>),...) set.
  *   - c) Jobs to update links for a single page (the job title)
  *        These jobs need no extra fields set.
  *
index 7f50055..1c12a1c 100644 (file)
@@ -33,7 +33,7 @@
  * For example, if templates A and B are edited (at the same time) the queue will have:
  *     (A base, B base)
  * When these jobs run, the queue will have per-title and remnant partition jobs:
- *        (titleX,titleY,titleZ,...,A remnant,titleM,titleN,titleO,...,B remnant)
+ *     (titleX,titleY,titleZ,...,A remnant,titleM,titleN,titleO,...,B remnant)
  *
  * This works best when the queue is FIFO, for several reasons:
  *   - a) Since the remnant jobs are enqueued after the leaf jobs, the slower leaf jobs have to
@@ -133,7 +133,7 @@ class BacklinkJobUtils {
                                        'table'         => $params['table'],
                                        'range'         => [
                                                'start'     => $ranges[1][0],
-                                               'end'       => $ranges[count( $ranges ) - 1][1],
+                                               'end'       => $ranges[count( $ranges ) - 1][1],
                                                'batchSize' => $realBSize,
                                                'subranges' => array_slice( $ranges, 1 )
                                        ],
index bc99672..b1cece8 100644 (file)
@@ -8,7 +8,7 @@
  * not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *             http://www.apache.org/licenses/LICENSE-2.0
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software distributed
  * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
@@ -237,7 +237,7 @@ class CSSMin {
                //       * Otherwise remap the URL to work in generated stylesheets
 
                // Guard against trailing slashes, because "some/remote/../foo.png"
-               // resolves to "some/remote/foo.png" on (some?) clients (bug 27052).
+               // resolves to "some/remote/foo.png" on (some?) clients (T29052).
                if ( substr( $remote, -1 ) == '/' ) {
                        $remote = substr( $remote, 0, -1 );
                }
index 4c86757..6b3e4a7 100644 (file)
@@ -197,11 +197,11 @@ class CryptHKDF {
         * From http://eprint.iacr.org/2010/264.pdf:
         *
         * The scheme HKDF is specifed as:
-        *      HKDF(XTS, SKM, CTXinfo, L) = K(1) || K(2) || ... || K(t)
+        *   HKDF(XTS, SKM, CTXinfo, L) = K(1) || K(2) || ... || K(t)
         * where the values K(i) are defined as follows:
-        *      PRK = HMAC(XTS, SKM)
-        *      K(1) = HMAC(PRK, CTXinfo || 0);
-        *      K(i+1) = HMAC(PRK, K(i) || CTXinfo || i), 1 <= i < t;
+        *   PRK = HMAC(XTS, SKM)
+        *   K(1) = HMAC(PRK, CTXinfo || 0);
+        *   K(i+1) = HMAC(PRK, K(i) || CTXinfo || i), 1 <= i < t;
         * where t = [L/k] and the value K(t) is truncated to its first d = L mod k bits;
         * the counter i is non-wrapping and of a given fixed size, e.g., a single byte.
         * Note that the length of the HMAC output is the same as its key length and therefore
index 21203a4..a6aa0a3 100644 (file)
@@ -675,7 +675,7 @@ class IP {
         * @return string|null Valid dotted quad IPv4 address or null
         */
        public static function canonicalize( $addr ) {
-               // remove zone info (bug 35738)
+               // remove zone info (T37738)
                $addr = preg_replace( '/\%.*/', '', $addr );
 
                if ( self::isValid( $addr ) ) {
index db085da..e860ec4 100644 (file)
@@ -85,7 +85,7 @@ class StatusValue {
         * defined as:
         * [
         *     0 => object(StatusValue) # the StatusValue with error messages, only
-        *         1 => object(StatusValue) # The StatusValue with warning messages, only
+        *     1 => object(StatusValue) # The StatusValue with warning messages, only
         * ]
         *
         * @return StatusValue[]
@@ -154,7 +154,7 @@ class StatusValue {
        }
 
        /**
-        * Change operation resuklt
+        * Change operation result
         *
         * @param bool $ok Whether the operation completed
         * @param mixed $value
index 8afdce4..4f0805b 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup FileBackend
  * @author Aaron Schulz
  */
+use Wikimedia\Timestamp\ConvertibleTimestamp;
 
 /**
  * @brief Class for a file system (FS) based file backend.
index a7ceab2..5179477 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup FileBackend
  * @author Aaron Schulz
  */
+use Wikimedia\Timestamp\ConvertibleTimestamp;
 
 /**
  * @brief Base class for all backends using particular storage medium.
index 800fdfa..a7d064b 100644 (file)
@@ -19,6 +19,7 @@
  *
  * @file
  */
+use Wikimedia\Timestamp\ConvertibleTimestamp;
 
 /**
  * Functions related to the output of file content
index d40e896..c50dfd7 100644 (file)
@@ -1089,7 +1089,7 @@ class SwiftFileBackend extends FileBackendStore {
                        // good
                } elseif ( $rcode === 404 ) {
                        $status->fatal( 'backend-fail-stream', $params['src'] );
-                       // Per bug 41113, nasty things can happen if bad cache entries get
+                       // Per T43113, nasty things can happen if bad cache entries get
                        // stuck in cache. It's also possible that this error can come up
                        // with simple race conditions. Clear out the stat cache to be safe.
                        $this->clearCache( [ $params['src'] ] );
index 5edd889..2468f38 100644 (file)
@@ -95,9 +95,9 @@ application/vnd.ms-powerpoint [OFFICE]
 application/x-director         [OFFICE]
 text/rtf                       [OFFICE]
 
-application/vnd.openxmlformats-officedocument.wordprocessingml.document        [OFFICE]
+application/vnd.openxmlformats-officedocument.wordprocessingml.document        [OFFICE]
 application/vnd.openxmlformats-officedocument.wordprocessingml.template                [OFFICE]
-application/vnd.ms-word.document.macroEnabled.12                               [OFFICE]
+application/vnd.ms-word.document.macroEnabled.12                               [OFFICE]
 application/vnd.ms-word.template.macroEnabled.12                               [OFFICE]
 application/vnd.openxmlformats-officedocument.presentationml.template          [OFFICE]
 application/vnd.openxmlformats-officedocument.presentationml.slideshow         [OFFICE]
index ae91be5..730eed1 100644 (file)
@@ -63,9 +63,9 @@ class RESTBagOStuff extends BagOStuff {
        protected function doGet( $key, $flags = 0 ) {
                $req = [
                        'method' => 'GET',
-                   'url' => $this->url . rawurlencode( $key ),
-
+                       'url' => $this->url . rawurlencode( $key ),
                ];
+
                list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->client->run( $req );
                if ( $rcode === 200 ) {
                        if ( is_string( $rbody ) ) {
index d852f82..583ec37 100644 (file)
@@ -321,7 +321,7 @@ class RedisBagOStuff extends BagOStuff {
         */
        protected function serialize( $data ) {
                // Serialize anything but integers so INCR/DECR work
-               // Do not store integer-like strings as integers to avoid type confusion (bug 60563)
+               // Do not store integer-like strings as integers to avoid type confusion (T62563)
                return is_int( $data ) ? $data : serialize( $data );
        }
 
index 75c79a9..f0a439a 100644 (file)
@@ -44,15 +44,20 @@ use Psr\Log\NullLogger;
  *
  * The simplest purge method is delete().
  *
- * There are two supported ways to handle broadcasted operations:
+ * There are three supported ways to handle broadcasted operations:
  *   - a) Configure the 'purge' EventRelayer to point to a valid PubSub endpoint
- *        that has subscribed listeners on the cache servers applying the cache updates.
+ *         that has subscribed listeners on the cache servers applying the cache updates.
  *   - b) Ignore the 'purge' EventRelayer configuration (default is NullEventRelayer)
- *        and set up mcrouter as the underlying cache backend, using one of the memcached
- *        BagOStuff classes as 'cache'. Use OperationSelectorRoute in the mcrouter settings
- *        to configure 'set' and 'delete' operations to go to all DCs via AllAsyncRoute and
- *        configure other operations to go to the local DC via PoolRoute (for reference,
- *        see https://github.com/facebook/mcrouter/wiki/List-of-Route-Handles).
+ *         and set up mcrouter as the underlying cache backend, using one of the memcached
+ *         BagOStuff classes as 'cache'. Use OperationSelectorRoute in the mcrouter settings
+ *         to configure 'set' and 'delete' operations to go to all DCs via AllAsyncRoute and
+ *         configure other operations to go to the local DC via PoolRoute (for reference,
+ *         see https://github.com/facebook/mcrouter/wiki/List-of-Route-Handles).
+ *   - c) Ignore the 'purge' EventRelayer configuration (default is NullEventRelayer)
+ *         and set up dynomite as cache middleware between the web servers and either
+ *         memcached or redis. This will also broadcast all key setting operations, not just purges,
+ *         which can be useful for cache warming. Writes are eventually consistent via the
+ *         Dynamo replication model (see https://github.com/Netflix/dynomite).
  *
  * Broadcasted operations like delete() and touchCheckKey() are done asynchronously
  * in all datacenters this way, though the local one should likely be near immediate.
index d84c959..98f44d1 100644 (file)
@@ -41,7 +41,7 @@ class WinCacheBagOStuff extends BagOStuff {
                $result = wincache_ucache_set( $key, serialize( $value ), $expire );
 
                /* wincache_ucache_set returns an empty array on success if $value
-                  was an array, bool otherwise */
+                * was an array, bool otherwise */
                return ( is_array( $result ) && $result === [] ) || $result;
        }
 
index a7952a6..c5afe1e 100644 (file)
@@ -29,8 +29,10 @@ use Wikimedia\ScopedCallback;
 use Wikimedia\Rdbms\TransactionProfiler;
 use Wikimedia\Rdbms\LikeMatch;
 use Wikimedia\Rdbms\DatabaseDomain;
+use Wikimedia\Rdbms\ResultWrapper;
 use Wikimedia\Rdbms\DBMasterPos;
 use Wikimedia\Rdbms\Blob;
+use Wikimedia\Timestamp\ConvertibleTimestamp;
 
 /**
  * Relational database abstraction object
@@ -846,7 +848,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
 
                // Add trace comment to the begin of the sql string, right after the operator.
-               // Or, for one-word queries (like "BEGIN" or COMMIT") add it to the end (bug 42598)
+               // Or, for one-word queries (like "BEGIN" or COMMIT") add it to the end (T44598)
                $commentedSql = preg_replace( '/\s|$/', " /* $fname {$this->agent} */ ", $sql, 1 );
 
                # Start implicit transactions that wrap the request if DBO_TRX is enabled
@@ -1025,8 +1027,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        private function handleSessionLoss() {
                $this->mTrxLevel = 0;
-               $this->mTrxIdleCallbacks = []; // bug 65263
-               $this->mTrxPreCommitCallbacks = []; // bug 65263
+               $this->mTrxIdleCallbacks = []; // T67263
+               $this->mTrxPreCommitCallbacks = []; // T67263
                $this->mSessionTempTables = [];
                $this->mNamedLocksHeld = [];
                try {
index 7c82479..75ddc9d 100644 (file)
@@ -27,6 +27,8 @@
 use Wikimedia\Rdbms\Blob;
 use Wikimedia\Rdbms\MssqlBlob;
 use Wikimedia\Rdbms\MssqlField;
+use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\MssqlResultWrapper;
 
 /**
  * @ingroup Database
index 61ba498..9270589 100644 (file)
@@ -23,6 +23,7 @@
 use Wikimedia\Rdbms\DBMasterPos;
 use Wikimedia\Rdbms\MySQLMasterPos;
 use Wikimedia\Rdbms\MySQLField;
+use Wikimedia\Rdbms\ResultWrapper;
 
 /**
  * Database abstraction object for MySQL.
index 2f27ff9..7a2200a 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Database
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * Database abstraction object for PHP extension mysqli.
  *
index c62fec1..af9716d 100644 (file)
  * @file
  * @ingroup Database
  */
+use Wikimedia\Timestamp\ConvertibleTimestamp;
 use Wikimedia\WaitConditionLoop;
 use Wikimedia\Rdbms\Blob;
 use Wikimedia\Rdbms\PostgresBlob;
 use Wikimedia\Rdbms\PostgresField;
+use Wikimedia\Rdbms\ResultWrapper;
 
 /**
  * @ingroup Database
@@ -985,7 +987,7 @@ __INDEXATTR__;
                                /**
                                 * Prepend our schema (e.g. 'mediawiki') in front
                                 * of the search path
-                                * Fixes bug 15816
+                                * Fixes T17816
                                 */
                                $search_path = $this->getSearchPath();
                                array_unshift( $search_path,
@@ -1026,7 +1028,7 @@ __INDEXATTR__;
                                // Normal client
                                $this->numericVersion = $versionInfo['server'];
                        } else {
-                               // Bug 16937: broken pgsql extension from PHP<5.3
+                               // T18937: broken pgsql extension from PHP<5.3
                                $this->numericVersion = pg_parameter_status( $conn, 'server_version' );
                        }
                }
index 30bfcf8..090ce8e 100644 (file)
@@ -23,6 +23,7 @@
  */
 use Wikimedia\Rdbms\Blob;
 use Wikimedia\Rdbms\SQLiteField;
+use Wikimedia\Rdbms\ResultWrapper;
 
 /**
  * @ingroup Database
index f7bb6cf..6bc870b 100644 (file)
@@ -28,6 +28,7 @@ use Wikimedia\Rdbms\Blob;
 use Wikimedia\Rdbms\LikeMatch;
 use Wikimedia\Rdbms\DBMasterPos;
 use Wikimedia\Rdbms\Field;
+use Wikimedia\Rdbms\IResultWrapper;
 
 /**
  * Basic database interface for live and lazy-loaded relation database handles
@@ -363,7 +364,7 @@ interface IDatabase {
         * member variables.
         * If no more rows are available, false is returned.
         *
-        * @param ResultWrapper|stdClass $res Object as returned from IDatabase::query(), etc.
+        * @param IResultWrapper|stdClass $res Object as returned from IDatabase::query(), etc.
         * @return stdClass|bool
         * @throws DBUnexpectedError Thrown if the database returns an error
         */
@@ -374,7 +375,7 @@ interface IDatabase {
         * form. Fields are retrieved with $row['fieldname'].
         * If no more rows are available, false is returned.
         *
-        * @param ResultWrapper $res Result object as returned from IDatabase::query(), etc.
+        * @param IResultWrapper $res Result object as returned from IDatabase::query(), etc.
         * @return array|bool
         * @throws DBUnexpectedError Thrown if the database returns an error
         */
@@ -517,7 +518,7 @@ interface IDatabase {
         * @param bool $tempIgnore Whether to avoid throwing an exception on errors...
         *     maybe best to catch the exception instead?
         * @throws DBError
-        * @return bool|ResultWrapper True for a successful write query, ResultWrapper object
+        * @return bool|IResultWrapper True for a successful write query, IResultWrapper object
         *     for a successful read query, or false on failure if $tempIgnore set
         */
        public function query( $sql, $fname = __METHOD__, $tempIgnore = false );
@@ -731,7 +732,7 @@ interface IDatabase {
         *
         *    [ 'page' => [ 'LEFT JOIN', 'page_latest=rev_id' ] ]
         *
-        * @return ResultWrapper|bool If the query returned no rows, a ResultWrapper
+        * @return IResultWrapper|bool If the query returned no rows, a IResultWrapper
         *   with no rows in it will be returned. If there was a query error, a
         *   DBQueryError exception will be thrown, except if the "ignore errors"
         *   option was set, in which case false will be returned.
@@ -1196,7 +1197,7 @@ interface IDatabase {
         *   for the format. Use $conds == "*" to delete all rows
         * @param string $fname Name of the calling function
         * @throws DBUnexpectedError
-        * @return bool|ResultWrapper
+        * @return bool|IResultWrapper
         */
        public function delete( $table, $conds, $fname = __METHOD__ );
 
@@ -1224,7 +1225,7 @@ interface IDatabase {
         * @param array $selectOptions Options for the SELECT part of the query, see
         *    IDatabase::select() for details.
         *
-        * @return ResultWrapper
+        * @return IResultWrapper
         */
        public function insertSelect( $destTable, $srcTable, $varMap, $conds,
                $fname = __METHOD__,
index 1a046cf..fd7af11 100644 (file)
@@ -1,4 +1,9 @@
 <?php
+
+namespace Wikimedia\Rdbms;
+
+use stdClass;
+
 /**
  * Overloads the relevant methods of the real ResultsWrapper so it
  * doesn't go anywhere near an actual database.
@@ -56,3 +61,6 @@ class FakeResultWrapper extends ResultWrapper {
                return $this->fetchObject();
        }
 }
+
+class_alias( FakeResultWrapper::class, 'FakeResultWrapper' );
+
index b591f4f..4e28397 100644 (file)
@@ -1,4 +1,9 @@
 <?php
+
+namespace Wikimedia\Rdbms;
+
+use stdClass;
+
 class MssqlResultWrapper extends ResultWrapper {
        /** @var integer|null */
        private $mSeekTo = null;
index 88e7cdd..a76d66a 100644 (file)
@@ -1,6 +1,10 @@
 <?php
 
-use Wikimedia\Rdbms\IResultWrapper;
+namespace Wikimedia\Rdbms;
+
+use IDatabase;
+use stdClass;
+use RuntimeException;
 
 /**
  * Result wrapper for grabbing data queried from an IDatabase object
@@ -115,3 +119,5 @@ class ResultWrapper implements IResultWrapper {
                return $this->current() !== false;
        }
 }
+
+class_alias( ResultWrapper::class, 'ResultWrapper' );
index c4229bc..f05dabc 100644 (file)
@@ -336,7 +336,7 @@ abstract class LBFactory implements ILBFactory {
                $masterPositions = array_fill( 0, count( $lbs ), false );
                foreach ( $lbs as $i => $lb ) {
                        if ( $lb->getServerCount() <= 1 ) {
-                               // Bug 27975 - Don't try to wait for replica DBs if there are none
+                               // T29975 - Don't try to wait for replica DBs if there are none
                                // Prevents permission error when getting master position
                                continue;
                        } elseif ( $opts['ifWritesSince']
diff --git a/includes/libs/time/ConvertibleTimestamp.php b/includes/libs/time/ConvertibleTimestamp.php
deleted file mode 100644 (file)
index c830b4e..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-<?php
-/**
- * Creation, parsing, and conversion of timestamps.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @since 1.20
- * @author Tyler Romeo, 2012
- */
-
-/**
- * Library for creating, parsing, and converting timestamps. Based on the JS
- * library that does the same thing.
- *
- * @since 1.28
- */
-class ConvertibleTimestamp {
-       /**
-        * Standard gmdate() formats for the different timestamp types.
-        */
-       private static $formats = [
-               TS_UNIX => 'U',
-               TS_MW => 'YmdHis',
-               TS_DB => 'Y-m-d H:i:s',
-               TS_ISO_8601 => 'Y-m-d\TH:i:s\Z',
-               TS_ISO_8601_BASIC => 'Ymd\THis\Z',
-               TS_EXIF => 'Y:m:d H:i:s', // This shouldn't ever be used, but is included for completeness
-               TS_RFC2822 => 'D, d M Y H:i:s',
-               TS_ORACLE => 'd-m-Y H:i:s.000000', // Was 'd-M-y h.i.s A' . ' +00:00' before r51500
-               TS_POSTGRES => 'Y-m-d H:i:s',
-       ];
-
-       /**
-        * The actual timestamp being wrapped (DateTime object).
-        * @var DateTime
-        */
-       public $timestamp;
-
-       /**
-        * Make a new timestamp and set it to the specified time,
-        * or the current time if unspecified.
-        *
-        * @param bool|string|int|float|DateTime $timestamp Timestamp to set, or false for current time
-        */
-       public function __construct( $timestamp = false ) {
-               if ( $timestamp instanceof DateTime ) {
-                       $this->timestamp = $timestamp;
-               } else {
-                       $this->setTimestamp( $timestamp );
-               }
-       }
-
-       /**
-        * Set the timestamp to the specified time, or the current time if unspecified.
-        *
-        * Parse the given timestamp into either a DateTime object or a Unix timestamp,
-        * and then store it.
-        *
-        * @param string|bool $ts Timestamp to store, or false for now
-        * @throws TimestampException
-        */
-       public function setTimestamp( $ts = false ) {
-               $m = [];
-               $da = [];
-               $strtime = '';
-
-               // We want to catch 0, '', null... but not date strings starting with a letter.
-               if ( !$ts || $ts === "\0\0\0\0\0\0\0\0\0\0\0\0\0\0" ) {
-                       $uts = time();
-                       $strtime = "@$uts";
-               } elseif ( preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)$/D', $ts, $da ) ) {
-                       # TS_DB
-               } elseif ( preg_match( '/^(\d{4}):(\d\d):(\d\d) (\d\d):(\d\d):(\d\d)$/D', $ts, $da ) ) {
-                       # TS_EXIF
-               } elseif ( preg_match( '/^(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/D', $ts, $da ) ) {
-                       # TS_MW
-               } elseif ( preg_match( '/^(-?\d{1,13})(\.\d+)?$/D', $ts, $m ) ) {
-                       # TS_UNIX
-                       $strtime = "@{$m[1]}"; // https://secure.php.net/manual/en/datetime.formats.compound.php
-               } elseif ( preg_match( '/^\d{2}-\d{2}-\d{4} \d{2}:\d{2}:\d{2}.\d{6}$/', $ts ) ) {
-                       # TS_ORACLE // session altered to DD-MM-YYYY HH24:MI:SS.FF6
-                       $strtime = preg_replace( '/(\d\d)\.(\d\d)\.(\d\d)(\.(\d+))?/', "$1:$2:$3",
-                               str_replace( '+00:00', 'UTC', $ts ) );
-               } elseif ( preg_match(
-                       '/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.*\d*)?Z?$/',
-                       $ts,
-                       $da
-               ) ) {
-                       # TS_ISO_8601
-               } elseif ( preg_match(
-                       '/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(?:\.*\d*)?Z?$/',
-                       $ts,
-                       $da
-               ) ) {
-                       # TS_ISO_8601_BASIC
-               } elseif ( preg_match(
-                       '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.*\d*[\+\- ](\d\d)$/',
-                       $ts,
-                       $da
-               ) ) {
-                       # TS_POSTGRES
-               } elseif ( preg_match(
-                       '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.*\d* GMT$/',
-                       $ts,
-                       $da
-               ) ) {
-                       # TS_POSTGRES
-               } elseif ( preg_match(
-               # Day of week
-                       '/^[ \t\r\n]*([A-Z][a-z]{2},[ \t\r\n]*)?' .
-                       # dd Mon yyyy
-                       '\d\d?[ \t\r\n]*[A-Z][a-z]{2}[ \t\r\n]*\d{2}(?:\d{2})?' .
-                       # hh:mm:ss
-                       '[ \t\r\n]*\d\d[ \t\r\n]*:[ \t\r\n]*\d\d[ \t\r\n]*:[ \t\r\n]*\d\d/S',
-                       $ts
-               ) ) {
-                       # TS_RFC2822, accepting a trailing comment.
-                       # See http://www.squid-cache.org/mail-archive/squid-users/200307/0122.html / r77171
-                       # The regex is a superset of rfc2822 for readability
-                       $strtime = strtok( $ts, ';' );
-               } elseif ( preg_match( '/^[A-Z][a-z]{5,8}, \d\d-[A-Z][a-z]{2}-\d{2} \d\d:\d\d:\d\d/', $ts ) ) {
-                       # TS_RFC850
-                       $strtime = $ts;
-               } elseif ( preg_match( '/^[A-Z][a-z]{2} [A-Z][a-z]{2} +\d{1,2} \d\d:\d\d:\d\d \d{4}/', $ts ) ) {
-                       # asctime
-                       $strtime = $ts;
-               } else {
-                       throw new TimestampException( __METHOD__ . ": Invalid timestamp - $ts" );
-               }
-
-               if ( !$strtime ) {
-                       $da = array_map( 'intval', $da );
-                       $da[0] = "%04d-%02d-%02dT%02d:%02d:%02d.00+00:00";
-                       $strtime = call_user_func_array( "sprintf", $da );
-               }
-
-               try {
-                       $final = new DateTime( $strtime, new DateTimeZone( 'GMT' ) );
-               } catch ( Exception $e ) {
-                       throw new TimestampException( __METHOD__ . ': Invalid timestamp format.', $e->getCode(), $e );
-               }
-
-               if ( $final === false ) {
-                       throw new TimestampException( __METHOD__ . ': Invalid timestamp format.' );
-               }
-
-               $this->timestamp = $final;
-       }
-
-       /**
-        * Convert a timestamp string to a given format.
-        *
-        * @param int $style Constant Output format for timestamp
-        * @param string $ts Timestamp
-        * @return string|bool Formatted timestamp or false on failure
-        */
-       public static function convert( $style = TS_UNIX, $ts ) {
-               try {
-                       $ct = new static( $ts );
-                       return $ct->getTimestamp( $style );
-               } catch ( TimestampException $e ) {
-                       return false;
-               }
-       }
-
-       /**
-        * Get the current time in the given format
-        *
-        * @param int $style Constant Output format for timestamp
-        * @return string
-        */
-       public static function now( $style = TS_MW ) {
-               return static::convert( $style, time() );
-       }
-
-       /**
-        * Get the timestamp represented by this object in a certain form.
-        *
-        * Convert the internal timestamp to the specified format and then
-        * return it.
-        *
-        * @param int $style Constant Output format for timestamp
-        * @throws TimestampException
-        * @return string The formatted timestamp
-        */
-       public function getTimestamp( $style = TS_UNIX ) {
-               if ( !isset( self::$formats[$style] ) ) {
-                       throw new TimestampException( __METHOD__ . ': Illegal timestamp output type.' );
-               }
-
-               $output = $this->timestamp->format( self::$formats[$style] );
-
-               if ( ( $style == TS_RFC2822 ) || ( $style == TS_POSTGRES ) ) {
-                       $output .= ' GMT';
-               }
-
-               if ( $style == TS_MW && strlen( $output ) !== 14 ) {
-                       throw new TimestampException( __METHOD__ . ': The timestamp cannot be represented in ' .
-                               'the specified format' );
-               }
-
-               return $output;
-       }
-
-       /**
-        * @return string
-        */
-       public function __toString() {
-               return $this->getTimestamp();
-       }
-
-       /**
-        * Calculate the difference between two ConvertibleTimestamp objects.
-        *
-        * @param ConvertibleTimestamp $relativeTo Base time to calculate difference from
-        * @return DateInterval|bool The DateInterval object representing the
-        *   difference between the two dates or false on failure
-        */
-       public function diff( ConvertibleTimestamp $relativeTo ) {
-               return $this->timestamp->diff( $relativeTo->timestamp );
-       }
-
-       /**
-        * Set the timezone of this timestamp to the specified timezone.
-        *
-        * @param string $timezone Timezone to set
-        * @throws TimestampException
-        */
-       public function setTimezone( $timezone ) {
-               try {
-                       $this->timestamp->setTimezone( new DateTimeZone( $timezone ) );
-               } catch ( Exception $e ) {
-                       throw new TimestampException( __METHOD__ . ': Invalid timezone.', $e->getCode(), $e );
-               }
-       }
-
-       /**
-        * Get the timezone of this timestamp.
-        *
-        * @return DateTimeZone The timezone
-        */
-       public function getTimezone() {
-               return $this->timestamp->getTimezone();
-       }
-
-       /**
-        * Format the timestamp in a given format.
-        *
-        * @param string $format Pattern to format in
-        * @return string The formatted timestamp
-        */
-       public function format( $format ) {
-               return $this->timestamp->format( $format );
-       }
-}
diff --git a/includes/libs/time/TimestampException.php b/includes/libs/time/TimestampException.php
deleted file mode 100644 (file)
index 36ffdee..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-
-/**
- * @since 1.20
- */
-class TimestampException extends Exception {
-}
diff --git a/includes/libs/time/defines.php b/includes/libs/time/defines.php
deleted file mode 100644 (file)
index ff4dde8..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-
-/**
- * Unix time - the number of seconds since 1970-01-01 00:00:00 UTC
- */
-define( 'TS_UNIX', 0 );
-
-/**
- * MediaWiki concatenated string timestamp (YYYYMMDDHHMMSS)
- */
-define( 'TS_MW', 1 );
-
-/**
- * MySQL DATETIME (YYYY-MM-DD HH:MM:SS)
- */
-define( 'TS_DB', 2 );
-
-/**
- * RFC 2822 format, for E-mail and HTTP headers
- */
-define( 'TS_RFC2822', 3 );
-
-/**
- * ISO 8601 format with no timezone: 1986-02-09T20:00:00Z
- *
- * This is used by Special:Export
- */
-define( 'TS_ISO_8601', 4 );
-
-/**
- * An Exif timestamp (YYYY:MM:DD HH:MM:SS)
- *
- * @see http://exif.org/Exif2-2.PDF The Exif 2.2 spec, see page 28 for the
- *       DateTime tag and page 36 for the DateTimeOriginal and
- *       DateTimeDigitized tags.
- */
-define( 'TS_EXIF', 5 );
-
-/**
- * Oracle format time.
- */
-define( 'TS_ORACLE', 6 );
-
-/**
- * Postgres format time.
- */
-define( 'TS_POSTGRES', 7 );
-
-/**
- * ISO 8601 basic format with no timezone: 19860209T200000Z.  This is used by ResourceLoader
- */
-define( 'TS_ISO_8601_BASIC', 9 );
index 0d171f5..f1df7f1 100644 (file)
@@ -647,7 +647,7 @@ class XMPReader implements LoggerAwareInterface {
        private function endElementNested( $elm ) {
 
                /* cur item must be the same as $elm, unless if in MODE_STRUCT
-                  in which case it could also be rdf:Description */
+                * in which case it could also be rdf:Description */
                if ( $this->curItem[0] !== $elm
                        && !( $elm === self::NS_RDF . ' Description'
                                && $this->mode[0] === self::MODE_STRUCT )
@@ -895,7 +895,7 @@ class XMPReader implements LoggerAwareInterface {
                if ( $elm === self::NS_RDF . ' Seq' ) {
                        array_unshift( $this->mode, self::MODE_LI );
                } elseif ( $elm === self::NS_RDF . ' Bag' ) {
-                       # bug 27105
+                       # T29105
                        $this->logger->info( __METHOD__ . ' Expected an rdf:Seq, but got an rdf:Bag. Pretending'
                                . ' it is a Seq, since some buggy software is known to screw this up.' );
                        array_unshift( $this->mode, self::MODE_LI );
index 052be33..5211a2c 100644 (file)
@@ -650,7 +650,7 @@ class XMPInfo {
                                'choices' => [ '1' => true, '2' => true ],
                        ],
                        /********
-                        * Disable extracting this property (bug 31944)
+                        * Disable extracting this property (T33944)
                         * Several files have a string instead of a Seq
                         * for this property. XMPReader doesn't handle
                         * mismatched types very gracefully (it marks
@@ -658,7 +658,7 @@ class XMPInfo {
                         * the relavent prop). Since this prop
                         * doesn't communicate all that useful information
                         * just disable this prop for now, until such
-                        * XMPReader is more graceful (bug 32172)
+                        * XMPReader is more graceful (T34172)
                         * 'YCbCrSubSampling'  => array(
                         *    'map_group' => 'exif',
                         *    'mode'      => XMPReader::MODE_SEQ,
index 31eaa3b..76ae279 100644 (file)
@@ -23,6 +23,7 @@
 
 use Psr\Log\LoggerInterface;
 use Psr\Log\LoggerAwareInterface;
+use Wikimedia\Timestamp\ConvertibleTimestamp;
 
 /**
  * This contains some static methods for
index b5af783..68404bf 100644 (file)
@@ -167,7 +167,7 @@ class LogFormatter {
 
        /**
         * Even uglier hack to maintain backwards compatibilty with IRC bots
-        * (bug 34508).
+        * (T36508).
         * @see getActionText()
         * @return string Text
         */
@@ -188,7 +188,7 @@ class LogFormatter {
 
        /**
         * Even uglier hack to maintain backwards compatibilty with IRC bots
-        * (bug 34508).
+        * (T36508).
         * @see getActionText()
         * @return string Text
         */
index 68163c1..ea28ff2 100644 (file)
@@ -181,7 +181,7 @@ class LogPager extends ReverseChronologicalPager {
                } else {
                        $this->mConds['log_user'] = $userid;
                }
-               // Paranoia: avoid brute force searches (bug 17342)
+               // Paranoia: avoid brute force searches (T19342)
                $user = $this->getUser();
                if ( !$user->isAllowed( 'deletedhistory' ) ) {
                        $this->mConds[] = $this->mDb->bitAnd( 'log_deleted', LogPage::DELETED_USER ) . ' = 0';
@@ -256,7 +256,7 @@ class LogPager extends ReverseChronologicalPager {
                } else {
                        $this->mConds['log_title'] = $title->getDBkey();
                }
-               // Paranoia: avoid brute force searches (bug 17342)
+               // Paranoia: avoid brute force searches (T19342)
                $user = $this->getUser();
                if ( !$user->isAllowed( 'deletedhistory' ) ) {
                        $this->mConds[] = $db->bitAnd( 'log_deleted', LogPage::DELETED_ACTION ) . ' = 0';
index 1d0bdf6..d66e7e3 100644 (file)
@@ -316,7 +316,7 @@ class EmailNotification {
                $pageTitle = $this->title->getPrefixedText();
 
                if ( $this->oldid ) {
-                       // Always show a link to the diff which triggered the mail. See bug 32210.
+                       // Always show a link to the diff which triggered the mail. See T34210.
                        $keys['$NEWPAGE'] = "\n\n" . wfMessage( 'enotif_lastdiff',
                                        $this->title->getCanonicalURL( [ 'diff' => 'next', 'oldid' => $this->oldid ] ) )
                                        ->inContentLanguage()->text();
@@ -363,7 +363,7 @@ class EmailNotification {
                        Skin::makeInternalOrExternalUrl( wfMessage( 'helppage' )->inContentLanguage()->text() )
                );
 
-               # Replace this after transforming the message, bug 35019
+               # Replace this after transforming the message, T37019
                $postTransformKeys['$PAGESUMMARY'] = $this->summary == '' ? ' - ' : $this->summary;
 
                // Now build message's subject and body
index 21effa0..3858f27 100644 (file)
@@ -103,9 +103,9 @@ class UserMailer {
         * @param string $subject Email's subject.
         * @param string $body Email's text or Array of two strings to be the text and html bodies
         * @param array $options:
-        *              'replyTo' MailAddress
-        *              'contentType' string default 'text/plain; charset=UTF-8'
-        *              'headers' array Extra headers to set
+        *     'replyTo' MailAddress
+        *     'contentType' string default 'text/plain; charset=UTF-8'
+        *     'headers' array Extra headers to set
         *
         * @throws MWException
         * @throws Exception
@@ -197,9 +197,9 @@ class UserMailer {
         * @param string $subject Email's subject.
         * @param string $body Email's text or Array of two strings to be the text and html bodies
         * @param array $options:
-        *              'replyTo' MailAddress
-        *              'contentType' string default 'text/plain; charset=UTF-8'
-        *              'headers' array Extra headers to set
+        *     'replyTo' MailAddress
+        *     'contentType' string default 'text/plain; charset=UTF-8'
+        *     'headers' array Extra headers to set
         *
         * @throws MWException
         * @throws Exception
index ac0564d..0f0b074 100644 (file)
@@ -150,7 +150,7 @@ class BitmapHandler extends TransformationalImageHandler {
                        if ( $params['interlace'] ) {
                                $animation_post = [ '-interlace', 'JPEG' ];
                        }
-                       # Sharpening, see bug 6193
+                       # Sharpening, see T8193
                        if ( ( $params['physicalWidth'] + $params['physicalHeight'] )
                                / ( $params['srcWidth'] + $params['srcHeight'] )
                                < $wgSharpenReductionThreshold
@@ -178,10 +178,10 @@ class BitmapHandler extends TransformationalImageHandler {
                                // be a total drag. :P
                                $scene = 0;
                        } elseif ( $this->isAnimatedImage( $image ) ) {
-                               // Coalesce is needed to scale animated GIFs properly (bug 1017).
+                               // Coalesce is needed to scale animated GIFs properly (T3017).
                                $animation_pre = [ '-coalesce' ];
                                // We optimize the output, but -optimize is broken,
-                               // use optimizeTransparency instead (bug 11822)
+                               // use optimizeTransparency instead (T13822)
                                if ( version_compare( $this->getMagickVersion(), "6.3.5" ) >= 0 ) {
                                        $animation_post = [ '-fuzz', '5%', '-layers', 'optimizeTransparency' ];
                                }
@@ -211,7 +211,7 @@ class BitmapHandler extends TransformationalImageHandler {
                                && $xcfMeta['colorType'] === 'greyscale-alpha'
                                && version_compare( $this->getMagickVersion(), "6.8.9-3" ) < 0
                        ) {
-                               // bug 66323 - Greyscale images not rendered properly.
+                               // T68323 - Greyscale images not rendered properly.
                                // So only take the "red" channel.
                                $channelOnly = [ '-channel', 'R', '-separate' ];
                                $animation_pre = array_merge( $animation_pre, $channelOnly );
@@ -283,7 +283,7 @@ class BitmapHandler extends TransformationalImageHandler {
                        $im->readImage( $params['srcPath'] );
 
                        if ( $params['mimeType'] == 'image/jpeg' ) {
-                               // Sharpening, see bug 6193
+                               // Sharpening, see T8193
                                if ( ( $params['physicalWidth'] + $params['physicalHeight'] )
                                        / ( $params['srcWidth'] + $params['srcHeight'] )
                                        < $wgSharpenReductionThreshold
@@ -312,7 +312,7 @@ class BitmapHandler extends TransformationalImageHandler {
                                        // be a total drag. :P
                                        $im->setImageScene( 0 );
                                } elseif ( $this->isAnimatedImage( $image ) ) {
-                                       // Coalesce is needed to scale animated GIFs properly (bug 1017).
+                                       // Coalesce is needed to scale animated GIFs properly (T3017).
                                        $im = $im->coalesceImages();
                                }
                                // GIF interlacing is only available since 6.3.4
index 5e8f8c8..57b5b36 100644 (file)
@@ -277,9 +277,9 @@ class DjVuImage {
                                $reg = <<<EOR
                                        /\(page\s[\d-]*\s[\d-]*\s[\d-]*\s[\d-]*\s*"
                                        ((?>    # Text to match is composed of atoms of either:
-                                         \\\\. # - any escaped character
-                                         |     # - any character different from " and \
-                                         [^"\\\\]+
+                                               \\\\. # - any escaped character
+                                               |     # - any character different from " and \
+                                               [^"\\\\]+
                                        )*?)
                                        "\s*\)
                                        | # Or page can be empty ; in this case, djvutxt dumps ()
index 51a0135..f237287 100644 (file)
@@ -24,6 +24,7 @@
  * @see http://exif.org/Exif2-2.PDF The Exif 2.2 specification
  * @file
  */
+use Wikimedia\Timestamp\TimestampException;
 
 /**
  * Format Image metadata values into a human readable form.
index 6c857a8..c9f0dfa 100644 (file)
@@ -112,8 +112,8 @@ class JpegHandler extends ExifBitmapHandler {
                        wfDebug( __METHOD__ . ': ' . $e->getMessage() . "\n" );
 
                        /* This used to use 0 (ExifBitmapHandler::OLD_BROKEN_FILE) for the cases
-                        *      * No metadata in the file
-                        *      * Something is broken in the file.
+                        *   * No metadata in the file
+                        *   * Something is broken in the file.
                         * However, if the metadata support gets expanded then you can't tell if the 0 is from
                         * a broken file, or just no props found. A broken file is likely to stay broken, but
                         * a file which had no props could have props once the metadata support is improved.
index 2a735a2..6a23bd6 100644 (file)
@@ -762,7 +762,7 @@ abstract class MediaHandler {
         * @param string $cmd
         */
        protected function logErrorForExternalProcess( $retval, $err, $cmd ) {
-               # Keep error output limited (bug 57985)
+               # Keep error output limited (T59985)
                $errMessage = trim( substr( $err, 0, self::MAX_ERR_LOG_SIZE ) );
 
                wfDebugLog( 'thumbnail',
index 6a974c7..4087fb3 100644 (file)
@@ -86,13 +86,13 @@ class SVGReader {
                }
 
                // Expand entities, since Adobe Illustrator uses them for xmlns
-               // attributes (bug 31719). Note that libxml2 has some protection
+               // attributes (T33719). Note that libxml2 has some protection
                // against large recursive entity expansions so this is not as
                // insecure as it might appear to be. However, it is still extremely
                // insecure. It's necessary to wrap any read() calls with
                // libxml_disable_entity_loader() to avoid arbitrary local file
                // inclusion, or even arbitrary code execution if the expect
-               // extension is installed (bug 46859).
+               // extension is installed (T48859).
                $oldDisable = libxml_disable_entity_loader( true );
                $this->reader->setParserProperty( XMLReader::SUBST_ENTITIES, true );
 
index 7e8c2ba..07581d7 100644 (file)
@@ -405,7 +405,7 @@ class SqlBagOStuff extends BagOStuff {
                                $exptime = $this->convertExpiry( $exptime );
                                $encExpiry = $db->timestamp( $exptime );
                        }
-                       // (bug 24425) use a replace if the db supports it instead of
+                       // (T26425) use a replace if the db supports it instead of
                        // delete/insert to avoid clashes with conflicting keynames
                        $db->update(
                                $tableName,
@@ -480,7 +480,7 @@ class SqlBagOStuff extends BagOStuff {
                                ], __METHOD__, 'IGNORE' );
 
                        if ( $db->affectedRows() == 0 ) {
-                               // Race condition. See bug 28611
+                               // Race condition. See T30611
                                $newValue = null;
                        }
                } catch ( DBError $e ) {
index 2787c1b..e7a906d 100644 (file)
@@ -726,7 +726,7 @@ class Article implements Page {
 
                $ns = $this->getTitle()->getNamespace();
 
-               # Don't index user and user talk pages for blocked users (bug 11443)
+               # Don't index user and user talk pages for blocked users (T13443)
                if ( ( $ns == NS_USER || $ns == NS_USER_TALK ) && !$this->getTitle()->isSubpage() ) {
                        $specificTarget = null;
                        $vagueTarget = null;
@@ -784,7 +784,7 @@ class Article implements Page {
                }
 
                if ( isset( $wgArticleRobotPolicies[$this->getTitle()->getPrefixedText()] ) ) {
-                       # (bug 14900) site config can override user-defined __INDEX__ or __NOINDEX__
+                       # (T16900) site config can override user-defined __INDEX__ or __NOINDEX__
                        $policy = array_merge(
                                $policy,
                                self::formatRobotPolicy( $wgArticleRobotPolicies[$this->getTitle()->getPrefixedText()] )
index 53d7e55..f8202a6 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * Class for viewing MediaWiki file description pages
  *
@@ -213,7 +215,7 @@ class ImagePage extends Article {
                }
 
                $out->addModuleStyles( [
-                       'filepage', // always show the local local Filepage.css, bug 29277
+                       'filepage', // always show the local local Filepage.css, T31277
                        'mediawiki.action.view.filepage', // Add MediaWiki styles for a file page
                ] );
        }
@@ -534,7 +536,7 @@ class ImagePage extends Article {
                                // this will get messy.
                                // The dirmark, however, must not be immediately adjacent
                                // to the filename, because it can get copied with it.
-                               // See bug 25277.
+                               // See T27277.
                                // @codingStandardsIgnoreStart Ignore long line
                                $out->addWikiText( <<<EOT
 <div class="fullMedia"><span class="dangerousLink">{$medialink}</span> $dirmark<span class="fileInfo">$longDesc</span></div>
diff --git a/includes/page/PageAcrhive.php b/includes/page/PageAcrhive.php
new file mode 100644 (file)
index 0000000..388e693
--- /dev/null
@@ -0,0 +1,743 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\ResultWrapper;
+
+/**
+ * Used to show archived pages and eventually restore them.
+ */
+class PageArchive {
+       /** @var Title */
+       protected $title;
+
+       /** @var Status */
+       protected $fileStatus;
+
+       /** @var Status */
+       protected $revisionStatus;
+
+       /** @var Config */
+       protected $config;
+
+       public function __construct( $title, Config $config = null ) {
+               if ( is_null( $title ) ) {
+                       throw new MWException( __METHOD__ . ' given a null title.' );
+               }
+               $this->title = $title;
+               if ( $config === null ) {
+                       wfDebug( __METHOD__ . ' did not have a Config object passed to it' );
+                       $config = MediaWikiServices::getInstance()->getMainConfig();
+               }
+               $this->config = $config;
+       }
+
+       public function doesWrites() {
+               return true;
+       }
+
+       /**
+        * List all deleted pages recorded in the archive table. Returns result
+        * wrapper with (ar_namespace, ar_title, count) fields, ordered by page
+        * namespace/title.
+        *
+        * @return ResultWrapper
+        */
+       public static function listAllPages() {
+               $dbr = wfGetDB( DB_REPLICA );
+
+               return self::listPages( $dbr, '' );
+       }
+
+       /**
+        * List deleted pages recorded in the archive table matching the
+        * given title prefix.
+        * Returns result wrapper with (ar_namespace, ar_title, count) fields.
+        *
+        * @param string $prefix Title prefix
+        * @return ResultWrapper
+        */
+       public static function listPagesByPrefix( $prefix ) {
+               $dbr = wfGetDB( DB_REPLICA );
+
+               $title = Title::newFromText( $prefix );
+               if ( $title ) {
+                       $ns = $title->getNamespace();
+                       $prefix = $title->getDBkey();
+               } else {
+                       // Prolly won't work too good
+                       // @todo handle bare namespace names cleanly?
+                       $ns = 0;
+               }
+
+               $conds = [
+                       'ar_namespace' => $ns,
+                       'ar_title' . $dbr->buildLike( $prefix, $dbr->anyString() ),
+               ];
+
+               return self::listPages( $dbr, $conds );
+       }
+
+       /**
+        * @param IDatabase $dbr
+        * @param string|array $condition
+        * @return bool|ResultWrapper
+        */
+       protected static function listPages( $dbr, $condition ) {
+               return $dbr->select(
+                       [ 'archive' ],
+                       [
+                               'ar_namespace',
+                               'ar_title',
+                               'count' => 'COUNT(*)'
+                       ],
+                       $condition,
+                       __METHOD__,
+                       [
+                               'GROUP BY' => [ 'ar_namespace', 'ar_title' ],
+                               'ORDER BY' => [ 'ar_namespace', 'ar_title' ],
+                               'LIMIT' => 100,
+                       ]
+               );
+       }
+
+       /**
+        * List the revisions of the given page. Returns result wrapper with
+        * (ar_minor_edit, ar_timestamp, ar_user, ar_user_text, ar_comment) fields.
+        *
+        * @return ResultWrapper
+        */
+       public function listRevisions() {
+               $dbr = wfGetDB( DB_REPLICA );
+
+               $tables = [ 'archive' ];
+
+               $fields = [
+                       'ar_minor_edit', 'ar_timestamp', 'ar_user', 'ar_user_text',
+                       'ar_comment', 'ar_len', 'ar_deleted', 'ar_rev_id', 'ar_sha1',
+               ];
+
+               if ( $this->config->get( 'ContentHandlerUseDB' ) ) {
+                       $fields[] = 'ar_content_format';
+                       $fields[] = 'ar_content_model';
+               }
+
+               $conds = [ 'ar_namespace' => $this->title->getNamespace(),
+                       'ar_title' => $this->title->getDBkey() ];
+
+               $options = [ 'ORDER BY' => 'ar_timestamp DESC' ];
+
+               $join_conds = [];
+
+               ChangeTags::modifyDisplayQuery(
+                       $tables,
+                       $fields,
+                       $conds,
+                       $join_conds,
+                       $options,
+                       ''
+               );
+
+               return $dbr->select( $tables,
+                       $fields,
+                       $conds,
+                       __METHOD__,
+                       $options,
+                       $join_conds
+               );
+       }
+
+       /**
+        * List the deleted file revisions for this page, if it's a file page.
+        * Returns a result wrapper with various filearchive fields, or null
+        * if not a file page.
+        *
+        * @return ResultWrapper
+        * @todo Does this belong in Image for fuller encapsulation?
+        */
+       public function listFiles() {
+               if ( $this->title->getNamespace() != NS_FILE ) {
+                       return null;
+               }
+
+               $dbr = wfGetDB( DB_REPLICA );
+               return $dbr->select(
+                       'filearchive',
+                       ArchivedFile::selectFields(),
+                       [ 'fa_name' => $this->title->getDBkey() ],
+                       __METHOD__,
+                       [ 'ORDER BY' => 'fa_timestamp DESC' ]
+               );
+       }
+
+       /**
+        * Return a Revision object containing data for the deleted revision.
+        * Note that the result *may* or *may not* have a null page ID.
+        *
+        * @param string $timestamp
+        * @return Revision|null
+        */
+       public function getRevision( $timestamp ) {
+               $dbr = wfGetDB( DB_REPLICA );
+
+               $fields = [
+                       'ar_rev_id',
+                       'ar_text',
+                       'ar_comment',
+                       'ar_user',
+                       'ar_user_text',
+                       'ar_timestamp',
+                       'ar_minor_edit',
+                       'ar_flags',
+                       'ar_text_id',
+                       'ar_deleted',
+                       'ar_len',
+                       'ar_sha1',
+               ];
+
+               if ( $this->config->get( 'ContentHandlerUseDB' ) ) {
+                       $fields[] = 'ar_content_format';
+                       $fields[] = 'ar_content_model';
+               }
+
+               $row = $dbr->selectRow( 'archive',
+                       $fields,
+                       [ 'ar_namespace' => $this->title->getNamespace(),
+                               'ar_title' => $this->title->getDBkey(),
+                               'ar_timestamp' => $dbr->timestamp( $timestamp ) ],
+                       __METHOD__ );
+
+               if ( $row ) {
+                       return Revision::newFromArchiveRow( $row, [ 'title' => $this->title ] );
+               }
+
+               return null;
+       }
+
+       /**
+        * Return the most-previous revision, either live or deleted, against
+        * the deleted revision given by timestamp.
+        *
+        * May produce unexpected results in case of history merges or other
+        * unusual time issues.
+        *
+        * @param string $timestamp
+        * @return Revision|null Null when there is no previous revision
+        */
+       public function getPreviousRevision( $timestamp ) {
+               $dbr = wfGetDB( DB_REPLICA );
+
+               // Check the previous deleted revision...
+               $row = $dbr->selectRow( 'archive',
+                       'ar_timestamp',
+                       [ 'ar_namespace' => $this->title->getNamespace(),
+                               'ar_title' => $this->title->getDBkey(),
+                               'ar_timestamp < ' .
+                               $dbr->addQuotes( $dbr->timestamp( $timestamp ) ) ],
+                       __METHOD__,
+                       [
+                               'ORDER BY' => 'ar_timestamp DESC',
+                               'LIMIT' => 1 ] );
+               $prevDeleted = $row ? wfTimestamp( TS_MW, $row->ar_timestamp ) : false;
+
+               $row = $dbr->selectRow( [ 'page', 'revision' ],
+                       [ 'rev_id', 'rev_timestamp' ],
+                       [
+                               'page_namespace' => $this->title->getNamespace(),
+                               'page_title' => $this->title->getDBkey(),
+                               'page_id = rev_page',
+                               'rev_timestamp < ' .
+                               $dbr->addQuotes( $dbr->timestamp( $timestamp ) ) ],
+                       __METHOD__,
+                       [
+                               'ORDER BY' => 'rev_timestamp DESC',
+                               'LIMIT' => 1 ] );
+               $prevLive = $row ? wfTimestamp( TS_MW, $row->rev_timestamp ) : false;
+               $prevLiveId = $row ? intval( $row->rev_id ) : null;
+
+               if ( $prevLive && $prevLive > $prevDeleted ) {
+                       // Most prior revision was live
+                       return Revision::newFromId( $prevLiveId );
+               } elseif ( $prevDeleted ) {
+                       // Most prior revision was deleted
+                       return $this->getRevision( $prevDeleted );
+               }
+
+               // No prior revision on this page.
+               return null;
+       }
+
+       /**
+        * Get the text from an archive row containing ar_text, ar_flags and ar_text_id
+        *
+        * @param object $row Database row
+        * @return string
+        */
+       public function getTextFromRow( $row ) {
+               if ( is_null( $row->ar_text_id ) ) {
+                       // An old row from MediaWiki 1.4 or previous.
+                       // Text is embedded in this row in classic compression format.
+                       return Revision::getRevisionText( $row, 'ar_' );
+               }
+
+               // New-style: keyed to the text storage backend.
+               $dbr = wfGetDB( DB_REPLICA );
+               $text = $dbr->selectRow( 'text',
+                       [ 'old_text', 'old_flags' ],
+                       [ 'old_id' => $row->ar_text_id ],
+                       __METHOD__ );
+
+               return Revision::getRevisionText( $text );
+       }
+
+       /**
+        * Fetch (and decompress if necessary) the stored text of the most
+        * recently edited deleted revision of the page.
+        *
+        * If there are no archived revisions for the page, returns NULL.
+        *
+        * @return string|null
+        */
+       public function getLastRevisionText() {
+               $dbr = wfGetDB( DB_REPLICA );
+               $row = $dbr->selectRow( 'archive',
+                       [ 'ar_text', 'ar_flags', 'ar_text_id' ],
+                       [ 'ar_namespace' => $this->title->getNamespace(),
+                               'ar_title' => $this->title->getDBkey() ],
+                       __METHOD__,
+                       [ 'ORDER BY' => 'ar_timestamp DESC' ] );
+
+               if ( $row ) {
+                       return $this->getTextFromRow( $row );
+               }
+
+               return null;
+       }
+
+       /**
+        * Quick check if any archived revisions are present for the page.
+        *
+        * @return bool
+        */
+       public function isDeleted() {
+               $dbr = wfGetDB( DB_REPLICA );
+               $n = $dbr->selectField( 'archive', 'COUNT(ar_title)',
+                       [ 'ar_namespace' => $this->title->getNamespace(),
+                               'ar_title' => $this->title->getDBkey() ],
+                       __METHOD__
+               );
+
+               return ( $n > 0 );
+       }
+
+       /**
+        * Restore the given (or all) text and file revisions for the page.
+        * Once restored, the items will be removed from the archive tables.
+        * The deletion log will be updated with an undeletion notice.
+        *
+        * This also sets Status objects, $this->fileStatus and $this->revisionStatus
+        * (depending what operations are attempted).
+        *
+        * @param array $timestamps Pass an empty array to restore all revisions,
+        *   otherwise list the ones to undelete.
+        * @param string $comment
+        * @param array $fileVersions
+        * @param bool $unsuppress
+        * @param User $user User performing the action, or null to use $wgUser
+        * @param string|string[] $tags Change tags to add to log entry
+        *   ($user should be able to add the specified tags before this is called)
+        * @return array|bool array(number of file revisions restored, number of image revisions
+        *   restored, log message) on success, false on failure.
+        */
+       public function undelete( $timestamps, $comment = '', $fileVersions = [],
+               $unsuppress = false, User $user = null, $tags = null
+       ) {
+               // If both the set of text revisions and file revisions are empty,
+               // restore everything. Otherwise, just restore the requested items.
+               $restoreAll = empty( $timestamps ) && empty( $fileVersions );
+
+               $restoreText = $restoreAll || !empty( $timestamps );
+               $restoreFiles = $restoreAll || !empty( $fileVersions );
+
+               if ( $restoreFiles && $this->title->getNamespace() == NS_FILE ) {
+                       $img = wfLocalFile( $this->title );
+                       $img->load( File::READ_LATEST );
+                       $this->fileStatus = $img->restore( $fileVersions, $unsuppress );
+                       if ( !$this->fileStatus->isOK() ) {
+                               return false;
+                       }
+                       $filesRestored = $this->fileStatus->successCount;
+               } else {
+                       $filesRestored = 0;
+               }
+
+               if ( $restoreText ) {
+                       $this->revisionStatus = $this->undeleteRevisions( $timestamps, $unsuppress, $comment );
+                       if ( !$this->revisionStatus->isOK() ) {
+                               return false;
+                       }
+
+                       $textRestored = $this->revisionStatus->getValue();
+               } else {
+                       $textRestored = 0;
+               }
+
+               // Touch the log!
+
+               if ( $textRestored && $filesRestored ) {
+                       $reason = wfMessage( 'undeletedrevisions-files' )
+                               ->numParams( $textRestored, $filesRestored )->inContentLanguage()->text();
+               } elseif ( $textRestored ) {
+                       $reason = wfMessage( 'undeletedrevisions' )->numParams( $textRestored )
+                               ->inContentLanguage()->text();
+               } elseif ( $filesRestored ) {
+                       $reason = wfMessage( 'undeletedfiles' )->numParams( $filesRestored )
+                               ->inContentLanguage()->text();
+               } else {
+                       wfDebug( "Undelete: nothing undeleted...\n" );
+
+                       return false;
+               }
+
+               if ( trim( $comment ) != '' ) {
+                       $reason .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $comment;
+               }
+
+               if ( $user === null ) {
+                       global $wgUser;
+                       $user = $wgUser;
+               }
+
+               $logEntry = new ManualLogEntry( 'delete', 'restore' );
+               $logEntry->setPerformer( $user );
+               $logEntry->setTarget( $this->title );
+               $logEntry->setComment( $reason );
+               $logEntry->setTags( $tags );
+
+               Hooks::run( 'ArticleUndeleteLogEntry', [ $this, &$logEntry, $user ] );
+
+               $logid = $logEntry->insert();
+               $logEntry->publish( $logid );
+
+               return [ $textRestored, $filesRestored, $reason ];
+       }
+
+       /**
+        * This is the meaty bit -- It restores archived revisions of the given page
+        * to the revision table.
+        *
+        * @param array $timestamps Pass an empty array to restore all revisions,
+        *   otherwise list the ones to undelete.
+        * @param bool $unsuppress Remove all ar_deleted/fa_deleted restrictions of seletected revs
+        * @param string $comment
+        * @throws ReadOnlyError
+        * @return Status Status object containing the number of revisions restored on success
+        */
+       private function undeleteRevisions( $timestamps, $unsuppress = false, $comment = '' ) {
+               if ( wfReadOnly() ) {
+                       throw new ReadOnlyError();
+               }
+
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->startAtomic( __METHOD__ );
+
+               $restoreAll = empty( $timestamps );
+
+               # Does this page already exist? We'll have to update it...
+               $article = WikiPage::factory( $this->title );
+               # Load latest data for the current page (T33179)
+               $article->loadPageData( 'fromdbmaster' );
+               $oldcountable = $article->isCountable();
+
+               $page = $dbw->selectRow( 'page',
+                       [ 'page_id', 'page_latest' ],
+                       [ 'page_namespace' => $this->title->getNamespace(),
+                               'page_title' => $this->title->getDBkey() ],
+                       __METHOD__,
+                       [ 'FOR UPDATE' ] // lock page
+               );
+
+               if ( $page ) {
+                       $makepage = false;
+                       # Page already exists. Import the history, and if necessary
+                       # we'll update the latest revision field in the record.
+
+                       # Get the time span of this page
+                       $previousTimestamp = $dbw->selectField( 'revision', 'rev_timestamp',
+                               [ 'rev_id' => $page->page_latest ],
+                               __METHOD__ );
+
+                       if ( $previousTimestamp === false ) {
+                               wfDebug( __METHOD__ . ": existing page refers to a page_latest that does not exist\n" );
+
+                               $status = Status::newGood( 0 );
+                               $status->warning( 'undeleterevision-missing' );
+                               $dbw->endAtomic( __METHOD__ );
+
+                               return $status;
+                       }
+               } else {
+                       # Have to create a new article...
+                       $makepage = true;
+                       $previousTimestamp = 0;
+               }
+
+               $oldWhere = [
+                       'ar_namespace' => $this->title->getNamespace(),
+                       'ar_title' => $this->title->getDBkey(),
+               ];
+               if ( !$restoreAll ) {
+                       $oldWhere['ar_timestamp'] = array_map( [ &$dbw, 'timestamp' ], $timestamps );
+               }
+
+               $fields = [
+                       'ar_id',
+                       'ar_rev_id',
+                       'rev_id',
+                       'ar_text',
+                       'ar_comment',
+                       'ar_user',
+                       'ar_user_text',
+                       'ar_timestamp',
+                       'ar_minor_edit',
+                       'ar_flags',
+                       'ar_text_id',
+                       'ar_deleted',
+                       'ar_page_id',
+                       'ar_len',
+                       'ar_sha1'
+               ];
+
+               if ( $this->config->get( 'ContentHandlerUseDB' ) ) {
+                       $fields[] = 'ar_content_format';
+                       $fields[] = 'ar_content_model';
+               }
+
+               /**
+                * Select each archived revision...
+                */
+               $result = $dbw->select(
+                       [ 'archive', 'revision' ],
+                       $fields,
+                       $oldWhere,
+                       __METHOD__,
+                       /* options */
+                       [ 'ORDER BY' => 'ar_timestamp' ],
+                       [ 'revision' => [ 'LEFT JOIN', 'ar_rev_id=rev_id' ] ]
+               );
+
+               $rev_count = $result->numRows();
+               if ( !$rev_count ) {
+                       wfDebug( __METHOD__ . ": no revisions to restore\n" );
+
+                       $status = Status::newGood( 0 );
+                       $status->warning( "undelete-no-results" );
+                       $dbw->endAtomic( __METHOD__ );
+
+                       return $status;
+               }
+
+               // We use ar_id because there can be duplicate ar_rev_id even for the same
+               // page.  In this case, we may be able to restore the first one.
+               $restoreFailedArIds = [];
+
+               // Map rev_id to the ar_id that is allowed to use it.  When checking later,
+               // if it doesn't match, the current ar_id can not be restored.
+
+               // Value can be an ar_id or -1 (-1 means no ar_id can use it, since the
+               // rev_id is taken before we even start the restore).
+               $allowedRevIdToArIdMap = [];
+
+               $latestRestorableRow = null;
+
+               foreach ( $result as $row ) {
+                       if ( $row->ar_rev_id ) {
+                               // rev_id is taken even before we start restoring.
+                               if ( $row->ar_rev_id === $row->rev_id ) {
+                                       $restoreFailedArIds[] = $row->ar_id;
+                                       $allowedRevIdToArIdMap[$row->ar_rev_id] = -1;
+                               } else {
+                                       // rev_id is not taken yet in the DB, but it might be taken
+                                       // by a prior revision in the same restore operation. If
+                                       // not, we need to reserve it.
+                                       if ( isset( $allowedRevIdToArIdMap[$row->ar_rev_id] ) ) {
+                                               $restoreFailedArIds[] = $row->ar_id;
+                                       } else {
+                                               $allowedRevIdToArIdMap[$row->ar_rev_id] = $row->ar_id;
+                                               $latestRestorableRow = $row;
+                                       }
+                               }
+                       } else {
+                               // If ar_rev_id is null, there can't be a collision, and a
+                               // rev_id will be chosen automatically.
+                               $latestRestorableRow = $row;
+                       }
+               }
+
+               $result->seek( 0 ); // move back
+
+               $oldPageId = 0;
+               if ( $latestRestorableRow !== null ) {
+                       $oldPageId = (int)$latestRestorableRow->ar_page_id; // pass this to ArticleUndelete hook
+
+                       // grab the content to check consistency with global state before restoring the page.
+                       $revision = Revision::newFromArchiveRow( $latestRestorableRow,
+                               [
+                                       'title' => $article->getTitle(), // used to derive default content model
+                               ]
+                       );
+                       $user = User::newFromName( $revision->getUserText( Revision::RAW ), false );
+                       $content = $revision->getContent( Revision::RAW );
+
+                       // NOTE: article ID may not be known yet. prepareSave() should not modify the database.
+                       $status = $content->prepareSave( $article, 0, -1, $user );
+                       if ( !$status->isOK() ) {
+                               $dbw->endAtomic( __METHOD__ );
+
+                               return $status;
+                       }
+               }
+
+               $newid = false; // newly created page ID
+               $restored = 0; // number of revisions restored
+               /** @var Revision $revision */
+               $revision = null;
+
+               // If there are no restorable revisions, we can skip most of the steps.
+               if ( $latestRestorableRow === null ) {
+                       $failedRevisionCount = $rev_count;
+               } else {
+                       if ( $makepage ) {
+                               // Check the state of the newest to-be version...
+                               if ( !$unsuppress
+                                       && ( $latestRestorableRow->ar_deleted & Revision::DELETED_TEXT )
+                               ) {
+                                       $dbw->endAtomic( __METHOD__ );
+
+                                       return Status::newFatal( "undeleterevdel" );
+                               }
+                               // Safe to insert now...
+                               $newid = $article->insertOn( $dbw, $latestRestorableRow->ar_page_id );
+                               if ( $newid === false ) {
+                                       // The old ID is reserved; let's pick another
+                                       $newid = $article->insertOn( $dbw );
+                               }
+                               $pageId = $newid;
+                       } else {
+                               // Check if a deleted revision will become the current revision...
+                               if ( $latestRestorableRow->ar_timestamp > $previousTimestamp ) {
+                                       // Check the state of the newest to-be version...
+                                       if ( !$unsuppress
+                                               && ( $latestRestorableRow->ar_deleted & Revision::DELETED_TEXT )
+                                       ) {
+                                               $dbw->endAtomic( __METHOD__ );
+
+                                               return Status::newFatal( "undeleterevdel" );
+                                       }
+                               }
+
+                               $newid = false;
+                               $pageId = $article->getId();
+                       }
+
+                       foreach ( $result as $row ) {
+                               // Check for key dupes due to needed archive integrity.
+                               if ( $row->ar_rev_id && $allowedRevIdToArIdMap[$row->ar_rev_id] !== $row->ar_id ) {
+                                       continue;
+                               }
+                               // Insert one revision at a time...maintaining deletion status
+                               // unless we are specifically removing all restrictions...
+                               $revision = Revision::newFromArchiveRow( $row,
+                                       [
+                                               'page' => $pageId,
+                                               'title' => $this->title,
+                                               'deleted' => $unsuppress ? 0 : $row->ar_deleted
+                                       ] );
+
+                               $revision->insertOn( $dbw );
+                               $restored++;
+
+                               Hooks::run( 'ArticleRevisionUndeleted',
+                                       [ &$this->title, $revision, $row->ar_page_id ] );
+                       }
+
+                       // Now that it's safely stored, take it out of the archive
+                       // Don't delete rows that we failed to restore
+                       $toDeleteConds = $oldWhere;
+                       $failedRevisionCount = count( $restoreFailedArIds );
+                       if ( $failedRevisionCount > 0 ) {
+                               $toDeleteConds[] = 'ar_id NOT IN ( ' . $dbw->makeList( $restoreFailedArIds ) . ' )';
+                       }
+
+                       $dbw->delete( 'archive',
+                               $toDeleteConds,
+                               __METHOD__ );
+               }
+
+               $status = Status::newGood( $restored );
+
+               if ( $failedRevisionCount > 0 ) {
+                       $status->warning(
+                               wfMessage( 'undeleterevision-duplicate-revid', $failedRevisionCount ) );
+               }
+
+               // Was anything restored at all?
+               if ( $restored ) {
+                       $created = (bool)$newid;
+                       // Attach the latest revision to the page...
+                       $wasnew = $article->updateIfNewerOn( $dbw, $revision );
+                       if ( $created || $wasnew ) {
+                               // Update site stats, link tables, etc
+                               $article->doEditUpdates(
+                                       $revision,
+                                       User::newFromName( $revision->getUserText( Revision::RAW ), false ),
+                                       [
+                                               'created' => $created,
+                                               'oldcountable' => $oldcountable,
+                                               'restored' => true
+                                       ]
+                               );
+                       }
+
+                       Hooks::run( 'ArticleUndelete', [ &$this->title, $created, $comment, $oldPageId ] );
+                       if ( $this->title->getNamespace() == NS_FILE ) {
+                               DeferredUpdates::addUpdate( new HTMLCacheUpdate( $this->title, 'imagelinks' ) );
+                       }
+               }
+
+               $dbw->endAtomic( __METHOD__ );
+
+               return $status;
+       }
+
+       /**
+        * @return Status
+        */
+       public function getFileStatus() {
+               return $this->fileStatus;
+       }
+
+       /**
+        * @return Status
+        */
+       public function getRevisionStatus() {
+               return $this->revisionStatus;
+       }
+}
index 1fa4bfa..e4b524b 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use Wikimedia\Rdbms\FakeResultWrapper;
+
 /**
  * Special handling for file pages
  *
index bc936ab..4bc8ad6 100644 (file)
@@ -22,6 +22,7 @@
 
 use \MediaWiki\Logger\LoggerFactory;
 use \MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\FakeResultWrapper;
 
 /**
  * Class representing a MediaWiki article and history.
@@ -151,7 +152,7 @@ class WikiPage implements Page, IDBAccessObject {
         * @return WikiPage|null
         */
        public static function newFromID( $id, $from = 'fromdb' ) {
-               // page id's are never 0 or negative, see bug 61166
+               // page ids are never 0 or negative, see T63166
                if ( $id < 1 ) {
                        return null;
                }
@@ -257,7 +258,7 @@ class WikiPage implements Page, IDBAccessObject {
                $this->mTimestamp = '';
                $this->mIsRedirect = false;
                $this->mLatest = false;
-               // Bug 57026: do not clear mPreparedEdit since prepareTextForEdit() already checks
+               // T59026: do not clear mPreparedEdit since prepareTextForEdit() already checks
                // the requested rev ID and content against the cached one for equality. For most
                // content types, the output should not change during the lifetime of this cache.
                // Clearing it can cause extra parses on edit for no reason.
@@ -424,7 +425,7 @@ class WikiPage implements Page, IDBAccessObject {
                        $this->mLinksUpdated = wfTimestampOrNull( TS_MW, $data->page_links_updated );
                        $this->mIsRedirect = intval( $data->page_is_redirect );
                        $this->mLatest = intval( $data->page_latest );
-                       // Bug 37225: $latest may no longer match the cached latest Revision object.
+                       // T39225: $latest may no longer match the cached latest Revision object.
                        // Double-check the ID of any cached latest Revision object for consistency.
                        if ( $this->mLastRevision && $this->mLastRevision->getId() != $this->mLatest ) {
                                $this->mLastRevision = null;
@@ -619,7 +620,7 @@ class WikiPage implements Page, IDBAccessObject {
                }
 
                if ( $this->mDataLoadedFrom == self::READ_LOCKING ) {
-                       // Bug 37225: if session S1 loads the page row FOR UPDATE, the result always
+                       // T39225: if session S1 loads the page row FOR UPDATE, the result always
                        // includes the latest changes committed. This is true even within REPEATABLE-READ
                        // transactions, where S1 normally only sees changes committed before the first S1
                        // SELECT. Thus we need S1 to also gets the revision row FOR UPDATE; otherwise, it
@@ -1460,7 +1461,7 @@ class WikiPage implements Page, IDBAccessObject {
                                        $this->getContentHandler()->getModelID() );
                        }
 
-                       // Bug 30711: always use current version when adding a new section
+                       // T32711: always use current version when adding a new section
                        if ( is_null( $baseRevId ) || $sectionId === 'new' ) {
                                $oldContent = $this->getContent();
                        } else {
@@ -1695,7 +1696,7 @@ class WikiPage implements Page, IDBAccessObject {
 
                        return $status;
                } elseif ( !$oldContent ) {
-                       // Sanity check for bug 37225
+                       // Sanity check for T39225
                        throw new MWException( "Could not find text for current revision {$oldid}." );
                }
 
@@ -1783,7 +1784,7 @@ class WikiPage implements Page, IDBAccessObject {
                        $dbw->endAtomic( __METHOD__ );
                        $this->mTimestamp = $now;
                } else {
-                       // Bug 32948: revision ID must be set to page {{REVISIONID}} and
+                       // T34948: revision ID must be set to page {{REVISIONID}} and
                        // related variables correctly. Likewise for {{REVISIONUSER}} (T135261).
                        $revision->setId( $this->getLatest() );
                        $revision->setUserIdAndName(
@@ -2023,7 +2024,7 @@ class WikiPage implements Page, IDBAccessObject {
                $user = is_null( $user ) ? $wgUser : $user;
                // XXX: check $user->getId() here???
 
-               // Use a sane default for $serialFormat, see bug 57026
+               // Use a sane default for $serialFormat, see T59026
                if ( $serialFormat === null ) {
                        $serialFormat = $content->getContentHandler()->getDefaultFormat();
                }
@@ -2195,7 +2196,7 @@ class WikiPage implements Page, IDBAccessObject {
 
                // Update the links tables and other secondary data
                if ( $content ) {
-                       $recursive = $options['changed']; // bug 50785
+                       $recursive = $options['changed']; // T52785
                        $updates = $content->getSecondaryDataUpdates(
                                $this->getTitle(), null, $recursive, $editInfo->output
                        );
@@ -2297,7 +2298,7 @@ class WikiPage implements Page, IDBAccessObject {
 
                if ( $options['created'] ) {
                        self::onArticleCreate( $this->mTitle );
-               } elseif ( $options['changed'] ) { // bug 50785
+               } elseif ( $options['changed'] ) { // T52785
                        self::onArticleEdit( $this->mTitle, $revision );
                }
 
@@ -2911,7 +2912,7 @@ class WikiPage implements Page, IDBAccessObject {
 
                $dbw->onTransactionPreCommitOrIdle(
                        function () use ( $dbw, $logEntry, $logid ) {
-                               // Bug 56776: avoid deadlocks (especially from FileDeleteForm)
+                               // T58776: avoid deadlocks (especially from FileDeleteForm)
                                $logEntry->publish( $logid );
                        },
                        __METHOD__
@@ -3191,7 +3192,7 @@ class WikiPage implements Page, IDBAccessObject {
                );
 
                // Set patrolling and bot flag on the edits, which gets rollbacked.
-               // This is done even on edit failure to have patrolling in that case (bug 62157).
+               // This is done even on edit failure to have patrolling in that case (T64157).
                $set = [];
                if ( $bot && $guser->isAllowed( 'markbotedits' ) ) {
                        // Mark all reverted edits as bot
index 395cee5..dc302a2 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Pager
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * IndexPager is an efficient pager which uses a (roughly unique) index in the
  * data set to implement paging, rather than a "LIMIT offset,limit" clause.
index 6f325c9..76f3470 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  * @ingroup Pager
  */
+use Wikimedia\Timestamp\TimestampException;
 
 /**
  * IndexPager with a formatted navigation bar
index 2ef599a..2023d13 100644 (file)
@@ -299,7 +299,7 @@ class BlockLevelPass {
 
                                if ( $openMatch || $closeMatch ) {
                                        $pendingPTag = false;
-                                       # @todo bug 5718: paragraph closed
+                                       # @todo T7718: paragraph closed
                                        $output .= $this->closeParagraph();
                                        if ( $preOpenMatch && !$preCloseMatch ) {
                                                $this->inPre = true;
@@ -353,7 +353,7 @@ class BlockLevelPass {
                                        }
                                }
                        }
-                       # somewhere above we forget to get out of pre block (bug 785)
+                       # somewhere above we forget to get out of pre block (T2785)
                        if ( $preCloseMatch && $this->inPre ) {
                                $this->inPre = false;
                        }
index 6aa3acc..e34d10b 100644 (file)
@@ -157,7 +157,7 @@ class CoreParserFunctions {
        }
 
        /**
-        * urlencodes a string according to one of three patterns: (bug 22474)
+        * urlencodes a string according to one of three patterns: (T24474)
         *
         * By default (for HTTP "query" strings), spaces are encoded as '+'.
         * Or to encode a value for the HTTP "path", spaces are encoded as '%20'.
index 76ee525..605a873 100644 (file)
@@ -107,7 +107,7 @@ class DateFormatter {
                $this->targets[self::ISO2] = '[[y-m-d]]';
 
                # Rules
-               #            pref    source       target
+               #            pref       source      target
                $this->rules[self::DMY][self::MD] = self::DM;
                $this->rules[self::ALL][self::MD] = self::MD;
                $this->rules[self::MDY][self::DM] = self::MD;
@@ -127,7 +127,7 @@ class DateFormatter {
         * Get a DateFormatter object
         *
         * @param Language|string|null $lang In which language to format the date
-        *              Defaults to the site content language
+        *     Defaults to the site content language
         * @return DateFormatter
         */
        public static function getInstance( $lang = null ) {
index 86aa06a..8db1fe3 100644 (file)
@@ -89,13 +89,15 @@ class Parser {
        # Everything except bracket, space, or control characters
        # \p{Zs} is unicode 'separator, space' category. It covers the space 0x20
        # as well as U+3000 is IDEOGRAPHIC SPACE for T21052
-       const EXT_LINK_URL_CLASS = '[^][<>"\\x00-\\x20\\x7F\p{Zs}]';
+       # \x{FFFD} is the Unicode replacement character, which Preprocessor_DOM
+       # uses to replace invalid HTML characters.
+       const EXT_LINK_URL_CLASS = '[^][<>"\\x00-\\x20\\x7F\p{Zs}\x{FFFD}]';
        # Simplified expression to match an IPv4 or IPv6 address, or
        # at least one character of a host name (embeds EXT_LINK_URL_CLASS)
-       const EXT_LINK_ADDR = '(?:[0-9.]+|\\[(?i:[0-9a-f:.]+)\\]|[^][<>"\\x00-\\x20\\x7F\p{Zs}])';
+       const EXT_LINK_ADDR = '(?:[0-9.]+|\\[(?i:[0-9a-f:.]+)\\]|[^][<>"\\x00-\\x20\\x7F\p{Zs}\x{FFFD}])';
        # RegExp to make image URLs (embeds IPv6 part of EXT_LINK_ADDR)
        // @codingStandardsIgnoreStart Generic.Files.LineLength
-       const EXT_IMAGE_REGEX = '/^(http:\/\/|https:\/\/)((?:\\[(?i:[0-9a-f:.]+)\\])?[^][<>"\\x00-\\x20\\x7F\p{Zs}]+)
+       const EXT_IMAGE_REGEX = '/^(http:\/\/|https:\/\/)((?:\\[(?i:[0-9a-f:.]+)\\])?[^][<>"\\x00-\\x20\\x7F\p{Zs}\x{FFFD}]+)
                \\/([A-Za-z0-9_.,~%\\-+&;#*?!=()@\\x80-\\xFF]+)\\.((?i)gif|png|jpg|jpeg)$/Sxu';
        // @codingStandardsIgnoreEnd
 
@@ -264,7 +266,7 @@ class Parser {
                $this->mUrlProtocols = wfUrlProtocols();
                $this->mExtLinkBracketedRegex = '/\[(((?i)' . $this->mUrlProtocols . ')' .
                        self::EXT_LINK_ADDR .
-                       self::EXT_LINK_URL_CLASS . '*)\p{Zs}*([^\]\\x00-\\x08\\x0a-\\x1F]*?)\]/Su';
+                       self::EXT_LINK_URL_CLASS . '*)\p{Zs}*([^\]\\x00-\\x08\\x0a-\\x1F\\x{FFFD}]*?)\]/Su';
                if ( isset( $conf['preprocessorClass'] ) ) {
                        $this->mPreprocessorClass = $conf['preprocessorClass'];
                } elseif ( defined( 'HPHP_VERSION' ) ) {
@@ -417,6 +419,8 @@ class Parser {
                        $text = strtr( $text, "\x7f", "?" );
                        $magicScopeVariable = $this->lock();
                }
+               // Strip U+0000 NULL (T159174)
+               $text = str_replace( "\000", '', $text );
 
                $this->startParse( $title, $options, self::OT_HTML, $clearState );
 
@@ -1450,15 +1454,16 @@ class Parser {
                $spdash = "(?:-|$space)"; # a dash or a non-newline space
                $spaces = "$space++"; # possessive match of 1 or more spaces
                $text = preg_replace_callback(
-                       '!(?:                            # Start cases
-                               (<a[ \t\r\n>].*?</a>) |      # m[1]: Skip link text
-                               (<.*?>) |                    # m[2]: Skip stuff inside
-                                                            #       HTML elements' . "
-                               (\b(?i:$prots)($addr$urlChar*)) | # m[3]: Free external links
-                                                            # m[4]: Post-protocol path
-                               \b(?:RFC|PMID) $spaces       # m[5]: RFC or PMID, capture number
+                       '!(?:                        # Start cases
+                               (<a[ \t\r\n>].*?</a>) |    # m[1]: Skip link text
+                               (<.*?>) |                  # m[2]: Skip stuff inside HTML elements' . "
+                               (\b                        # m[3]: Free external links
+                                       (?i:$prots)
+                                       ($addr$urlChar*)         # m[4]: Post-protocol path
+                               ) |
+                               \b(?:RFC|PMID) $spaces     # m[5]: RFC or PMID, capture number
                                        ([0-9]+)\b |
-                               \bISBN $spaces (             # m[6]: ISBN, capture number
+                               \bISBN $spaces (           # m[6]: ISBN, capture number
                                        (?: 97[89] $spdash? )?   #  optional 13-digit ISBN prefix
                                        (?: [0-9]  $spdash? ){9} #  9 digits with opt. delimiters
                                        [0-9Xx]                  #  check digit
@@ -4462,6 +4467,9 @@ class Parser {
                $this->startParse( $title, $options, self::OT_WIKI, $clearState );
                $this->setUser( $user );
 
+               // Strip U+0000 NULL (T159174)
+               $text = str_replace( "\000", '', $text );
+
                // We still normalize line endings for backwards-compatibility
                // with other code that just calls PST, but this should already
                // be handled in TextContent subclasses
index 9e96540..f76c0b5 100644 (file)
@@ -223,7 +223,7 @@ class ParserCache {
 
                // The edit section preference may not be the appropiate one in
                // the ParserOutput, as we are not storing it in the parsercache
-               // key. Force it here. See bug 31445.
+               // key. Force it here. See T33445.
                $value->setEditSectionTokens( $popts->getEditSection() );
 
                $wikiPage = method_exists( $article, 'getPage' )
index 2900f41..7be8281 100644 (file)
@@ -409,7 +409,7 @@ class ParserOptions {
         * when the page is rendered based on the language of the user.
         *
         * @note When saving, this will return the default language instead of the user's.
-        * {{int: }} uses this which used to produce inconsistent link tables (bug 14404).
+        * {{int: }} uses this which used to produce inconsistent link tables (T16404).
         *
         * @return Language
         * @since 1.19
index 0c162b4..b2f99b3 100644 (file)
@@ -709,7 +709,7 @@ class ParserOutput extends CacheTime {
                        return false;
                }
 
-               // Important to parse with correct title (bug 31469)
+               // Important to parse with correct title (T33469)
                $cat = wfMessage( $msg )
                        ->title( $title )
                        ->inContentLanguage()
index 661318b..b93c617 100644 (file)
@@ -134,7 +134,7 @@ class Preprocessor_DOM extends Preprocessor {
         *                                is to assume a direct page view.
         *
         * The generated DOM tree must depend only on the input text and the flags.
-        * The DOM tree must be the same in OT_HTML and OT_WIKI mode, to avoid a regression of bug 4899.
+        * The DOM tree must be the same in OT_HTML and OT_WIKI mode, to avoid a regression of T6899.
         *
         * Any flag added to the $flags parameter here, or any other parameter liable to cause a
         * change in the DOM tree for a given text, must be passed through the section identifier
index 2666c93..b2e9531 100644 (file)
@@ -107,7 +107,7 @@ class Preprocessor_Hash extends Preprocessor {
         *                                 included. Default is to assume a direct page view.
         *
         * The generated DOM tree must depend only on the input text and the flags.
-        * The DOM tree must be the same in OT_HTML and OT_WIKI mode, to avoid a regression of bug 4899.
+        * The DOM tree must be the same in OT_HTML and OT_WIKI mode, to avoid a regression of T6899.
         *
         * Any flag added to the $flags parameter here, or any other parameter liable to cause a
         * change in the DOM tree for a given text, must be passed through the section identifier
index 534e86b..1f1add7 100644 (file)
@@ -129,7 +129,7 @@ class PoolWorkArticleView extends PoolCounterWork {
                        return false;
                }
 
-               // Reduce effects of race conditions for slow parses (bug 46014)
+               // Reduce effects of race conditions for slow parses (T48014)
                $cacheTime = wfTimestampNow();
 
                $time = - microtime( true );
index 088721c..264ec0c 100644 (file)
@@ -41,7 +41,7 @@ class ProfilerOutputDb extends ProfilerOutput {
        }
 
        public function canUse() {
-               # Do not log anything if database is readonly (bug 5375)
+               # Do not log anything if database is readonly (T7375)
                return !wfReadOnly();
        }
 
index a4100bb..210deb1 100644 (file)
@@ -23,11 +23,11 @@ interface Processor {
 
        /**
         * @return array With following keys:
-        *              'globals' - variables to be set to $GLOBALS
-        *              'defines' - constants to define
-        *              'callbacks' - functions to be executed by the registry
-        *              'credits' - metadata to be stored by registry
-        *              'attributes' - registration info which isn't a global variable
+        *     'globals' - variables to be set to $GLOBALS
+        *     'defines' - constants to define
+        *     'callbacks' - functions to be executed by the registry
+        *     'credits' - metadata to be stored by registry
+        *     'attributes' - registration info which isn't a global variable
         */
        public function getExtractedInfo();
 
index 5aaaa1b..a31551c 100644 (file)
@@ -87,17 +87,17 @@ class VersionChecker {
         * installed extensions in the $credits array.
         *
         * Example $extDependencies:
-        *      {
-        *              'FooBar' => {
-        *                      'MediaWiki' => '>= 1.25.0',
-        *                      'extensions' => {
-        *                              'FooBaz' => '>= 1.25.0'
-        *                      },
-        *                      'skins' => {
-        *                              'BazBar' => '>= 1.0.0'
-        *                      }
-        *              }
-        *      }
+        *     {
+        *       'FooBar' => {
+        *         'MediaWiki' => '>= 1.25.0',
+        *         'extensions' => {
+        *           'FooBaz' => '>= 1.25.0'
+        *         },
+        *         'skins' => {
+        *           'BazBar' => '>= 1.0.0'
+        *         }
+        *       }
+        *     }
         *
         * @param array $extDependencies All extensions that depend on other ones
         * @return array
index 59c60df..717fb45 100644 (file)
@@ -714,7 +714,7 @@ class ResourceLoader implements LoggerAwareInterface {
                        $module = $this->getModule( $name );
                        if ( $module ) {
                                // Do not allow private modules to be loaded from the web.
-                               // This is a security issue, see bug 34907.
+                               // This is a security issue, see T36907.
                                if ( $module->getGroup() === 'private' ) {
                                        $this->logger->debug( "Request for private module '$name' denied" );
                                        $this->errors[] = "Cannot show private module \"$name\"";
@@ -1217,7 +1217,7 @@ MESSAGE;
                        $styles = (array)$styles;
                        foreach ( $styles as $style ) {
                                $style = trim( $style );
-                               // Don't output an empty "@media print { }" block (bug 40498)
+                               // Don't output an empty "@media print { }" block (T42498)
                                if ( $style !== '' ) {
                                        // Transform the media type based on request params and config
                                        // The way that this relies on $wgRequest to propagate request params is slightly evil
@@ -1634,7 +1634,7 @@ MESSAGE;
         */
        public function getLessCompiler( $extraVars = [] ) {
                // When called from the installer, it is possible that a required PHP extension
-               // is missing (at least for now; see bug 47564). If this is the case, throw an
+               // 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.
                if ( !class_exists( 'Less_Parser' ) ) {
                        throw new MWException( 'MediaWiki requires the less.php parser' );
index 29f8cfe..8c792ad 100644 (file)
@@ -417,7 +417,7 @@ class ResourceLoaderClientHtml {
                                // Special handling for the user group; because users might change their stuff
                                // on-wiki like user pages, or user preferences; we need to find the highest
                                // timestamp of these user-changeable modules so we can ensure cache misses on change
-                               // This should NOT be done for the site group (bug 27564) because anons get that too
+                               // This should NOT be done for the site group (T29564) because anons get that too
                                // and we shouldn't be putting timestamps in CDN-cached HTML
                                if ( $group === 'user' ) {
                                        // Must setModules() before makeVersionQuery()
index a1a89cb..8955b8c 100644 (file)
@@ -197,7 +197,7 @@ class ResourceLoaderContext {
                if ( $this->direction === null ) {
                        $this->direction = $this->getRequest()->getRawVal( 'dir' );
                        if ( !$this->direction ) {
-                               // Determine directionality based on user language (bug 6100)
+                               // Determine directionality based on user language (T8100)
                                $this->direction = Language::factory( $this->getLanguage() )->getDir();
                        }
                }
index 6d2bc0d..d4dabe7 100644 (file)
@@ -651,7 +651,7 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
                                        && substr( rtrim( $scripts ), -1 ) !== ';'
                                ) {
                                        // Append semicolon to prevent weird bugs caused by files not
-                                       // terminating their statements right (bug 27054)
+                                       // terminating their statements right (T29054)
                                        $scripts .= ";\n";
                                }
                        }
@@ -662,7 +662,7 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
                if ( $context->shouldIncludeStyles() ) {
                        $styles = [];
                        // Don't create empty stylesheets like [ '' => '' ] for modules
-                       // that don't *have* any stylesheets (bug 38024).
+                       // that don't *have* any stylesheets (T40024).
                        $stylePairs = $this->getStyles( $context );
                        if ( count( $stylePairs ) ) {
                                // If we are in debug mode without &only= set, we'll want to return an array of URLs
index a99305c..48e4a0d 100644 (file)
@@ -82,7 +82,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                        'wgSearchType' => $conf->get( 'SearchType' ),
                        'wgVariantArticlePath' => $conf->get( 'VariantArticlePath' ),
                        // Force object to avoid "empty" associative array from
-                       // becoming [] instead of {} in JS (bug 34604)
+                       // becoming [] instead of {} in JS (T36604)
                        'wgActionPaths' => (object)$conf->get( 'ActionPaths' ),
                        'wgServer' => $conf->get( 'Server' ),
                        'wgServerName' => $conf->get( 'ServerName' ),
index e8574f4..b0d060b 100644 (file)
@@ -268,7 +268,7 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
                        return true;
                }
 
-               // Bug 68488: For other modules (i.e. ones that are called in cached html output) only check
+               // T70488: For other modules (i.e. ones that are called in cached html output) only check
                // page existance. This ensures that, if some pages in a module are temporarily blanked,
                // we don't end omit the module's script or link tag on some pages.
                return count( $revisions ) === 0;
index f0b1907..453c6cc 100644 (file)
@@ -19,6 +19,8 @@
  * @ingroup RevisionDelete
  */
 
+use Wikimedia\Rdbms\FakeResultWrapper;
+
 /**
  * List for revision table items
  *
index 8a06b65..910fd77 100644 (file)
@@ -93,7 +93,7 @@ abstract class SearchIndexFieldDefinition implements SearchIndexField {
        public function merge( SearchIndexField $that ) {
                // TODO: which definitions may be compatible?
                if ( ( $that instanceof self ) && $this->type === $that->type &&
-                    $this->flags === $that->flags && $this->type !== self::INDEX_TYPE_NESTED
+                       $this->flags === $that->flags && $this->type !== self::INDEX_TYPE_NESTED
                ) {
                        return $that;
                }
index c3985d1..53d09e8 100644 (file)
@@ -1,4 +1,7 @@
 <?php
+
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * This class is used for different SQL-based search engines shipped with MediaWiki
  * @ingroup Search
index 3ab0f43..c6990fe 100644 (file)
@@ -91,9 +91,9 @@ interface SessionManagerInterface extends LoggerAwareInterface {
         *
         * The return value is such that someone could theoretically do this:
         * @code
-        *  foreach ( $provider->getVaryHeaders() as $header => $options ) {
-        *      $outputPage->addVaryHeader( $header, $options );
-        *  }
+        * foreach ( $provider->getVaryHeaders() as $header => $options ) {
+        *   $outputPage->addVaryHeader( $header, $options );
+        * }
         * @endcode
         *
         * @return array
index 61c7500..e8d81cb 100644 (file)
@@ -397,9 +397,9 @@ abstract class SessionProvider implements SessionProviderInterface, LoggerAwareI
         *
         * The return value is such that someone could theoretically do this:
         * @code
-        *  foreach ( $provider->getVaryHeaders() as $header => $options ) {
-        *      $outputPage->addVaryHeader( $header, $options );
-        *  }
+        * foreach ( $provider->getVaryHeaders() as $header => $options ) {
+        *   $outputPage->addVaryHeader( $header, $options );
+        * }
         * @endcode
         *
         * @protected For use by \MediaWiki\Session\SessionManager only
index eef421c..e571c58 100644 (file)
@@ -324,12 +324,12 @@ abstract class BaseTemplate extends QuickTemplate {
         *
         * If a "data" key is present, it must be an array, where the keys represent
         * the data-xxx properties with their provided values. For example,
-        *  $item['data'] = [
-        *       'foo' => 1,
-        *       'bar' => 'baz',
-        *  ];
+        *     $item['data'] = [
+        *       'foo' => 1,
+        *       'bar' => 'baz',
+        *     ];
         * will render as element properties:
-        *  data-foo='1' data-bar='baz'
+        *     data-foo='1' data-bar='baz'
         *
         * @param array $options Can be used to affect the output of a link.
         * Possible options are:
@@ -648,7 +648,7 @@ abstract class BaseTemplate extends QuickTemplate {
         * @since 1.25
         */
        public function getIndicators() {
-               $out = "<div class=\"mw-indicators\">\n";
+               $out = "<div class=\"mw-indicators mw-body-content\">\n";
                foreach ( $this->data['indicators'] as $id => $content ) {
                        $out .= Html::rawElement(
                                'div',
index 96812ea..a7740a0 100644 (file)
@@ -381,7 +381,7 @@ abstract class Skin extends ContextSource {
 
                if ( $title->isSpecialPage() ) {
                        $type = 'ns-special';
-                       // bug 23315: provide a class based on the canonical special page name without subpages
+                       // T25315: provide a class based on the canonical special page name without subpages
                        list( $canonicalName ) = SpecialPageFactory::resolveAlias( $title->getDBkey() );
                        if ( $canonicalName ) {
                                $type .= ' ' . Sanitizer::escapeClass( "mw-special-$canonicalName" );
@@ -906,7 +906,10 @@ abstract class Skin extends ContextSource {
                                $html = htmlspecialchars( $icon["alt"] );
                        }
                        if ( $url ) {
-                               $html = Html::rawElement( 'a', [ "href" => $url ], $html );
+                               global $wgExternalLinkTarget;
+                               $html = Html::rawElement( 'a',
+                                       [ "href" => $url, "target" => $wgExternalLinkTarget ],
+                                       $html );
                        }
                }
                return $html;
@@ -1283,7 +1286,7 @@ abstract class Skin extends ContextSource {
                                        $line = array_map( 'trim', explode( '|', $line, 2 ) );
                                        if ( count( $line ) !== 2 ) {
                                                // Second sanity check, could be hit by people doing
-                                               // funky stuff with parserfuncs... (bug 33321)
+                                               // funky stuff with parserfuncs... (T35321)
                                                continue;
                                        }
 
@@ -1538,7 +1541,7 @@ abstract class Skin extends ContextSource {
 
                $attribs = [];
                if ( !is_null( $tooltip ) ) {
-                       # Bug 25462: undo double-escaping.
+                       # T27462: undo double-escaping.
                        $tooltip = Sanitizer::decodeCharReferences( $tooltip );
                        $attribs['title'] = wfMessage( 'editsectionhint' )->rawParams( $tooltip )
                                ->inLanguage( $lang )->text();
index bc6dfca..780fac4 100644 (file)
@@ -582,7 +582,7 @@ class SkinTemplate extends Skin {
                /* set up the default links for the personal toolbar */
                $personal_urls = [];
 
-               # Due to bug 32276, if a user does not have read permissions,
+               # Due to T34276, if a user does not have read permissions,
                # $this->getTitle() will just give Special:Badtitle, which is
                # not especially useful as a returnto parameter. Use the title
                # from the request instead, if there was one.
@@ -663,7 +663,7 @@ class SkinTemplate extends Skin {
                                        'text' => $this->msg( 'pt-userlogout' )->text(),
                                        'href' => self::makeSpecialUrl( 'Userlogout',
                                                // userlogout link must always contain an & character, otherwise we might not be able
-                                               // to detect a buggy precaching proxy (bug 17790)
+                                               // to detect a buggy precaching proxy (T19790)
                                                $title->isSpecial( 'Preferences' ) ? 'noreturnto' : $returnto ),
                                        'active' => false
                                ];
@@ -1120,7 +1120,7 @@ class SkinTemplate extends Skin {
                        $content_navigation['namespaces']['special'] = [
                                'class' => 'selected',
                                'text' => $this->msg( 'nstab-special' )->text(),
-                               'href' => $request->getRequestURL(), // @see: bug 2457, bug 2510
+                               'href' => $request->getRequestURL(), // @see: T4457, T4510
                                'context' => 'subject'
                        ];
 
index 00439a1..f62b302 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup SpecialPage
  */
 use MediaWiki\Logger\LoggerFactory;
+use Wikimedia\Rdbms\ResultWrapper;
 
 /**
  * Special page which uses a ChangesList to show query results.
@@ -311,7 +312,7 @@ abstract class ChangesListSpecialPage extends SpecialPage {
                        $operator = $opts['invert'] ? '!=' : '=';
                        $boolean = $opts['invert'] ? 'AND' : 'OR';
 
-                       // Namespace association (bug 2429)
+                       // Namespace association (T4429)
                        if ( !$opts['associated'] ) {
                                $condition = "rc_namespace $operator $selectedNS";
                        } else {
index c4e53ee..bafee65 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup SpecialPage
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * Variant of QueryPage which uses a gallery to output results, thus
  * suited for reports generating images
index c3ee321..5c048a2 100644 (file)
@@ -177,7 +177,7 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage {
 
                # 1. When switching accounts, it sucks to get automatically logged out
                # 2. Do not return to PasswordReset after a successful password change
-               #    but goto Wiki start page (Main_Page) instead ( bug 33997 )
+               #    but goto Wiki start page (Main_Page) instead ( T35997 )
                $returnToTitle = Title::newFromText( $this->mReturnTo );
                if ( is_object( $returnToTitle )
                        && ( $returnToTitle->isSpecial( 'Userlogout' )
@@ -702,7 +702,7 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage {
         */
        protected function getFakeTemplate( $msg, $msgType ) {
                global $wgAuth, $wgEnableEmail, $wgHiddenPrefs, $wgEmailConfirmToEdit, $wgEnableUserEmail,
-                          $wgSecureLogin, $wgPasswordResetRoutes;
+                       $wgSecureLogin, $wgPasswordResetRoutes;
 
                // make a best effort to get the value of fields which used to be fixed in the old login
                // template but now might or might not exist depending on what providers are used
@@ -727,7 +727,7 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage {
                $user = $this->getUser();
                $template = new FakeAuthTemplate();
 
-               // Pre-fill username (if not creating an account, bug 44775).
+               // Pre-fill username (if not creating an account, T46775).
                if ( $data->mUsername == '' && $this->isSignup() ) {
                        if ( $user->isLoggedIn() ) {
                                $data->mUsername = $user->getName();
@@ -772,7 +772,7 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage {
                $resetLink = $this->isSignup()
                        ? null
                        : is_array( $wgPasswordResetRoutes )
-                         && in_array( true, array_values( $wgPasswordResetRoutes ), true );
+                               && in_array( true, array_values( $wgPasswordResetRoutes ), true );
 
                $template->set( 'header', '' );
                $template->set( 'formheader', '' );
index 3bb3f85..45cef2b 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup SpecialPage
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * Variant of QueryPage which formats the result as a simple link to the page
  *
index 3592500..40f82f5 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup SpecialPage
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * This is a class for doing query pages; since they're almost all the same,
  * we factor out some of the functionality into a superclass, and let
@@ -322,7 +324,7 @@ abstract class QueryPage extends SpecialPage {
                                                        $value = wfTimestamp( TS_UNIX,
                                                                $row->value );
                                                } else {
-                                                       $value = intval( $row->value ); // @bug 14414
+                                                       $value = intval( $row->value ); // T16414
                                                }
                                        } else {
                                                $value = 0;
index daabded..33e1cc3 100644 (file)
@@ -346,7 +346,7 @@ class SpecialPageFactory {
                        return [ null, null ];
                }
 
-               if ( !isset( $bits[1] ) ) { // bug 2087
+               if ( !isset( $bits[1] ) ) { // T4087
                        $par = null;
                } else {
                        $par = $bits[1];
@@ -512,7 +512,7 @@ class SpecialPageFactory {
                // @todo FIXME: Redirects broken due to this call
                $bits = explode( '/', $title->getDBkey(), 2 );
                $name = $bits[0];
-               if ( !isset( $bits[1] ) ) { // bug 2087
+               if ( !isset( $bits[1] ) ) { // T4087
                        $par = null;
                } else {
                        $par = $bits[1];
index 00fca12..9d92cbd 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup SpecialPage
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * Class definition for a wanted query page like
  * WantedPages, WantedTemplates, etc
index c18ae0e..04c04b2 100644 (file)
@@ -64,7 +64,7 @@ class SpecialBlock extends FormSpecialPage {
        protected function checkExecutePermissions( User $user ) {
                parent::checkExecutePermissions( $user );
 
-               # bug 15810: blocked admins should have limited access here
+               # T17810: blocked admins should have limited access here
                $status = self::checkUnblockSelf( $this->target, $user );
                if ( $status !== true ) {
                        throw new ErrorPageError( 'badaccess', $status );
@@ -275,7 +275,7 @@ class SpecialBlock extends FormSpecialPage {
                        }
 
                        // If the username was hidden (ipb_deleted == 1), don't show the reason
-                       // unless this user also has rights to hideuser: Bug 35839
+                       // unless this user also has rights to hideuser: T37839
                        if ( !$block->mHideName || $this->getUser()->isAllowed( 'hideuser' ) ) {
                                $fields['Reason']['default'] = $block->mReason;
                        } else {
@@ -744,7 +744,7 @@ class SpecialBlock extends FormSpecialPage {
                        $blockNotConfirmed = !$data['Confirm'] || ( array_key_exists( 'PreviousTarget', $data )
                                && $data['PreviousTarget'] !== $target );
 
-                       # Special case for API - bug 32434
+                       # Special case for API - T34434
                        $reblockNotAllowed = ( array_key_exists( 'Reblock', $data ) && !$data['Reblock'] );
 
                        # Show form unless the user is already aware of this...
@@ -824,7 +824,7 @@ class SpecialBlock extends FormSpecialPage {
                $logEntry->setComment( $data['Reason'][0] );
                $logEntry->setPerformer( $performer );
                $logEntry->setParameters( $logParams );
-               # Relate log ID to block IDs (bug 25763)
+               # Relate log ID to block IDs (T27763)
                $blockIds = array_merge( [ $status['id'] ], $status['autoIds'] );
                $logEntry->setRelations( [ 'ipb_id' => $blockIds ] );
                $logId = $logEntry->insert();
@@ -902,7 +902,7 @@ class SpecialBlock extends FormSpecialPage {
        }
 
        /**
-        * bug 15810: blocked admins should not be able to block/unblock
+        * T17810: blocked admins should not be able to block/unblock
         * others, and probably shouldn't be able to unblock themselves
         * either.
         * @param User|int|string $user
index b730ecd..9aba41e 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup SpecialPage
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * A special page listing redirects to non existent page. Those should be
  * fixed to point to an existing page.
index 766de1b..1028002 100644 (file)
@@ -359,7 +359,7 @@ class SpecialContributions extends IncludableSpecialPage {
                                [ 'page' => $userpage->getPrefixedText() ]
                        );
 
-                       # Suppression log link (bug 59120)
+                       # Suppression log link (T61120)
                        if ( $sp->getUser()->isAllowed( 'suppressionlog' ) ) {
                                $tools['log-suppression'] = $linkRenderer->makeKnownLink(
                                        SpecialPage::getTitleFor( 'Log', 'suppress' ),
index 9140bf1..59351dc 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup SpecialPage
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * A special page listing redirects to redirecting page.
  * The software will automatically not follow double redirects, to prevent loops.
@@ -75,7 +77,7 @@ class DoubleRedirectsPage extends QueryPage {
                        'conds' => [
                                'ra.rd_from = pa.page_id',
 
-                               // Filter out redirects where the target goes interwiki (bug 40353).
+                               // Filter out redirects where the target goes interwiki (T42353).
                                // This isn't an optimization, it is required for correct results,
                                // otherwise a non-double redirect like Bar -> w:Foo will show up
                                // like "Bar -> Foo -> w:Foo".
index b447271..e1ecfe8 100644 (file)
@@ -793,7 +793,7 @@ class EditWatchlistCheckboxSeriesField extends HTMLMultiSelectField {
         * HTMLMultiSelectField throws validation errors if we get input data
         * that doesn't match the data set in the form setup. This causes
         * problems if something gets removed from the watchlist while the
-        * form is open (bug 32126), but we know that invalid items will
+        * form is open (T34126), but we know that invalid items will
         * be harmless so we can override it here.
         *
         * @param string $value The value the field was submitted with
index ca0d139..560d75a 100644 (file)
@@ -263,7 +263,7 @@ class SpecialExpandTemplates extends SpecialPage {
                        $user = $this->getUser();
 
                        // To prevent cross-site scripting attacks, don't show the preview if raw HTML is
-                       // allowed and a valid edit token is not provided (bug 71111). However, MediaWiki
+                       // allowed and a valid edit token is not provided (T73111). However, MediaWiki
                        // does not currently provide logged-out users with CSRF protection; in that case,
                        // do not show the preview unless anonymous editing is allowed.
                        if ( $user->isAnon() && !$user->isAllowed( 'edit' ) ) {
index 2d6ba4a..f5e9e49 100644 (file)
@@ -361,7 +361,7 @@ class SpecialExport extends SpecialPage {
 
                        $pages = array_keys( $pageSet );
 
-                       // Normalize titles to the same format and remove dupes, see bug 17374
+                       // Normalize titles to the same format and remove dupes, see T19374
                        foreach ( $pages as $k => $v ) {
                                $pages[$k] = str_replace( " ", "_", $v );
                        }
@@ -394,7 +394,7 @@ class SpecialExport extends SpecialPage {
                        $exporter->allPages();
                } else {
                        foreach ( $pages as $page ) {
-                               # Bug 8824: Only export pages the user can read
+                               # T10824: Only export pages the user can read
                                $title = Title::newFromText( $page );
                                if ( is_null( $title ) ) {
                                        // @todo Perhaps output an <error> tag or something.
index a2fa844..a1f5efa 100644 (file)
@@ -22,6 +22,8 @@
  * @author Brion Vibber
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * Special:LinkSearch to search the external-links table.
  * @ingroup SpecialPage
index dbe5c2f..52c710d 100644 (file)
@@ -24,6 +24,8 @@
  * @author Brian Wolff
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * Special:ListDuplicatedFiles Lists all files where the current version is
  *   a duplicate of the current version of some other file.
index d034a6c..b2d6a33 100644 (file)
@@ -24,6 +24,8 @@
  * @author Rob Church <robchur@gmail.com>
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * Special:Listredirects - Lists all the redirects on the wiki.
  * @ingroup SpecialPage
index 533a331..195d08b 100644 (file)
@@ -96,7 +96,7 @@ class SpecialLog extends SpecialPage {
 
                # Some log types are only for a 'User:' title but we might have been given
                # only the username instead of the full title 'User:username'. This part try
-               # to lookup for a user by that name and eventually fix user input. See bug 1697.
+               # to lookup for a user by that name and eventually fix user input. See T3697.
                if ( in_array( $opts->getValue( 'type' ), self::getLogTypesOnUser() ) ) {
                        # ok we have a type of log which expect a user title.
                        $target = Title::newFromText( $opts->getValue( 'page' ) );
index 1cb6549..a88767a 100644 (file)
@@ -22,6 +22,8 @@
  * @author Brian Wolff
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * @ingroup SpecialPage
  */
index 6095412..0776eec 100644 (file)
@@ -24,6 +24,8 @@
  * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * A special page that list pages that have highest category count
  *
index 210c4a2..8560dca 100644 (file)
@@ -24,6 +24,8 @@
  * @author Umherirrender
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * A special page that listed pages that have highest interwiki count
  *
index 712574c..ff8550d 100644 (file)
@@ -25,6 +25,8 @@
  * @author Rob Church <robchur@gmail.com>
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * A special page to show pages ordered by the number of pages linking to them.
  *
index 41678cb..699940b 100644 (file)
@@ -24,6 +24,8 @@
  * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * A querypage to show categories ordered in descending order by the pages in them
  *
index d102791..f5c2c5f 100644 (file)
@@ -22,6 +22,8 @@
  * @author Rob Church <robchur@gmail.com>
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * Special page lists templates with a large number of
  * transclusion links, i.e. "most used" templates
index 0281b15..7d8a493 100644 (file)
@@ -77,7 +77,7 @@ class MovePageForm extends UnlistedSpecialPage {
                $request = $this->getRequest();
                $target = !is_null( $par ) ? $par : $request->getVal( 'target' );
 
-               // Yes, the use of getVal() and getText() is wanted, see bug 20365
+               // Yes, the use of getVal() and getText() is wanted, see T22365
 
                $oldTitleText = $request->getVal( 'wpOldTitle', $target );
                $this->oldTitle = Title::newFromText( $oldTitleText );
@@ -620,7 +620,7 @@ class MovePageForm extends UnlistedSpecialPage {
                        // a redirect to the new title. This is not safe, but what we did before was
                        // even worse: we just determined whether a redirect should have been created,
                        // and reported that it was created if it should have, without any checks.
-                       // Also note that isRedirect() is unreliable because of bug 37209.
+                       // Also note that isRedirect() is unreliable because of T39209.
                        $msgName = 'movepage-moved-redirect';
                } else {
                        $msgName = 'movepage-moved-noredirect';
@@ -708,7 +708,7 @@ class MovePageForm extends UnlistedSpecialPage {
 
                        $newPageName = preg_replace(
                                '#^' . preg_quote( $ot->getDBkey(), '#' ) . '#',
-                               StringUtils::escapeRegexReplacement( $nt->getDBkey() ), # bug 21234
+                               StringUtils::escapeRegexReplacement( $nt->getDBkey() ), # T23234
                                $oldSubpage->getDBkey()
                        );
 
@@ -721,7 +721,7 @@ class MovePageForm extends UnlistedSpecialPage {
                                $newNs = $nt->getSubjectPage()->getNamespace();
                        }
 
-                       # Bug 14385: we need makeTitleSafe because the new page names may
+                       # T16385: we need makeTitleSafe because the new page names may
                        # be longer than 255 characters.
                        $newSubpage = Title::makeTitleSafe( $newNs, $newPageName );
                        if ( !$newSubpage ) {
index 4671591..34ffa07 100644 (file)
@@ -83,7 +83,7 @@ class SpecialPrefixindex extends SpecialAllPages {
                        $showme = $from;
                }
 
-               // Bug 27864: if transcluded, show all pages instead of the form.
+               // T29864: if transcluded, show all pages instead of the form.
                if ( $this->including() || $showme != '' || $ns !== null ) {
                        $this->showPrefixChunk( $namespace, $showme, $from );
                } else {
index 5bdae15..8e20d88 100644 (file)
@@ -21,8 +21,6 @@
  * @ingroup SpecialPage
  */
 
-use MediaWiki\Linker\LinkRenderer;
-
 /**
  * A special page that lists protected pages
  *
@@ -273,317 +271,3 @@ class SpecialProtectedpages extends SpecialPage {
                return 'maintenance';
        }
 }
-
-/**
- * @todo document
- * @ingroup Pager
- */
-class ProtectedPagesPager extends TablePager {
-       public $mForm, $mConds;
-       private $type, $level, $namespace, $sizetype, $size, $indefonly, $cascadeonly, $noredirect;
-
-       /**
-        * @var LinkRenderer
-        */
-       private $linkRenderer;
-
-       /**
-        * @param SpecialProtectedpages $form
-        * @param array $conds
-        * @param $type
-        * @param $level
-        * @param $namespace
-        * @param string $sizetype
-        * @param int $size
-        * @param bool $indefonly
-        * @param bool $cascadeonly
-        * @param bool $noredirect
-        * @param LinkRenderer $linkRenderer
-        */
-       function __construct( $form, $conds = [], $type, $level, $namespace,
-               $sizetype = '', $size = 0, $indefonly = false, $cascadeonly = false, $noredirect = false,
-               LinkRenderer $linkRenderer
-       ) {
-               $this->mForm = $form;
-               $this->mConds = $conds;
-               $this->type = ( $type ) ? $type : 'edit';
-               $this->level = $level;
-               $this->namespace = $namespace;
-               $this->sizetype = $sizetype;
-               $this->size = intval( $size );
-               $this->indefonly = (bool)$indefonly;
-               $this->cascadeonly = (bool)$cascadeonly;
-               $this->noredirect = (bool)$noredirect;
-               $this->linkRenderer = $linkRenderer;
-               parent::__construct( $form->getContext() );
-       }
-
-       function preprocessResults( $result ) {
-               # Do a link batch query
-               $lb = new LinkBatch;
-               $userids = [];
-
-               foreach ( $result as $row ) {
-                       $lb->add( $row->page_namespace, $row->page_title );
-                       // field is nullable, maybe null on old protections
-                       if ( $row->log_user !== null ) {
-                               $userids[] = $row->log_user;
-                       }
-               }
-
-               // fill LinkBatch with user page and user talk
-               if ( count( $userids ) ) {
-                       $userCache = UserCache::singleton();
-                       $userCache->doQuery( $userids, [], __METHOD__ );
-                       foreach ( $userids as $userid ) {
-                               $name = $userCache->getProp( $userid, 'name' );
-                               if ( $name !== false ) {
-                                       $lb->add( NS_USER, $name );
-                                       $lb->add( NS_USER_TALK, $name );
-                               }
-                       }
-               }
-
-               $lb->execute();
-       }
-
-       function getFieldNames() {
-               static $headers = null;
-
-               if ( $headers == [] ) {
-                       $headers = [
-                               'log_timestamp' => 'protectedpages-timestamp',
-                               'pr_page' => 'protectedpages-page',
-                               'pr_expiry' => 'protectedpages-expiry',
-                               'log_user' => 'protectedpages-performer',
-                               'pr_params' => 'protectedpages-params',
-                               'log_comment' => 'protectedpages-reason',
-                       ];
-                       foreach ( $headers as $key => $val ) {
-                               $headers[$key] = $this->msg( $val )->text();
-                       }
-               }
-
-               return $headers;
-       }
-
-       /**
-        * @param string $field
-        * @param string $value
-        * @return string HTML
-        * @throws MWException
-        */
-       function formatValue( $field, $value ) {
-               /** @var $row object */
-               $row = $this->mCurrentRow;
-
-               switch ( $field ) {
-                       case 'log_timestamp':
-                               // when timestamp is null, this is a old protection row
-                               if ( $value === null ) {
-                                       $formatted = Html::rawElement(
-                                               'span',
-                                               [ 'class' => 'mw-protectedpages-unknown' ],
-                                               $this->msg( 'protectedpages-unknown-timestamp' )->escaped()
-                                       );
-                               } else {
-                                       $formatted = htmlspecialchars( $this->getLanguage()->userTimeAndDate(
-                                               $value, $this->getUser() ) );
-                               }
-                               break;
-
-                       case 'pr_page':
-                               $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
-                               if ( !$title ) {
-                                       $formatted = Html::element(
-                                               'span',
-                                               [ 'class' => 'mw-invalidtitle' ],
-                                               Linker::getInvalidTitleDescription(
-                                                       $this->getContext(),
-                                                       $row->page_namespace,
-                                                       $row->page_title
-                                               )
-                                       );
-                               } else {
-                                       $formatted = $this->linkRenderer->makeLink( $title );
-                               }
-                               if ( !is_null( $row->page_len ) ) {
-                                       $formatted .= $this->getLanguage()->getDirMark() .
-                                               ' ' . Html::rawElement(
-                                               'span',
-                                               [ 'class' => 'mw-protectedpages-length' ],
-                                               Linker::formatRevisionSize( $row->page_len )
-                                       );
-                               }
-                               break;
-
-                       case 'pr_expiry':
-                               $formatted = htmlspecialchars( $this->getLanguage()->formatExpiry(
-                                       $value, /* User preference timezone */true ) );
-                               $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
-                               if ( $this->getUser()->isAllowed( 'protect' ) && $title ) {
-                                       $changeProtection = $this->linkRenderer->makeKnownLink(
-                                               $title,
-                                               $this->msg( 'protect_change' )->text(),
-                                               [],
-                                               [ 'action' => 'unprotect' ]
-                                       );
-                                       $formatted .= ' ' . Html::rawElement(
-                                               'span',
-                                               [ 'class' => 'mw-protectedpages-actions' ],
-                                               $this->msg( 'parentheses' )->rawParams( $changeProtection )->escaped()
-                                       );
-                               }
-                               break;
-
-                       case 'log_user':
-                               // when timestamp is null, this is a old protection row
-                               if ( $row->log_timestamp === null ) {
-                                       $formatted = Html::rawElement(
-                                               'span',
-                                               [ 'class' => 'mw-protectedpages-unknown' ],
-                                               $this->msg( 'protectedpages-unknown-performer' )->escaped()
-                                       );
-                               } else {
-                                       $username = UserCache::singleton()->getProp( $value, 'name' );
-                                       if ( LogEventsList::userCanBitfield(
-                                               $row->log_deleted,
-                                               LogPage::DELETED_USER,
-                                               $this->getUser()
-                                       ) ) {
-                                               if ( $username === false ) {
-                                                       $formatted = htmlspecialchars( $value );
-                                               } else {
-                                                       $formatted = Linker::userLink( $value, $username )
-                                                               . Linker::userToolLinks( $value, $username );
-                                               }
-                                       } else {
-                                               $formatted = $this->msg( 'rev-deleted-user' )->escaped();
-                                       }
-                                       if ( LogEventsList::isDeleted( $row, LogPage::DELETED_USER ) ) {
-                                               $formatted = '<span class="history-deleted">' . $formatted . '</span>';
-                                       }
-                               }
-                               break;
-
-                       case 'pr_params':
-                               $params = [];
-                               // Messages: restriction-level-sysop, restriction-level-autoconfirmed
-                               $params[] = $this->msg( 'restriction-level-' . $row->pr_level )->escaped();
-                               if ( $row->pr_cascade ) {
-                                       $params[] = $this->msg( 'protect-summary-cascade' )->escaped();
-                               }
-                               $formatted = $this->getLanguage()->commaList( $params );
-                               break;
-
-                       case 'log_comment':
-                               // when timestamp is null, this is an old protection row
-                               if ( $row->log_timestamp === null ) {
-                                       $formatted = Html::rawElement(
-                                               'span',
-                                               [ 'class' => 'mw-protectedpages-unknown' ],
-                                               $this->msg( 'protectedpages-unknown-reason' )->escaped()
-                                       );
-                               } else {
-                                       if ( LogEventsList::userCanBitfield(
-                                               $row->log_deleted,
-                                               LogPage::DELETED_COMMENT,
-                                               $this->getUser()
-                                       ) ) {
-                                               $formatted = Linker::formatComment( $value !== null ? $value : '' );
-                                       } else {
-                                               $formatted = $this->msg( 'rev-deleted-comment' )->escaped();
-                                       }
-                                       if ( LogEventsList::isDeleted( $row, LogPage::DELETED_COMMENT ) ) {
-                                               $formatted = '<span class="history-deleted">' . $formatted . '</span>';
-                                       }
-                               }
-                               break;
-
-                       default:
-                               throw new MWException( "Unknown field '$field'" );
-               }
-
-               return $formatted;
-       }
-
-       function getQueryInfo() {
-               $conds = $this->mConds;
-               $conds[] = 'pr_expiry > ' . $this->mDb->addQuotes( $this->mDb->timestamp() ) .
-                       ' OR pr_expiry IS NULL';
-               $conds[] = 'page_id=pr_page';
-               $conds[] = 'pr_type=' . $this->mDb->addQuotes( $this->type );
-
-               if ( $this->sizetype == 'min' ) {
-                       $conds[] = 'page_len>=' . $this->size;
-               } elseif ( $this->sizetype == 'max' ) {
-                       $conds[] = 'page_len<=' . $this->size;
-               }
-
-               if ( $this->indefonly ) {
-                       $infinity = $this->mDb->addQuotes( $this->mDb->getInfinity() );
-                       $conds[] = "pr_expiry = $infinity OR pr_expiry IS NULL";
-               }
-               if ( $this->cascadeonly ) {
-                       $conds[] = 'pr_cascade = 1';
-               }
-               if ( $this->noredirect ) {
-                       $conds[] = 'page_is_redirect = 0';
-               }
-
-               if ( $this->level ) {
-                       $conds[] = 'pr_level=' . $this->mDb->addQuotes( $this->level );
-               }
-               if ( !is_null( $this->namespace ) ) {
-                       $conds[] = 'page_namespace=' . $this->mDb->addQuotes( $this->namespace );
-               }
-
-               return [
-                       'tables' => [ 'page', 'page_restrictions', 'log_search', 'logging' ],
-                       'fields' => [
-                               'pr_id',
-                               'page_namespace',
-                               'page_title',
-                               'page_len',
-                               'pr_type',
-                               'pr_level',
-                               'pr_expiry',
-                               'pr_cascade',
-                               'log_timestamp',
-                               'log_user',
-                               'log_comment',
-                               'log_deleted',
-                       ],
-                       'conds' => $conds,
-                       'join_conds' => [
-                               'log_search' => [
-                                       'LEFT JOIN', [
-                                               'ls_field' => 'pr_id', 'ls_value = ' . $this->mDb->buildStringCast( 'pr_id' )
-                                       ]
-                               ],
-                               'logging' => [
-                                       'LEFT JOIN', [
-                                               'ls_log_id = log_id'
-                                       ]
-                               ]
-                       ]
-               ];
-       }
-
-       protected function getTableClass() {
-               return parent::getTableClass() . ' mw-protectedpages';
-       }
-
-       function getIndexField() {
-               return 'pr_id';
-       }
-
-       function getDefaultSort() {
-               return 'pr_id';
-       }
-
-       function isFieldSortable( $field ) {
-               // no index for sorting exists
-               return false;
-       }
-}
index 975e210..eb29907 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\ResultWrapper;
 
 /**
  * A special page that lists last changes made to the wiki
@@ -455,14 +456,31 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                $panel[] = $form;
                $panelString = implode( "\n", $panel );
 
-               $this->getOutput()->addHTML(
-                       Xml::fieldset(
-                               $this->msg( 'recentchanges-legend' )->text(),
-                               $panelString,
-                               [ 'class' => 'rcoptions' ]
-                       )
+               $rcoptions = Xml::fieldset(
+                       $this->msg( 'recentchanges-legend' )->text(),
+                       $panelString,
+                       [ 'class' => 'rcoptions' ]
                );
 
+               // Insert a placeholder for RCFilters
+               if ( $this->getUser()->getOption( 'rcenhancedfilters' ) ) {
+                       $rcfilterContainer = Html::element(
+                               'div',
+                               [ 'class' => 'rcfilters-container' ]
+                       );
+
+                       // Wrap both with rcfilters-head
+                       $this->getOutput()->addHTML(
+                               Html::rawElement(
+                                       'div',
+                                       [ 'class' => 'rcfilters-head' ],
+                                       $rcfilterContainer . $rcoptions
+                               )
+                       );
+               } else {
+                       $this->getOutput()->addHTML( $rcoptions );
+               }
+
                $this->setBottomText( $opts );
        }
 
@@ -526,13 +544,9 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                parent::addModules();
                $out = $this->getOutput();
                $out->addModules( 'mediawiki.special.recentchanges' );
-               if ( $this->getUser()->getOption(
-                               'rcenhancedfilters',
-                               /*default=*/ null,
-                               /*ignoreHidden=*/ true
-                       )
-               ) {
+               if ( $this->getUser()->getOption( 'rcenhancedfilters' ) ) {
                        $out->addModules( 'mediawiki.rcfilters.filters.ui' );
+                       $out->addModuleStyles( 'mediawiki.rcfilters.filters.base.styles' );
                }
        }
 
@@ -668,7 +682,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
        function makeOptionsLink( $title, $override, $options, $active = false ) {
                $params = $override + $options;
 
-               // Bug 36524: false values have be converted to "0" otherwise
+               // T38524: false values have be converted to "0" otherwise
                // wfArrayToCgi() will omit it them.
                foreach ( $params as &$value ) {
                        if ( $value === false ) {
@@ -681,7 +695,10 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                        $title = new HtmlArmor( '<strong>' . htmlspecialchars( $title ) . '</strong>' );
                }
 
-               return $this->getLinkRenderer()->makeKnownLink( $this->getPageTitle(), $title, [], $params );
+               return $this->getLinkRenderer()->makeKnownLink( $this->getPageTitle(), $title, [
+                       'data-params' => json_encode( $override ),
+                       'data-keys' => implode( ',', array_keys( $override ) ),
+               ], $params );
        }
 
        /**
@@ -817,9 +834,9 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
 
        function filterOnUserExperienceLevel( &$tables, &$conds, &$join_conds, $opts ) {
                global $wgLearnerEdits,
-                          $wgExperiencedUserEdits,
-                          $wgLearnerMemberSince,
-                          $wgExperiencedUserMemberSince;
+                       $wgExperiencedUserEdits,
+                       $wgLearnerMemberSince,
+                       $wgExperiencedUserMemberSince;
 
                $selectedExpLevels = explode( ',', strtolower( $opts['userExpLevel'] ) );
                // remove values that are not recognized
index a78b082..a5e5113 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup SpecialPage
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * SpecialShortpages extends QueryPage. It is used to return the shortest
  * pages in the database.
index a7a1c58..19850e6 100644 (file)
@@ -95,9 +95,11 @@ class SpecialStatistics extends SpecialPage {
                        if ( !$msg->isDisabled() ) {
                                $descriptionHtml = $this->msg( 'parentheses' )->rawParams( $msg->parse() )
                                        ->escaped();
-                               $text .= "<br />" .
-                                         Html::rawElement( 'small', [ 'class' => 'mw-statistic-desc' ],
-                                                                               " $descriptionHtml" );
+                               $text .= "<br />" . Html::rawElement(
+                                       'small',
+                                       [ 'class' => 'mw-statistic-desc' ],
+                                       " $descriptionHtml"
+                               );
                        }
                }
 
index 0d42e3f..01125fc 100644 (file)
@@ -186,7 +186,7 @@ class SpecialUnblock extends SpecialPage {
                        return [ [ 'ipb_cant_unblock', $target ] ];
                }
 
-               # bug 15810: blocked admins should have limited access here.  This
+               # T17810: blocked admins should have limited access here.  This
                # won't allow sysops to remove autoblocks on themselves, but they
                # should have ipblock-exempt anyway
                $status = SpecialBlock::checkUnblockSelf( $target, $performer );
index 4c6a593..dc5f877 100644 (file)
  * @file
  * @ingroup SpecialPage
  */
-use MediaWiki\MediaWikiServices;
 
-/**
- * Used to show archived pages and eventually restore them.
- *
- * @ingroup SpecialPage
- */
-class PageArchive {
-       /** @var Title */
-       protected $title;
-
-       /** @var Status */
-       protected $fileStatus;
-
-       /** @var Status */
-       protected $revisionStatus;
-
-       /** @var Config */
-       protected $config;
-
-       function __construct( $title, Config $config = null ) {
-               if ( is_null( $title ) ) {
-                       throw new MWException( __METHOD__ . ' given a null title.' );
-               }
-               $this->title = $title;
-               if ( $config === null ) {
-                       wfDebug( __METHOD__ . ' did not have a Config object passed to it' );
-                       $config = MediaWikiServices::getInstance()->getMainConfig();
-               }
-               $this->config = $config;
-       }
-
-       public function doesWrites() {
-               return true;
-       }
-
-       /**
-        * List all deleted pages recorded in the archive table. Returns result
-        * wrapper with (ar_namespace, ar_title, count) fields, ordered by page
-        * namespace/title.
-        *
-        * @return ResultWrapper
-        */
-       public static function listAllPages() {
-               $dbr = wfGetDB( DB_REPLICA );
-
-               return self::listPages( $dbr, '' );
-       }
-
-       /**
-        * List deleted pages recorded in the archive table matching the
-        * given title prefix.
-        * Returns result wrapper with (ar_namespace, ar_title, count) fields.
-        *
-        * @param string $prefix Title prefix
-        * @return ResultWrapper
-        */
-       public static function listPagesByPrefix( $prefix ) {
-               $dbr = wfGetDB( DB_REPLICA );
-
-               $title = Title::newFromText( $prefix );
-               if ( $title ) {
-                       $ns = $title->getNamespace();
-                       $prefix = $title->getDBkey();
-               } else {
-                       // Prolly won't work too good
-                       // @todo handle bare namespace names cleanly?
-                       $ns = 0;
-               }
-
-               $conds = [
-                       'ar_namespace' => $ns,
-                       'ar_title' . $dbr->buildLike( $prefix, $dbr->anyString() ),
-               ];
-
-               return self::listPages( $dbr, $conds );
-       }
-
-       /**
-        * @param IDatabase $dbr
-        * @param string|array $condition
-        * @return bool|ResultWrapper
-        */
-       protected static function listPages( $dbr, $condition ) {
-               return $dbr->select(
-                       [ 'archive' ],
-                       [
-                               'ar_namespace',
-                               'ar_title',
-                               'count' => 'COUNT(*)'
-                       ],
-                       $condition,
-                       __METHOD__,
-                       [
-                               'GROUP BY' => [ 'ar_namespace', 'ar_title' ],
-                               'ORDER BY' => [ 'ar_namespace', 'ar_title' ],
-                               'LIMIT' => 100,
-                       ]
-               );
-       }
-
-       /**
-        * List the revisions of the given page. Returns result wrapper with
-        * (ar_minor_edit, ar_timestamp, ar_user, ar_user_text, ar_comment) fields.
-        *
-        * @return ResultWrapper
-        */
-       function listRevisions() {
-               $dbr = wfGetDB( DB_REPLICA );
-
-               $tables = [ 'archive' ];
-
-               $fields = [
-                       'ar_minor_edit', 'ar_timestamp', 'ar_user', 'ar_user_text',
-                       'ar_comment', 'ar_len', 'ar_deleted', 'ar_rev_id', 'ar_sha1',
-               ];
-
-               if ( $this->config->get( 'ContentHandlerUseDB' ) ) {
-                       $fields[] = 'ar_content_format';
-                       $fields[] = 'ar_content_model';
-               }
-
-               $conds = [ 'ar_namespace' => $this->title->getNamespace(),
-                       'ar_title' => $this->title->getDBkey() ];
-
-               $options = [ 'ORDER BY' => 'ar_timestamp DESC' ];
-
-               $join_conds = [];
-
-               ChangeTags::modifyDisplayQuery(
-                       $tables,
-                       $fields,
-                       $conds,
-                       $join_conds,
-                       $options,
-                       ''
-               );
-
-               return $dbr->select( $tables,
-                       $fields,
-                       $conds,
-                       __METHOD__,
-                       $options,
-                       $join_conds
-               );
-       }
-
-       /**
-        * List the deleted file revisions for this page, if it's a file page.
-        * Returns a result wrapper with various filearchive fields, or null
-        * if not a file page.
-        *
-        * @return ResultWrapper
-        * @todo Does this belong in Image for fuller encapsulation?
-        */
-       function listFiles() {
-               if ( $this->title->getNamespace() != NS_FILE ) {
-                       return null;
-               }
-
-               $dbr = wfGetDB( DB_REPLICA );
-               return $dbr->select(
-                       'filearchive',
-                       ArchivedFile::selectFields(),
-                       [ 'fa_name' => $this->title->getDBkey() ],
-                       __METHOD__,
-                       [ 'ORDER BY' => 'fa_timestamp DESC' ]
-               );
-       }
-
-       /**
-        * Return a Revision object containing data for the deleted revision.
-        * Note that the result *may* or *may not* have a null page ID.
-        *
-        * @param string $timestamp
-        * @return Revision|null
-        */
-       function getRevision( $timestamp ) {
-               $dbr = wfGetDB( DB_REPLICA );
-
-               $fields = [
-                       'ar_rev_id',
-                       'ar_text',
-                       'ar_comment',
-                       'ar_user',
-                       'ar_user_text',
-                       'ar_timestamp',
-                       'ar_minor_edit',
-                       'ar_flags',
-                       'ar_text_id',
-                       'ar_deleted',
-                       'ar_len',
-                       'ar_sha1',
-               ];
-
-               if ( $this->config->get( 'ContentHandlerUseDB' ) ) {
-                       $fields[] = 'ar_content_format';
-                       $fields[] = 'ar_content_model';
-               }
-
-               $row = $dbr->selectRow( 'archive',
-                       $fields,
-                       [ 'ar_namespace' => $this->title->getNamespace(),
-                               'ar_title' => $this->title->getDBkey(),
-                               'ar_timestamp' => $dbr->timestamp( $timestamp ) ],
-                       __METHOD__ );
-
-               if ( $row ) {
-                       return Revision::newFromArchiveRow( $row, [ 'title' => $this->title ] );
-               }
-
-               return null;
-       }
-
-       /**
-        * Return the most-previous revision, either live or deleted, against
-        * the deleted revision given by timestamp.
-        *
-        * May produce unexpected results in case of history merges or other
-        * unusual time issues.
-        *
-        * @param string $timestamp
-        * @return Revision|null Null when there is no previous revision
-        */
-       function getPreviousRevision( $timestamp ) {
-               $dbr = wfGetDB( DB_REPLICA );
-
-               // Check the previous deleted revision...
-               $row = $dbr->selectRow( 'archive',
-                       'ar_timestamp',
-                       [ 'ar_namespace' => $this->title->getNamespace(),
-                               'ar_title' => $this->title->getDBkey(),
-                               'ar_timestamp < ' .
-                                       $dbr->addQuotes( $dbr->timestamp( $timestamp ) ) ],
-                       __METHOD__,
-                       [
-                               'ORDER BY' => 'ar_timestamp DESC',
-                               'LIMIT' => 1 ] );
-               $prevDeleted = $row ? wfTimestamp( TS_MW, $row->ar_timestamp ) : false;
-
-               $row = $dbr->selectRow( [ 'page', 'revision' ],
-                       [ 'rev_id', 'rev_timestamp' ],
-                       [
-                               'page_namespace' => $this->title->getNamespace(),
-                               'page_title' => $this->title->getDBkey(),
-                               'page_id = rev_page',
-                               'rev_timestamp < ' .
-                                       $dbr->addQuotes( $dbr->timestamp( $timestamp ) ) ],
-                       __METHOD__,
-                       [
-                               'ORDER BY' => 'rev_timestamp DESC',
-                               'LIMIT' => 1 ] );
-               $prevLive = $row ? wfTimestamp( TS_MW, $row->rev_timestamp ) : false;
-               $prevLiveId = $row ? intval( $row->rev_id ) : null;
-
-               if ( $prevLive && $prevLive > $prevDeleted ) {
-                       // Most prior revision was live
-                       return Revision::newFromId( $prevLiveId );
-               } elseif ( $prevDeleted ) {
-                       // Most prior revision was deleted
-                       return $this->getRevision( $prevDeleted );
-               }
-
-               // No prior revision on this page.
-               return null;
-       }
-
-       /**
-        * Get the text from an archive row containing ar_text, ar_flags and ar_text_id
-        *
-        * @param object $row Database row
-        * @return string
-        */
-       function getTextFromRow( $row ) {
-               if ( is_null( $row->ar_text_id ) ) {
-                       // An old row from MediaWiki 1.4 or previous.
-                       // Text is embedded in this row in classic compression format.
-                       return Revision::getRevisionText( $row, 'ar_' );
-               }
-
-               // New-style: keyed to the text storage backend.
-               $dbr = wfGetDB( DB_REPLICA );
-               $text = $dbr->selectRow( 'text',
-                       [ 'old_text', 'old_flags' ],
-                       [ 'old_id' => $row->ar_text_id ],
-                       __METHOD__ );
-
-               return Revision::getRevisionText( $text );
-       }
-
-       /**
-        * Fetch (and decompress if necessary) the stored text of the most
-        * recently edited deleted revision of the page.
-        *
-        * If there are no archived revisions for the page, returns NULL.
-        *
-        * @return string|null
-        */
-       function getLastRevisionText() {
-               $dbr = wfGetDB( DB_REPLICA );
-               $row = $dbr->selectRow( 'archive',
-                       [ 'ar_text', 'ar_flags', 'ar_text_id' ],
-                       [ 'ar_namespace' => $this->title->getNamespace(),
-                               'ar_title' => $this->title->getDBkey() ],
-                       __METHOD__,
-                       [ 'ORDER BY' => 'ar_timestamp DESC' ] );
-
-               if ( $row ) {
-                       return $this->getTextFromRow( $row );
-               }
-
-               return null;
-       }
-
-       /**
-        * Quick check if any archived revisions are present for the page.
-        *
-        * @return bool
-        */
-       function isDeleted() {
-               $dbr = wfGetDB( DB_REPLICA );
-               $n = $dbr->selectField( 'archive', 'COUNT(ar_title)',
-                       [ 'ar_namespace' => $this->title->getNamespace(),
-                               'ar_title' => $this->title->getDBkey() ],
-                       __METHOD__
-               );
-
-               return ( $n > 0 );
-       }
-
-       /**
-        * Restore the given (or all) text and file revisions for the page.
-        * Once restored, the items will be removed from the archive tables.
-        * The deletion log will be updated with an undeletion notice.
-        *
-        * This also sets Status objects, $this->fileStatus and $this->revisionStatus
-        * (depending what operations are attempted).
-        *
-        * @param array $timestamps Pass an empty array to restore all revisions,
-        *   otherwise list the ones to undelete.
-        * @param string $comment
-        * @param array $fileVersions
-        * @param bool $unsuppress
-        * @param User $user User performing the action, or null to use $wgUser
-        * @param string|string[] $tags Change tags to add to log entry
-        *   ($user should be able to add the specified tags before this is called)
-        * @return array(number of file revisions restored, number of image revisions
-        *   restored, log message) on success, false on failure.
-        */
-       function undelete( $timestamps, $comment = '', $fileVersions = [],
-               $unsuppress = false, User $user = null, $tags = null
-       ) {
-               // If both the set of text revisions and file revisions are empty,
-               // restore everything. Otherwise, just restore the requested items.
-               $restoreAll = empty( $timestamps ) && empty( $fileVersions );
-
-               $restoreText = $restoreAll || !empty( $timestamps );
-               $restoreFiles = $restoreAll || !empty( $fileVersions );
-
-               if ( $restoreFiles && $this->title->getNamespace() == NS_FILE ) {
-                       $img = wfLocalFile( $this->title );
-                       $img->load( File::READ_LATEST );
-                       $this->fileStatus = $img->restore( $fileVersions, $unsuppress );
-                       if ( !$this->fileStatus->isOK() ) {
-                               return false;
-                       }
-                       $filesRestored = $this->fileStatus->successCount;
-               } else {
-                       $filesRestored = 0;
-               }
-
-               if ( $restoreText ) {
-                       $this->revisionStatus = $this->undeleteRevisions( $timestamps, $unsuppress, $comment );
-                       if ( !$this->revisionStatus->isOK() ) {
-                               return false;
-                       }
-
-                       $textRestored = $this->revisionStatus->getValue();
-               } else {
-                       $textRestored = 0;
-               }
-
-               // Touch the log!
-
-               if ( $textRestored && $filesRestored ) {
-                       $reason = wfMessage( 'undeletedrevisions-files' )
-                               ->numParams( $textRestored, $filesRestored )->inContentLanguage()->text();
-               } elseif ( $textRestored ) {
-                       $reason = wfMessage( 'undeletedrevisions' )->numParams( $textRestored )
-                               ->inContentLanguage()->text();
-               } elseif ( $filesRestored ) {
-                       $reason = wfMessage( 'undeletedfiles' )->numParams( $filesRestored )
-                               ->inContentLanguage()->text();
-               } else {
-                       wfDebug( "Undelete: nothing undeleted...\n" );
-
-                       return false;
-               }
-
-               if ( trim( $comment ) != '' ) {
-                       $reason .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $comment;
-               }
-
-               if ( $user === null ) {
-                       global $wgUser;
-                       $user = $wgUser;
-               }
-
-               $logEntry = new ManualLogEntry( 'delete', 'restore' );
-               $logEntry->setPerformer( $user );
-               $logEntry->setTarget( $this->title );
-               $logEntry->setComment( $reason );
-               $logEntry->setTags( $tags );
-
-               Hooks::run( 'ArticleUndeleteLogEntry', [ $this, &$logEntry, $user ] );
-
-               $logid = $logEntry->insert();
-               $logEntry->publish( $logid );
-
-               return [ $textRestored, $filesRestored, $reason ];
-       }
-
-       /**
-        * This is the meaty bit -- It restores archived revisions of the given page
-        * to the revision table.
-        *
-        * @param array $timestamps Pass an empty array to restore all revisions,
-        *   otherwise list the ones to undelete.
-        * @param bool $unsuppress Remove all ar_deleted/fa_deleted restrictions of seletected revs
-        * @param string $comment
-        * @throws ReadOnlyError
-        * @return Status Status object containing the number of revisions restored on success
-        */
-       private function undeleteRevisions( $timestamps, $unsuppress = false, $comment = '' ) {
-               if ( wfReadOnly() ) {
-                       throw new ReadOnlyError();
-               }
-
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->startAtomic( __METHOD__ );
-
-               $restoreAll = empty( $timestamps );
-
-               # Does this page already exist? We'll have to update it...
-               $article = WikiPage::factory( $this->title );
-               # Load latest data for the current page (bug 31179)
-               $article->loadPageData( 'fromdbmaster' );
-               $oldcountable = $article->isCountable();
-
-               $page = $dbw->selectRow( 'page',
-                       [ 'page_id', 'page_latest' ],
-                       [ 'page_namespace' => $this->title->getNamespace(),
-                               'page_title' => $this->title->getDBkey() ],
-                       __METHOD__,
-                       [ 'FOR UPDATE' ] // lock page
-               );
-
-               if ( $page ) {
-                       $makepage = false;
-                       # Page already exists. Import the history, and if necessary
-                       # we'll update the latest revision field in the record.
-
-                       # Get the time span of this page
-                       $previousTimestamp = $dbw->selectField( 'revision', 'rev_timestamp',
-                               [ 'rev_id' => $page->page_latest ],
-                               __METHOD__ );
-
-                       if ( $previousTimestamp === false ) {
-                               wfDebug( __METHOD__ . ": existing page refers to a page_latest that does not exist\n" );
-
-                               $status = Status::newGood( 0 );
-                               $status->warning( 'undeleterevision-missing' );
-                               $dbw->endAtomic( __METHOD__ );
-
-                               return $status;
-                       }
-               } else {
-                       # Have to create a new article...
-                       $makepage = true;
-                       $previousTimestamp = 0;
-               }
-
-               $oldWhere = [
-                       'ar_namespace' => $this->title->getNamespace(),
-                       'ar_title' => $this->title->getDBkey(),
-               ];
-               if ( !$restoreAll ) {
-                       $oldWhere['ar_timestamp'] = array_map( [ &$dbw, 'timestamp' ], $timestamps );
-               }
-
-               $fields = [
-                       'ar_id',
-                       'ar_rev_id',
-                       'rev_id',
-                       'ar_text',
-                       'ar_comment',
-                       'ar_user',
-                       'ar_user_text',
-                       'ar_timestamp',
-                       'ar_minor_edit',
-                       'ar_flags',
-                       'ar_text_id',
-                       'ar_deleted',
-                       'ar_page_id',
-                       'ar_len',
-                       'ar_sha1'
-               ];
-
-               if ( $this->config->get( 'ContentHandlerUseDB' ) ) {
-                       $fields[] = 'ar_content_format';
-                       $fields[] = 'ar_content_model';
-               }
-
-               /**
-                * Select each archived revision...
-                */
-               $result = $dbw->select(
-                       [ 'archive', 'revision' ],
-                       $fields,
-                       $oldWhere,
-                       __METHOD__,
-                       /* options */
-                       [ 'ORDER BY' => 'ar_timestamp' ],
-                       [ 'revision' => [ 'LEFT JOIN', 'ar_rev_id=rev_id' ] ]
-               );
-
-               $rev_count = $result->numRows();
-               if ( !$rev_count ) {
-                       wfDebug( __METHOD__ . ": no revisions to restore\n" );
-
-                       $status = Status::newGood( 0 );
-                       $status->warning( "undelete-no-results" );
-                       $dbw->endAtomic( __METHOD__ );
-
-                       return $status;
-               }
-
-               // We use ar_id because there can be duplicate ar_rev_id even for the same
-               // page.  In this case, we may be able to restore the first one.
-               $restoreFailedArIds = [];
-
-               // Map rev_id to the ar_id that is allowed to use it.  When checking later,
-               // if it doesn't match, the current ar_id can not be restored.
-
-               // Value can be an ar_id or -1 (-1 means no ar_id can use it, since the
-               // rev_id is taken before we even start the restore).
-               $allowedRevIdToArIdMap = [];
-
-               $latestRestorableRow = null;
-
-               foreach ( $result as $row ) {
-                       if ( $row->ar_rev_id ) {
-                               // rev_id is taken even before we start restoring.
-                               if ( $row->ar_rev_id === $row->rev_id ) {
-                                       $restoreFailedArIds[] = $row->ar_id;
-                                       $allowedRevIdToArIdMap[$row->ar_rev_id] = -1;
-                               } else {
-                                       // rev_id is not taken yet in the DB, but it might be taken
-                                       // by a prior revision in the same restore operation. If
-                                       // not, we need to reserve it.
-                                       if ( isset( $allowedRevIdToArIdMap[$row->ar_rev_id] ) ) {
-                                               $restoreFailedArIds[] = $row->ar_id;
-                                       } else {
-                                               $allowedRevIdToArIdMap[$row->ar_rev_id] = $row->ar_id;
-                                               $latestRestorableRow = $row;
-                                       }
-                               }
-                       } else {
-                               // If ar_rev_id is null, there can't be a collision, and a
-                               // rev_id will be chosen automatically.
-                               $latestRestorableRow = $row;
-                       }
-               }
-
-               $result->seek( 0 ); // move back
-
-               $oldPageId = 0;
-               if ( $latestRestorableRow !== null ) {
-                       $oldPageId = (int)$latestRestorableRow->ar_page_id; // pass this to ArticleUndelete hook
-
-                       // grab the content to check consistency with global state before restoring the page.
-                       $revision = Revision::newFromArchiveRow( $latestRestorableRow,
-                               [
-                                       'title' => $article->getTitle(), // used to derive default content model
-                               ]
-                       );
-                       $user = User::newFromName( $revision->getUserText( Revision::RAW ), false );
-                       $content = $revision->getContent( Revision::RAW );
-
-                       // NOTE: article ID may not be known yet. prepareSave() should not modify the database.
-                       $status = $content->prepareSave( $article, 0, -1, $user );
-                       if ( !$status->isOK() ) {
-                               $dbw->endAtomic( __METHOD__ );
-
-                               return $status;
-                       }
-               }
-
-               $newid = false; // newly created page ID
-               $restored = 0; // number of revisions restored
-               /** @var Revision $revision */
-               $revision = null;
-
-               // If there are no restorable revisions, we can skip most of the steps.
-               if ( $latestRestorableRow === null ) {
-                       $failedRevisionCount = $rev_count;
-               } else {
-                       if ( $makepage ) {
-                               // Check the state of the newest to-be version...
-                               if ( !$unsuppress
-                                       && ( $latestRestorableRow->ar_deleted & Revision::DELETED_TEXT )
-                               ) {
-                                       $dbw->endAtomic( __METHOD__ );
-
-                                       return Status::newFatal( "undeleterevdel" );
-                               }
-                               // Safe to insert now...
-                               $newid = $article->insertOn( $dbw, $latestRestorableRow->ar_page_id );
-                               if ( $newid === false ) {
-                                       // The old ID is reserved; let's pick another
-                                       $newid = $article->insertOn( $dbw );
-                               }
-                               $pageId = $newid;
-                       } else {
-                               // Check if a deleted revision will become the current revision...
-                               if ( $latestRestorableRow->ar_timestamp > $previousTimestamp ) {
-                                       // Check the state of the newest to-be version...
-                                       if ( !$unsuppress
-                                               && ( $latestRestorableRow->ar_deleted & Revision::DELETED_TEXT )
-                                       ) {
-                                               $dbw->endAtomic( __METHOD__ );
-
-                                               return Status::newFatal( "undeleterevdel" );
-                                       }
-                               }
-
-                               $newid = false;
-                               $pageId = $article->getId();
-                       }
-
-                       foreach ( $result as $row ) {
-                               // Check for key dupes due to needed archive integrity.
-                               if ( $row->ar_rev_id && $allowedRevIdToArIdMap[$row->ar_rev_id] !== $row->ar_id ) {
-                                       continue;
-                               }
-                               // Insert one revision at a time...maintaining deletion status
-                               // unless we are specifically removing all restrictions...
-                               $revision = Revision::newFromArchiveRow( $row,
-                                       [
-                                               'page' => $pageId,
-                                               'title' => $this->title,
-                                               'deleted' => $unsuppress ? 0 : $row->ar_deleted
-                                       ] );
-
-                               $revision->insertOn( $dbw );
-                               $restored++;
-
-                               Hooks::run( 'ArticleRevisionUndeleted',
-                                       [ &$this->title, $revision, $row->ar_page_id ] );
-                       }
-
-                       // Now that it's safely stored, take it out of the archive
-                       // Don't delete rows that we failed to restore
-                       $toDeleteConds = $oldWhere;
-                       $failedRevisionCount = count( $restoreFailedArIds );
-                       if ( $failedRevisionCount > 0 ) {
-                               $toDeleteConds[] = 'ar_id NOT IN ( ' . $dbw->makeList( $restoreFailedArIds ) . ' )';
-                       }
-
-                       $dbw->delete( 'archive',
-                               $toDeleteConds,
-                               __METHOD__ );
-               }
-
-               $status = Status::newGood( $restored );
-
-               if ( $failedRevisionCount > 0 ) {
-                       $status->warning(
-                               wfMessage( 'undeleterevision-duplicate-revid', $failedRevisionCount ) );
-               }
-
-               // Was anything restored at all?
-               if ( $restored ) {
-                       $created = (bool)$newid;
-                       // Attach the latest revision to the page...
-                       $wasnew = $article->updateIfNewerOn( $dbw, $revision );
-                       if ( $created || $wasnew ) {
-                               // Update site stats, link tables, etc
-                               $article->doEditUpdates(
-                                       $revision,
-                                       User::newFromName( $revision->getUserText( Revision::RAW ), false ),
-                                       [
-                                               'created' => $created,
-                                               'oldcountable' => $oldcountable,
-                                               'restored' => true
-                                       ]
-                               );
-                       }
-
-                       Hooks::run( 'ArticleUndelete', [ &$this->title, $created, $comment, $oldPageId ] );
-                       if ( $this->title->getNamespace() == NS_FILE ) {
-                               DeferredUpdates::addUpdate( new HTMLCacheUpdate( $this->title, 'imagelinks' ) );
-                       }
-               }
-
-               $dbw->endAtomic( __METHOD__ );
-
-               return $status;
-       }
-
-       /**
-        * @return Status
-        */
-       function getFileStatus() {
-               return $this->fileStatus;
-       }
-
-       /**
-        * @return Status
-        */
-       function getRevisionStatus() {
-               return $this->revisionStatus;
-       }
-}
+use Wikimedia\Rdbms\ResultWrapper;
 
 /**
  * Special page allowing users with the appropriate permissions to view
index ec39ccf..1469742 100644 (file)
@@ -55,7 +55,7 @@ class UnusedCategoriesPage extends QueryPage {
        }
 
        /**
-        * A should come before Z (bug 30907)
+        * A should come before Z (T32907)
         * @return bool
         */
        function sortDescending() {
index 96878a3..e82279e 100644 (file)
@@ -24,6 +24,8 @@
  * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * A special page that displays a list of pages that are not on anyones watchlist.
  *
index 8478e94..b0bb595 100644 (file)
@@ -327,7 +327,7 @@ class SpecialUploadStash extends UnlistedSpecialPage {
                header( "Content-Type: $contentType", true );
                header( 'Content-Transfer-Encoding: binary', true );
                header( 'Expires: Sun, 17-Jan-2038 19:14:07 GMT', true );
-               // Bug 53032 - It shouldn't be a problem here, but let's be safe and not cache
+               // T55032 - It shouldn't be a problem here, but let's be safe and not cache
                header( 'Cache-Control: private' );
                header( "Content-Length: $size", true );
        }
index c067f44..a9b732e 100644 (file)
@@ -38,7 +38,7 @@ class SpecialUserLogout extends UnlistedSpecialPage {
        function execute( $par ) {
                /**
                 * Some satellite ISPs use broken precaching schemes that log people out straight after
-                * they're logged in (bug 17790). Luckily, there's a way to detect such requests.
+                * they're logged in (T19790). Luckily, there's a way to detect such requests.
                 */
                if ( isset( $_SERVER['REQUEST_URI'] ) && strpos( $_SERVER['REQUEST_URI'], '&amp;' ) !== false ) {
                        wfDebug( "Special:UserLogout request {$_SERVER['REQUEST_URI']} looks suspicious, denying.\n" );
index 454d1e3..b33aa7d 100644 (file)
@@ -170,8 +170,8 @@ class UserrightsPage extends SpecialPage {
                        }
 
                        $targetUser = $this->mFetchedUser;
-                       if ( $targetUser instanceof User ) { // UserRightsProxy doesn't have this method (bug 61252)
-                               $targetUser->clearInstanceCache(); // bug 38989
+                       if ( $targetUser instanceof User ) { // UserRightsProxy doesn't have this method (T63252)
+                               $targetUser->clearInstanceCache(); // T40989
                        }
 
                        if ( $request->getVal( 'conflictcheck-originalgroups' )
index 74d5e5d..6d481f8 100644 (file)
@@ -83,7 +83,7 @@ class WantedFilesPage extends WantedQueryPage {
         * KLUGE: The results may contain false positives for files
         * that exist e.g. in a shared repo.  Setting this at least
         * keeps them from showing up as redlinks in the output, even
-        * if it doesn't fix the real problem (bug 6220).
+        * if it doesn't fix the real problem (T8220).
         *
         * @note could also have existing links here from broken file
         * redirects.
index 85ac2de..822648b 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\ResultWrapper;
 
 /**
  * A special page that lists last changes made to the wiki,
index efc51ef..ca1b7dc 100644 (file)
@@ -19,6 +19,8 @@
  * @ingroup Pager
  */
 
+use Wikimedia\Rdbms\FakeResultWrapper;
+
 /**
  * Use TablePager for prettified output. We have to pretend that we're
  * getting data from a table when in fact not all of it comes from the database.
index a4124db..9a447ef 100644 (file)
@@ -23,6 +23,7 @@
  * @ingroup Pager
  */
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\ResultWrapper;
 
 class BlockListPager extends TablePager {
 
index 47a2aed..5126bad 100644 (file)
@@ -24,6 +24,8 @@
  * @ingroup Pager
  */
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\FakeResultWrapper;
 
 class ContribsPager extends ReverseChronologicalPager {
 
@@ -160,7 +162,7 @@ class ContribsPager extends ReverseChronologicalPager {
                $user = $this->getUser();
                $conds = array_merge( $userCond, $this->getNamespaceCond() );
 
-               // Paranoia: avoid brute force searches (bug 17342)
+               // Paranoia: avoid brute force searches (T19342)
                if ( !$user->isAllowed( 'deletedhistory' ) ) {
                        $conds[] = $this->mDb->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0';
                } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
@@ -420,7 +422,7 @@ class ContribsPager extends ReverseChronologicalPager {
 
                        if ( $row->rev_parent_id === null ) {
                                // For some reason rev_parent_id isn't populated for this row.
-                               // Its rumoured this is true on wikipedia for some revisions (bug 34922).
+                               // Its rumoured this is true on wikipedia for some revisions (T36922).
                                // Next best thing is to have the total number of bytes.
                                $chardiff = ' <span class="mw-changeslist-separator">. .</span> ';
                                $chardiff .= Linker::formatRevisionSize( $row->rev_len );
index 9ffcce9..a1f6b84 100644 (file)
@@ -23,6 +23,8 @@
  * @ingroup Pager
  */
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\FakeResultWrapper;
 
 class DeletedContribsPager extends IndexPager {
 
@@ -59,7 +61,7 @@ class DeletedContribsPager extends IndexPager {
                list( $index, $userCond ) = $this->getUserCond();
                $conds = array_merge( $userCond, $this->getNamespaceCond() );
                $user = $this->getUser();
-               // Paranoia: avoid brute force searches (bug 17792)
+               // Paranoia: avoid brute force searches (T19792)
                if ( !$user->isAllowed( 'deletedhistory' ) ) {
                        $conds[] = $this->mDb->bitAnd( 'ar_deleted', Revision::DELETED_USER ) . ' = 0';
                } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
index 59dea02..3789dfa 100644 (file)
@@ -23,6 +23,8 @@
  * @ingroup Pager
  */
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\FakeResultWrapper;
 
 class ImageListPager extends TablePager {
 
@@ -449,7 +451,7 @@ class ImageListPager extends TablePager {
                                        $imgfile = $this->msg( 'imgfile' )->text();
                                }
 
-                               // Weird files can maybe exist? Bug 22227
+                               // Weird files can maybe exist? T24227
                                $filePage = Title::makeTitleSafe( NS_FILE, $value );
                                if ( $filePage ) {
                                        $link = $linkRenderer->makeKnownLink(
diff --git a/includes/specials/pagers/ProtectedPagesPager.php b/includes/specials/pagers/ProtectedPagesPager.php
new file mode 100644 (file)
index 0000000..45dced8
--- /dev/null
@@ -0,0 +1,335 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Pager
+ */
+
+use \MediaWiki\Linker\LinkRenderer;
+
+/**
+ * @todo document
+ */
+class ProtectedPagesPager extends TablePager {
+       public $mForm, $mConds;
+       private $type, $level, $namespace, $sizetype, $size, $indefonly, $cascadeonly, $noredirect;
+
+       /**
+        * @var LinkRenderer
+        */
+       private $linkRenderer;
+
+       /**
+        * @param SpecialProtectedpages $form
+        * @param array $conds
+        * @param $type
+        * @param $level
+        * @param $namespace
+        * @param string $sizetype
+        * @param int $size
+        * @param bool $indefonly
+        * @param bool $cascadeonly
+        * @param bool $noredirect
+        * @param LinkRenderer $linkRenderer
+        */
+       function __construct( $form, $conds = [], $type, $level, $namespace,
+               $sizetype = '', $size = 0, $indefonly = false, $cascadeonly = false, $noredirect = false,
+               LinkRenderer $linkRenderer
+       ) {
+               $this->mForm = $form;
+               $this->mConds = $conds;
+               $this->type = ( $type ) ? $type : 'edit';
+               $this->level = $level;
+               $this->namespace = $namespace;
+               $this->sizetype = $sizetype;
+               $this->size = intval( $size );
+               $this->indefonly = (bool)$indefonly;
+               $this->cascadeonly = (bool)$cascadeonly;
+               $this->noredirect = (bool)$noredirect;
+               $this->linkRenderer = $linkRenderer;
+               parent::__construct( $form->getContext() );
+       }
+
+       function preprocessResults( $result ) {
+               # Do a link batch query
+               $lb = new LinkBatch;
+               $userids = [];
+
+               foreach ( $result as $row ) {
+                       $lb->add( $row->page_namespace, $row->page_title );
+                       // field is nullable, maybe null on old protections
+                       if ( $row->log_user !== null ) {
+                               $userids[] = $row->log_user;
+                       }
+               }
+
+               // fill LinkBatch with user page and user talk
+               if ( count( $userids ) ) {
+                       $userCache = UserCache::singleton();
+                       $userCache->doQuery( $userids, [], __METHOD__ );
+                       foreach ( $userids as $userid ) {
+                               $name = $userCache->getProp( $userid, 'name' );
+                               if ( $name !== false ) {
+                                       $lb->add( NS_USER, $name );
+                                       $lb->add( NS_USER_TALK, $name );
+                               }
+                       }
+               }
+
+               $lb->execute();
+       }
+
+       function getFieldNames() {
+               static $headers = null;
+
+               if ( $headers == [] ) {
+                       $headers = [
+                               'log_timestamp' => 'protectedpages-timestamp',
+                               'pr_page' => 'protectedpages-page',
+                               'pr_expiry' => 'protectedpages-expiry',
+                               'log_user' => 'protectedpages-performer',
+                               'pr_params' => 'protectedpages-params',
+                               'log_comment' => 'protectedpages-reason',
+                       ];
+                       foreach ( $headers as $key => $val ) {
+                               $headers[$key] = $this->msg( $val )->text();
+                       }
+               }
+
+               return $headers;
+       }
+
+       /**
+        * @param string $field
+        * @param string $value
+        * @return string HTML
+        * @throws MWException
+        */
+       function formatValue( $field, $value ) {
+               /** @var $row object */
+               $row = $this->mCurrentRow;
+
+               switch ( $field ) {
+                       case 'log_timestamp':
+                               // when timestamp is null, this is a old protection row
+                               if ( $value === null ) {
+                                       $formatted = Html::rawElement(
+                                               'span',
+                                               [ 'class' => 'mw-protectedpages-unknown' ],
+                                               $this->msg( 'protectedpages-unknown-timestamp' )->escaped()
+                                       );
+                               } else {
+                                       $formatted = htmlspecialchars( $this->getLanguage()->userTimeAndDate(
+                                               $value, $this->getUser() ) );
+                               }
+                               break;
+
+                       case 'pr_page':
+                               $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
+                               if ( !$title ) {
+                                       $formatted = Html::element(
+                                               'span',
+                                               [ 'class' => 'mw-invalidtitle' ],
+                                               Linker::getInvalidTitleDescription(
+                                                       $this->getContext(),
+                                                       $row->page_namespace,
+                                                       $row->page_title
+                                               )
+                                       );
+                               } else {
+                                       $formatted = $this->linkRenderer->makeLink( $title );
+                               }
+                               if ( !is_null( $row->page_len ) ) {
+                                       $formatted .= $this->getLanguage()->getDirMark() .
+                                               ' ' . Html::rawElement(
+                                                       'span',
+                                                       [ 'class' => 'mw-protectedpages-length' ],
+                                                       Linker::formatRevisionSize( $row->page_len )
+                                               );
+                               }
+                               break;
+
+                       case 'pr_expiry':
+                               $formatted = htmlspecialchars( $this->getLanguage()->formatExpiry(
+                                       $value, /* User preference timezone */true ) );
+                               $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
+                               if ( $this->getUser()->isAllowed( 'protect' ) && $title ) {
+                                       $changeProtection = $this->linkRenderer->makeKnownLink(
+                                               $title,
+                                               $this->msg( 'protect_change' )->text(),
+                                               [],
+                                               [ 'action' => 'unprotect' ]
+                                       );
+                                       $formatted .= ' ' . Html::rawElement(
+                                                       'span',
+                                                       [ 'class' => 'mw-protectedpages-actions' ],
+                                                       $this->msg( 'parentheses' )->rawParams( $changeProtection )->escaped()
+                                               );
+                               }
+                               break;
+
+                       case 'log_user':
+                               // when timestamp is null, this is a old protection row
+                               if ( $row->log_timestamp === null ) {
+                                       $formatted = Html::rawElement(
+                                               'span',
+                                               [ 'class' => 'mw-protectedpages-unknown' ],
+                                               $this->msg( 'protectedpages-unknown-performer' )->escaped()
+                                       );
+                               } else {
+                                       $username = UserCache::singleton()->getProp( $value, 'name' );
+                                       if ( LogEventsList::userCanBitfield(
+                                               $row->log_deleted,
+                                               LogPage::DELETED_USER,
+                                               $this->getUser()
+                                       ) ) {
+                                               if ( $username === false ) {
+                                                       $formatted = htmlspecialchars( $value );
+                                               } else {
+                                                       $formatted = Linker::userLink( $value, $username )
+                                                               . Linker::userToolLinks( $value, $username );
+                                               }
+                                       } else {
+                                               $formatted = $this->msg( 'rev-deleted-user' )->escaped();
+                                       }
+                                       if ( LogEventsList::isDeleted( $row, LogPage::DELETED_USER ) ) {
+                                               $formatted = '<span class="history-deleted">' . $formatted . '</span>';
+                                       }
+                               }
+                               break;
+
+                       case 'pr_params':
+                               $params = [];
+                               // Messages: restriction-level-sysop, restriction-level-autoconfirmed
+                               $params[] = $this->msg( 'restriction-level-' . $row->pr_level )->escaped();
+                               if ( $row->pr_cascade ) {
+                                       $params[] = $this->msg( 'protect-summary-cascade' )->escaped();
+                               }
+                               $formatted = $this->getLanguage()->commaList( $params );
+                               break;
+
+                       case 'log_comment':
+                               // when timestamp is null, this is an old protection row
+                               if ( $row->log_timestamp === null ) {
+                                       $formatted = Html::rawElement(
+                                               'span',
+                                               [ 'class' => 'mw-protectedpages-unknown' ],
+                                               $this->msg( 'protectedpages-unknown-reason' )->escaped()
+                                       );
+                               } else {
+                                       if ( LogEventsList::userCanBitfield(
+                                               $row->log_deleted,
+                                               LogPage::DELETED_COMMENT,
+                                               $this->getUser()
+                                       ) ) {
+                                               $formatted = Linker::formatComment( $value !== null ? $value : '' );
+                                       } else {
+                                               $formatted = $this->msg( 'rev-deleted-comment' )->escaped();
+                                       }
+                                       if ( LogEventsList::isDeleted( $row, LogPage::DELETED_COMMENT ) ) {
+                                               $formatted = '<span class="history-deleted">' . $formatted . '</span>';
+                                       }
+                               }
+                               break;
+
+                       default:
+                               throw new MWException( "Unknown field '$field'" );
+               }
+
+               return $formatted;
+       }
+
+       function getQueryInfo() {
+               $conds = $this->mConds;
+               $conds[] = 'pr_expiry > ' . $this->mDb->addQuotes( $this->mDb->timestamp() ) .
+                       ' OR pr_expiry IS NULL';
+               $conds[] = 'page_id=pr_page';
+               $conds[] = 'pr_type=' . $this->mDb->addQuotes( $this->type );
+
+               if ( $this->sizetype == 'min' ) {
+                       $conds[] = 'page_len>=' . $this->size;
+               } elseif ( $this->sizetype == 'max' ) {
+                       $conds[] = 'page_len<=' . $this->size;
+               }
+
+               if ( $this->indefonly ) {
+                       $infinity = $this->mDb->addQuotes( $this->mDb->getInfinity() );
+                       $conds[] = "pr_expiry = $infinity OR pr_expiry IS NULL";
+               }
+               if ( $this->cascadeonly ) {
+                       $conds[] = 'pr_cascade = 1';
+               }
+               if ( $this->noredirect ) {
+                       $conds[] = 'page_is_redirect = 0';
+               }
+
+               if ( $this->level ) {
+                       $conds[] = 'pr_level=' . $this->mDb->addQuotes( $this->level );
+               }
+               if ( !is_null( $this->namespace ) ) {
+                       $conds[] = 'page_namespace=' . $this->mDb->addQuotes( $this->namespace );
+               }
+
+               return [
+                       'tables' => [ 'page', 'page_restrictions', 'log_search', 'logging' ],
+                       'fields' => [
+                               'pr_id',
+                               'page_namespace',
+                               'page_title',
+                               'page_len',
+                               'pr_type',
+                               'pr_level',
+                               'pr_expiry',
+                               'pr_cascade',
+                               'log_timestamp',
+                               'log_user',
+                               'log_comment',
+                               'log_deleted',
+                       ],
+                       'conds' => $conds,
+                       'join_conds' => [
+                               'log_search' => [
+                                       'LEFT JOIN', [
+                                               'ls_field' => 'pr_id', 'ls_value = ' . $this->mDb->buildStringCast( 'pr_id' )
+                                       ]
+                               ],
+                               'logging' => [
+                                       'LEFT JOIN', [
+                                               'ls_log_id = log_id'
+                                       ]
+                               ]
+                       ]
+               ];
+       }
+
+       protected function getTableClass() {
+               return parent::getTableClass() . ' mw-protectedpages';
+       }
+
+       function getIndexField() {
+               return 'pr_id';
+       }
+
+       function getDefaultSort() {
+               return 'pr_id';
+       }
+
+       function isFieldSortable( $field ) {
+               // no index for sorting exists
+               return false;
+       }
+}
index 12039aa..d599599 100644 (file)
@@ -164,7 +164,7 @@ class UsersPager extends AlphabeticPager {
         * @return string
         */
        function formatRow( $row ) {
-               if ( $row->user_id == 0 ) { # Bug 16487
+               if ( $row->user_id == 0 ) { # T18487
                        return '';
                }
 
index 8da1553..3467b49 100644 (file)
@@ -1824,7 +1824,7 @@ class Balancer {
         * Regex borrowed from Tim Starling's "remex-html" project.
         */
        const VALID_COMMENT_REGEX = "~ !--
-               (                             # 1. Comment match detector
+               (                           # 1. Comment match detector
                        > | -> | # Invalid short close
                        (                         # 2. Comment contents
                                (?:
@@ -1839,15 +1839,15 @@ class Balancer {
                        (                         # 3. Comment close
                                --> |   # Normal close
                                --!> |  # Comment end bang
-                               (                     # 4. Indicate matches requiring EOF
-                                       --! |   # EOF in comment end bang state
-                                       -- |    # EOF in comment end state
-                                       -  |    # EOF in comment end dash state
-                                               # EOF in comment state
+                               (                       # 4. Indicate matches requiring EOF
+                                       --! |                   # EOF in comment end bang state
+                                       -- |                    # EOF in comment end state
+                                       -  |                    # EOF in comment end dash state
+                                       (?#nothing)             # EOF in comment state
                                )
                        )
                )
-               ([^<]*) \z                    # 5. Non-tag text after the comment
+               ([^<]*) \z                  # 5. Non-tag text after the comment
                ~xs";
 
        /**
index 79166ef..733c4ff 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  * @ingroup Upload
  */
+use MediaWiki\MediaWikiServices;
 
 /**
  * @defgroup Upload Upload related
@@ -297,7 +298,7 @@ abstract class UploadBase {
         * @param string $srcPath The source path
         * @return string|bool The real path if it was a virtual URL Returns false on failure
         */
-       function getRealPath( $srcPath ) {
+       public function getRealPath( $srcPath ) {
                $repo = RepoGroup::singleton()->getLocalRepo();
                if ( $repo->isVirtualUrl( $srcPath ) ) {
                        /** @todo Just make uploads work with storage paths UploadFromStash
@@ -560,7 +561,7 @@ abstract class UploadBase {
         *
         * @param array $entry
         */
-       function zipEntryCallback( $entry ) {
+       public function zipEntryCallback( $entry ) {
                $names = [ $entry['name'] ];
 
                // If there is a null character, cut off the name at it, because JDK's
@@ -895,7 +896,7 @@ abstract class UploadBase {
                        return $this->mTitle;
                }
 
-               // Windows may be broken with special characters, see bug 1780
+               // Windows may be broken with special characters, see T3780
                if ( !preg_match( '/^[\x0-\x7f]*$/', $nt->getText() )
                        && !RepoGroup::singleton()->getLocalRepo()->backendSupportsUnicodePaths()
                ) {
@@ -1209,7 +1210,7 @@ abstract class UploadBase {
                }
 
                // Some browsers will interpret obscure xml encodings as UTF-8, while
-               // PHP/expat will interpret the given encoding in the xml declaration (bug 47304)
+               // PHP/expat will interpret the given encoding in the xml declaration (T49304)
                if ( $extension == 'svg' || strpos( $mime, 'image/svg' ) === 0 ) {
                        if ( self::checkXMLEncodingMissmatch( $file ) ) {
                                return true;
@@ -1361,8 +1362,8 @@ abstract class UploadBase {
                        [ 'processing_instruction_handler' => 'UploadBase::checkSvgPICallback' ]
                );
                if ( $check->wellFormed !== true ) {
-                       // Invalid xml (bug 58553)
-                       // But only when non-partial (bug 65724)
+                       // Invalid xml (T60553)
+                       // But only when non-partial (T67724)
                        return $partial ? false : [ 'uploadinvalidxml' ];
                } elseif ( $check->filterMatch ) {
                        if ( $this->mSVGNSError ) {
@@ -1382,7 +1383,7 @@ abstract class UploadBase {
         * @return bool (true if the filter identified something bad)
         */
        public static function checkSvgPICallback( $target, $data ) {
-               // Don't allow external stylesheets (bug 57550)
+               // Don't allow external stylesheets (T59550)
                if ( preg_match( '/xml-stylesheet/i', $target ) ) {
                        return [ 'upload-scripted-pi-callback' ];
                }
@@ -1401,7 +1402,7 @@ abstract class UploadBase {
                list( $namespace, $strippedElement ) = $this->splitXmlNamespace( $element );
 
                // We specifically don't include:
-               // http://www.w3.org/1999/xhtml (bug 60771)
+               // http://www.w3.org/1999/xhtml (T62771)
                static $validNamespaces = [
                        '',
                        'adobe:ns:meta/',
@@ -2083,7 +2084,7 @@ abstract class UploadBase {
        public static function getSessionStatus( User $user, $statusKey ) {
                $key = wfMemcKey( 'uploadstatus', $user->getId() ?: md5( $user->getName() ), $statusKey );
 
-               return ObjectCache::getMainStashInstance()->get( $key );
+               return MediaWikiServices::getInstance()->getMainObjectStash()->get( $key );
        }
 
        /**
@@ -2099,7 +2100,7 @@ abstract class UploadBase {
        public static function setSessionStatus( User $user, $statusKey, $value ) {
                $key = wfMemcKey( 'uploadstatus', $user->getId() ?: md5( $user->getName() ), $statusKey );
 
-               $cache = ObjectCache::getMainStashInstance();
+               $cache = MediaWikiServices::getInstance()->getMainObjectStash();
                if ( $value === false ) {
                        $cache->delete( $key );
                } else {
index c1aef22..4ee256c 100644 (file)
@@ -176,7 +176,7 @@ class PasswordReset implements LoggerAwareInterface {
                $firstUser = $users[0];
 
                if ( !$firstUser instanceof User || !$firstUser->getId() ) {
-                       // Don't parse username as wikitext (bug 65501)
+                       // Don't parse username as wikitext (T67501)
                        return StatusValue::newFatal( wfMessage( 'nosuchuser', wfEscapeWikiText( $username ) ) );
                }
 
@@ -192,7 +192,7 @@ class PasswordReset implements LoggerAwareInterface {
                                wfEscapeWikiText( $firstUser->getName() ) ) );
                }
 
-               // We need to have a valid IP address for the hook, but per bug 18347, we should
+               // We need to have a valid IP address for the hook, but per T20347, we should
                // send the user's name if they're logged in.
                $ip = $performingUser->getRequest()->getIP();
                if ( !$ip ) {
index d9c2a58..0acdb55 100644 (file)
@@ -949,7 +949,7 @@ class User implements IDBAccessObject {
 
                // Ensure that the username isn't longer than 235 bytes, so that
                // (at least for the builtin skins) user javascript and css files
-               // will work. (bug 23080)
+               // will work. (T25080)
                if ( strlen( $name ) > 235 ) {
                        wfDebugLog( 'username', __METHOD__ .
                                ": '$name' invalid due to length" );
@@ -1074,7 +1074,7 @@ class User implements IDBAccessObject {
                }
 
                // Clean up name according to title rules,
-               // but only when validation is requested (bug 12654)
+               // but only when validation is requested (T14654)
                $t = ( $validate !== false ) ?
                        Title::newFromText( $name, NS_USER ) : Title::makeTitle( NS_USER, $name );
                // Check for invalid titles
@@ -1664,7 +1664,7 @@ class User implements IDBAccessObject {
                        }
                }
 
-               // (bug 23343) Apply IP blocks to the contents of XFF headers, if enabled
+               // (T25343) Apply IP blocks to the contents of XFF headers, if enabled
                if ( !$block instanceof Block
                        && $wgApplyIpBlocksToXff
                        && $ip !== null
@@ -1787,7 +1787,7 @@ class User implements IDBAccessObject {
                $found = false;
                // @todo FIXME: IPv6 ???  (https://bugs.php.net/bug.php?id=33170)
                if ( IP::isIPv4( $ip ) ) {
-                       // Reverse IP, bug 21255
+                       // Reverse IP, T23255
                        $ipReversed = implode( '.', array_reverse( explode( '.', $ip ) ) );
 
                        foreach ( (array)$bases as $base ) {
@@ -3777,9 +3777,9 @@ class User implements IDBAccessObject {
         */
        public function getExperienceLevel() {
                global $wgLearnerEdits,
-                          $wgExperiencedUserEdits,
-                          $wgLearnerMemberSince,
-                          $wgExperiencedUserMemberSince;
+                       $wgExperiencedUserEdits,
+                       $wgLearnerMemberSince,
+                       $wgExperiencedUserMemberSince;
 
                if ( $this->isAnon() ) {
                        return false;
@@ -4125,7 +4125,7 @@ class User implements IDBAccessObject {
         *   }
         *   // do something with $user...
         *
-        * However, this was vulnerable to a race condition (bug 16020). By
+        * However, this was vulnerable to a race condition (T18020). By
         * initialising the user object if the user exists, we aim to support this
         * calling sequence as far as possible.
         *
@@ -4238,7 +4238,7 @@ class User implements IDBAccessObject {
                        return $this->mBlock;
                }
 
-               # bug 13611: if the IP address the user is trying to create an account from is
+               # T15611: if the IP address the user is trying to create an account from is
                # blocked with createaccount disabled, prevent new account creation there even
                # when the user is logged in
                if ( $this->mBlockedFromCreateAccount === false && !$this->isAllowed( 'ipblock-exempt' ) ) {
@@ -4531,7 +4531,7 @@ class User implements IDBAccessObject {
         * @note Since these URLs get dropped directly into emails, using the
         * short English names avoids insanely long URL-encoded links, which
         * also sometimes can get corrupted in some browsers/mailers
-        * (bug 6957 with Gmail and Internet Explorer).
+        * (T8957 with Gmail and Internet Explorer).
         *
         * @param string $page Special page
         * @param string $token Token
@@ -5391,7 +5391,7 @@ class User implements IDBAccessObject {
                # Note that the pattern requirement will always be satisfied if the
                # input is empty, so we need required in all cases.
 
-               # @todo FIXME: Bug 23769: This needs to not claim the password is required
+               # @todo FIXME: T25769: This needs to not claim the password is required
                # if e-mail confirmation is being used.  Since HTML5 input validation
                # is b0rked anyway in some browsers, just return nothing.  When it's
                # re-enabled, fix this code to not output required for e-mail
index dddc850..ab6683b 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 abstract class UserArray implements Iterator {
        /**
         * @param ResultWrapper $res
@@ -38,7 +40,7 @@ abstract class UserArray implements Iterator {
 
        /**
         * @param array $ids
-        * @return UserArrayFromResult
+        * @return UserArrayFromResult|ArrayIterator
         */
        static function newFromIDs( $ids ) {
                $ids = array_map( 'intval', (array)$ids ); // paranoia
@@ -59,7 +61,7 @@ abstract class UserArray implements Iterator {
        /**
         * @since 1.25
         * @param array $names
-        * @return UserArrayFromResult
+        * @return UserArrayFromResult|ArrayIterator
         */
        static function newFromNames( $names ) {
                $names = array_map( 'strval', (array)$names ); // paranoia
index fb533d0..527df7f 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 class UserArrayFromResult extends UserArray implements Countable {
        /** @var ResultWrapper */
        public $res;
@@ -27,7 +29,7 @@ class UserArrayFromResult extends UserArray implements Countable {
        /** @var int */
        public $key;
 
-       /** @var bool|stdClass */
+       /** @var bool|User */
        public $current;
 
        /**
index 55e228a..1dac0b1 100644 (file)
@@ -152,7 +152,7 @@ class AutoloadGenerator {
                ksort( $json[$key] );
 
                // Return the whole JSON file
-               return FormatJson::encode( $json, true ) . "\n";
+               return FormatJson::encode( $json, "\t", FormatJson::ALL_OK ) . "\n";
        }
 
        /**
@@ -432,6 +432,15 @@ class ClassCollector {
                                        $this->classes[] = $this->alias['name'];
                                        $this->alias = null;
                                        $this->startToken = null;
+                               } elseif ( !is_array( $token ) || (
+                                       $token[0] !== T_STRING &&
+                                       $token[0] !== T_DOUBLE_COLON &&
+                                       $token[0] !== T_CLASS &&
+                                       $token[0] !== T_WHITESPACE
+                               ) ) {
+                                       // Ignore this call to class_alias() - compat/Timestamp.php
+                                       $this->alias = null;
+                                       $this->startToken = null;
                                }
                        }
                        break;
index ef2c14a..43bccba 100644 (file)
@@ -230,7 +230,7 @@ class BatchRowIterator implements RecursiveIterator {
         * `=` conditions while the final key uses a `>` condition
         *
         * Example output:
-        *        [ '( foo = 42 AND bar > 7 ) OR ( foo > 42 )' ]
+        *     [ '( foo = 42 AND bar > 7 ) OR ( foo > 42 )' ]
         *
         * @return array The SQL conditions necessary to select the next set
         *  of rows in the batched query
index 3bddd77..1c8d486 100644 (file)
@@ -47,11 +47,11 @@ class MWCryptHKDF {
         * From http://eprint.iacr.org/2010/264.pdf:
         *
         * The scheme HKDF is specifed as:
-        *      HKDF(XTS, SKM, CTXinfo, L) = K(1) || K(2) || ... || K(t)
+        *   HKDF(XTS, SKM, CTXinfo, L) = K(1) || K(2) || ... || K(t)
         * where the values K(i) are defined as follows:
-        *      PRK = HMAC(XTS, SKM)
-        *      K(1) = HMAC(PRK, CTXinfo || 0);
-        *      K(i+1) = HMAC(PRK, K(i) || CTXinfo || i), 1 <= i < t;
+        *   PRK = HMAC(XTS, SKM)
+        *   K(1) = HMAC(PRK, CTXinfo || 0);
+        *   K(i+1) = HMAC(PRK, K(i) || CTXinfo || i), 1 <= i < t;
         * where t = [L/k] and the value K(t) is truncated to its first d = L mod k bits;
         * the counter i is non-wrapping and of a given fixed size, e.g., a single byte.
         * Note that the length of the HMAC output is the same as its key length and therefore
index b8d415f..a7407a0 100644 (file)
@@ -206,16 +206,13 @@ class SearchFormWidget {
         */
        protected function optionsHtml( $term, $isPowerSearch, $profile ) {
                $html = '';
-               $opts = [
-                       'profile' => $profile,
-               ];
 
                if ( $isPowerSearch ) {
-                       $html .= $this->powerSearchBox( $term, $opts );
+                       $html .= $this->powerSearchBox( $term, [] );
                } else {
                        $form = '';
                        Hooks::run( 'SpecialSearchProfileForm', [
-                               $this->specialSearch, &$form, $profile, $term, $opts
+                               $this->specialSearch, &$form, $profile, $term, []
                        ] );
                        $html .= $form;
                }
index a1cc4bc..2ec2d54 100644 (file)
@@ -2158,12 +2158,10 @@ class Language {
         * the date preference they're supposed to use, it should be used in
         * all children.
         *
-        *<code>
-        * function timeanddate([...], $format = true) {
-        *      $datePreference = $this->dateFormat($format);
-        * [...]
-        * }
-        *</code>
+        *     function timeanddate([...], $format = true) {
+        *       $datePreference = $this->dateFormat($format);
+        *       [...]
+        *     }
         *
         * @param int|string|bool $usePrefs If true, the user's preference is used
         *   if false, the site/language default is used
@@ -3286,14 +3284,14 @@ class Language {
        public function parseFormattedNumber( $number ) {
                $s = $this->digitTransformTable();
                if ( $s ) {
-                       // eliminate empty array values such as ''. (bug 64347)
+                       // eliminate empty array values such as ''. (T66347)
                        $s = array_filter( $s );
                        $number = strtr( $number, array_flip( $s ) );
                }
 
                $s = $this->separatorTransformTable();
                if ( $s ) {
-                       // eliminate empty array values such as ''. (bug 64347)
+                       // eliminate empty array values such as ''. (T66347)
                        $s = array_filter( $s );
                        $number = strtr( $number, array_flip( $s ) );
                }
@@ -3497,7 +3495,7 @@ class Language {
                                $string = $ellipsis . $string;
                        }
                }
-               # Do not truncate if the ellipsis makes the string longer/equal (bug 22181).
+               # Do not truncate if the ellipsis makes the string longer/equal (T24181).
                # This check is *not* redundant if $adjustLength, due to the single case where
                # LEN($ellipsis) > ABS($limit arg); $stringOriginal could be shorter than $string.
                if ( strlen( $string ) < strlen( $stringOriginal ) ) {
index 06fec44..6a426e5 100644 (file)
@@ -99,13 +99,13 @@ class LanguageConverter {
                        // '+' add rules for alltext
                        // 'E' the gave flags is error
                        // these flags above are reserved for program
-                       'A' => 'A',       // add rule for convert code (all text convert)
-                       'T' => 'T',       // title convert
-                       'R' => 'R',       // raw content
-                       'D' => 'D',       // convert description (subclass implement)
-                       '-' => '-',       // remove convert (not implement)
-                       'H' => 'H',       // add rule for convert code (but no display in placed code)
-                       'N' => 'N'        // current variant name
+                       'A' => 'A',   // add rule for convert code (all text convert)
+                       'T' => 'T',   // title convert
+                       'R' => 'R',   // raw content
+                       'D' => 'D',   // convert description (subclass implement)
+                       '-' => '-',   // remove convert (not implement)
+                       'H' => 'H',   // add rule for convert code (but no display in placed code)
+                       'N' => 'N',   // current variant name
                ];
                $this->mFlags = array_merge( $defaultflags, $flags );
                foreach ( $this->mVariants as $v ) {
@@ -357,10 +357,10 @@ class LanguageConverter {
                }
 
                /* we convert everything except:
-                  1. HTML markups (anything between < and >)
-                  2. HTML entities
-                  3. placeholders created by the parser
-               */
+                * 1. HTML markups (anything between < and >)
+                * 2. HTML entities
+                * 3. placeholders created by the parser
+                */
                $marker = '|' . Parser::MARKER_PREFIX . '[\-a-zA-Z0-9]+';
 
                // this one is needed when the text is inside an HTML markup
@@ -380,6 +380,7 @@ class LanguageConverter {
                $literalBlob = '';
 
                // Guard against delimiter nulls in the input
+               // (should never happen: see T159174)
                $text = str_replace( "\000", '', $text );
 
                $markupMatches = null;
@@ -489,7 +490,7 @@ class LanguageConverter {
        protected function applyManualConv( $convRule ) {
                // Use syntax -{T|zh-cn:TitleCN; zh-tw:TitleTw}- to custom
                // title conversion.
-               // Bug 24072: $mConvRuleTitle was overwritten by other manual
+               // T26072: $mConvRuleTitle was overwritten by other manual
                // rule(s) not for title, this breaks the title conversion.
                $newConvRuleTitle = $convRule->getTitle();
                if ( $newConvRuleTitle ) {
@@ -1085,12 +1086,12 @@ class LanguageConverter {
                        // text should be splited by ";" only if a valid variant
                        // name exist after the markup, for example:
                        //  -{zh-hans:<span style="font-size:120%;">xxx</span>;zh-hant:\
-                       //      <span style="font-size:120%;">yyy</span>;}-
+                       //  <span style="font-size:120%;">yyy</span>;}-
                        // we should split it as:
                        //  [
-                       //        [0] => 'zh-hans:<span style="font-size:120%;">xxx</span>'
-                       //        [1] => 'zh-hant:<span style="font-size:120%;">yyy</span>'
-                       //        [2] => ''
+                       //    [0] => 'zh-hans:<span style="font-size:120%;">xxx</span>'
+                       //    [1] => 'zh-hant:<span style="font-size:120%;">yyy</span>'
+                       //    [2] => ''
                        //  ]
                        $pat = '/;\s*(?=';
                        foreach ( $this->mVariants as $variant ) {
index 858a7be..90e3751 100644 (file)
@@ -30,7 +30,7 @@
 class LanguageAr extends Language {
 
        /**
-        * Temporary hack for bug 9413: replace Arabic presentation forms with their
+        * Temporary hack for T11413: replace Arabic presentation forms with their
         * standard equivalents.
         *
         * @todo FIXME: This is language-specific for now only to avoid the negative
index 76568c2..9ef53e5 100644 (file)
@@ -63,13 +63,11 @@ class LanguageKsh extends Language {
         *
         * Possible values for the type of genitive are:
         *      Sing, Iehr            prepositioned genitive = possessive dative
-        *      Vun, Fon, -omitted-   postpositioned genitive
-        *                                     = preposition "vun" with 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
+        *      Vun, Fon              preposition "vun" with dative = postpositioned genitive
         *      En, em                preposition "en" with dative
         *
         * Values for object gender specifiers of the possessive dative, or
index d1963e1..f4082af 100644 (file)
@@ -50,12 +50,12 @@ class LanguageLa extends Language {
                case 'genitive':
                        // only a few declensions, and even for those mostly the singular only
                        $in = [
-                               '/u[ms]$/',                     # 2nd declension singular
-                               '/ommunia$/',                   # 3rd declension neuter plural (partly)
-                               '/a$/',                         # 1st declension singular
+                               '/u[ms]$/',                          # 2nd declension singular
+                               '/ommunia$/',                        # 3rd declension neuter plural (partly)
+                               '/a$/',                              # 1st declension singular
                                '/libri$/', '/nuntii$/', '/datae$/', # 2nd declension plural (partly)
-                               '/tio$/', '/ns$/', '/as$/',     # 3rd declension singular (partly)
-                               '/es$/'                         # 5th declension singular
+                               '/tio$/', '/ns$/', '/as$/',          # 3rd declension singular (partly)
+                               '/es$/'                              # 5th declension singular
                        ];
                        $out = [
                                'i',
@@ -69,12 +69,12 @@ class LanguageLa extends Language {
                case 'accusative':
                        // only a few declensions, and even for those mostly the singular only
                        $in = [
-                               '/u[ms]$/',                     # 2nd declension singular
-                               '/a$/',                         # 1st declension singular
-                               '/ommuniam$/',              # 3rd declension neuter plural (partly)
+                               '/u[ms]$/',                          # 2nd declension singular
+                               '/a$/',                              # 1st declension singular
+                               '/ommuniam$/',                       # 3rd declension neuter plural (partly)
                                '/libri$/', '/nuntii$/', '/datam$/', # 2nd declension plural (partly)
-                               '/tio$/', '/ns$/', '/as$/',     # 3rd declension singular (partly)
-                               '/es$/'                         # 5th declension singular
+                               '/tio$/', '/ns$/', '/as$/',          # 3rd declension singular (partly)
+                               '/es$/'                              # 5th declension singular
                        ];
                        $out = [
                                'um',
@@ -88,12 +88,12 @@ class LanguageLa extends Language {
                case 'ablative':
                        // only a few declensions, and even for those mostly the singular only
                        $in = [
-                               '/u[ms]$/',                     # 2nd declension singular
-                               '/ommunia$/',                   # 3rd declension neuter plural (partly)
-                               '/a$/',                         # 1st declension singular
-                               '/libri$/', '/nuntii$/', '/data$/', # 2nd declension plural (partly)
-                               '/tio$/', '/ns$/', '/as$/',     # 3rd declension singular (partly)
-                               '/es$/'                         # 5th declension singular
+                               '/u[ms]$/',                          # 2nd declension singular
+                               '/ommunia$/',                        # 3rd declension neuter plural (partly)
+                               '/a$/',                              # 1st declension singular
+                               '/libri$/', '/nuntii$/', '/data$/',  # 2nd declension plural (partly)
+                               '/tio$/', '/ns$/', '/as$/',          # 3rd declension singular (partly)
+                               '/es$/'                              # 5th declension singular
                        ];
                        $out = [
                                'o',
index cd39378..df894a1 100644 (file)
@@ -31,8 +31,8 @@ class LanguageMl extends Language {
         * Temporary hack for the issue described at
         * http://permalink.gmane.org/gmane.science.linguistics.wikipedia.technical/46396
         * Convert Unicode 5.0 style Malayalam input to Unicode 5.1. Similar to
-        * bug 9413. Also fixes miscellaneous problems due to mishandling of ZWJ,
-        * e.g. bug 11162.
+        * T11413. Also fixes miscellaneous problems due to mishandling of ZWJ,
+        * e.g. T13162.
         *
         * @todo FIXME: This is language-specific for now only to avoid the negative
         * performance impact of enabling it for all languages.
index 42ee44d..49ee88a 100644 (file)
@@ -27,8 +27,7 @@
  * Turkish has two different i, one with a dot and another without a dot. They
  * are totally different letters in this language, so we have to override the
  * ucfirst and lcfirst methods.
- * See https://en.wikipedia.org/wiki/Dotted_and_dotless_I
- * and @bug 28040
+ * See https://en.wikipedia.org/wiki/Dotted_and_dotless_I and T30040
  * @ingroup Language
  */
 class LanguageTr extends Language {
index 0557455..1c350d0 100644 (file)
@@ -60,7 +60,7 @@ class Names {
                'als' => 'Alemannisch', # Alemannic -- not a valid code, for compatibility. See gsw.
                'am' => 'አማርኛ', # Amharic
                'an' => 'aragonés', # Aragonese
-               'ang' => 'Ænglisc', # Old English, bug 23283
+               'ang' => 'Ænglisc', # Old English, T25283
                'anp' => 'अङ्गिका', # Angika
                'ar' => 'العربية', # Arabic
                'arc' => 'ܐܪܡܝܐ', # Aramaic
@@ -274,7 +274,7 @@ class Names {
                'lus' => 'Mizo ţawng', # Mizo/Lushai
                'luz' => 'لئری دوٙمینی', # Southern Luri
                'lv' => 'latviešu', # Latvian
-               'lzh' => '文言', # Literary Chinese, bug 8217
+               'lzh' => '文言', # Literary Chinese, T10217
                'lzz' => 'Lazuri', # Laz
                'mai' => 'मैथिली', # Maithili
                'map-bms' => 'Basa Banyumasan', # Banyumasan
@@ -299,8 +299,8 @@ class Names {
                'mzn' => 'مازِرونی', # Mazanderani
                'na' => 'Dorerin Naoero', # Nauruan
                'nah' => 'Nāhuatl', # Nahuatl (not in ISO 639-3)
-               'nan' => 'Bân-lâm-gú', # Min-nan, bug 8217
-               'nap' => 'Napulitano', # Neapolitan, bug 43793
+               'nan' => 'Bân-lâm-gú', # Min-nan, T10217
+               'nap' => 'Napulitano', # Neapolitan, T45793
                'nb' => 'norsk bokmål', # Norwegian (Bokmal)
                'nds' => 'Plattdüütsch', # Low German ''or'' Low Saxon
                'nds-nl' => 'Nedersaksies', # aka Nedersaksisch: Dutch Low Saxon
@@ -321,7 +321,7 @@ class Names {
                'olo' => 'Livvinkarjala', # Livvi-Karelian
                'om' => 'Oromoo', # Oromo
                'or' => 'ଓଡ଼ିଆ', # Oriya
-               'os' => 'Ирон', # Ossetic, bug 29091
+               'os' => 'Ирон', # Ossetic, T31091
                'pa' => 'ਪੰਜਾਬੀ', # Eastern Punjabi (Gurmukhi script) (pan)
                'pag' => 'Pangasinan', # Pangasinan
                'pam' => 'Kapampangan', # Pampanga
@@ -456,17 +456,17 @@ class Names {
                'za' => 'Vahcuengh', # Zhuang
                'zea' => 'Zeêuws', # Zeeuws/Zeaws
                'zh' => '中文', # (Zhōng Wén) - Chinese
-               'zh-classical' => '文言', # Classical Chinese/Literary Chinese -- (see bug 8217)
+               'zh-classical' => '文言', # Classical Chinese/Literary Chinese -- (see T10217)
                'zh-cn' => "中文(中国大陆)\xE2\x80\x8E", # Chinese (PRC)
                'zh-hans' => "中文(简体)\xE2\x80\x8E", # Mandarin Chinese (Simplified Chinese script) (cmn-hans)
                'zh-hant' => "中文(繁體)\xE2\x80\x8E", # Mandarin Chinese (Traditional Chinese script) (cmn-hant)
                'zh-hk' => "中文(香港)\xE2\x80\x8E", # Chinese (Hong Kong)
-               'zh-min-nan' => 'Bân-lâm-gú', # Min-nan -- (see bug 8217)
+               'zh-min-nan' => 'Bân-lâm-gú', # Min-nan -- (see T10217)
                'zh-mo' => "中文(澳門)\xE2\x80\x8E", # Chinese (Macau)
                'zh-my' => "中文(马来西亚)\xE2\x80\x8E", # Chinese (Malaysia)
                'zh-sg' => "中文(新加坡)\xE2\x80\x8E", # Chinese (Singapore)
                'zh-tw' => "中文(台灣)\xE2\x80\x8E", # Chinese (Taiwan)
-               'zh-yue' => '粵語', # Cantonese -- (see bug 8217)
+               'zh-yue' => '粵語', # Cantonese -- (see T10217)
                'zu' => 'isiZulu' # Zulu
        ];
 }
index a3cd622..55813ae 100644 (file)
@@ -3008,7 +3008,6 @@ public static $zh2Hant = [
 '0只支援' => '0只支援',
 '0周后' => '0周後',
 '0天后' => '0天後',
-'0年' => '0年',
 '0只' => '0隻',
 '0余' => '0餘',
 '0出' => '0齣',
@@ -3016,63 +3015,54 @@ public static $zh2Hant = [
 '1只支援' => '1只支援',
 '1周后' => '1周後',
 '1天后' => '1天後',
-'1年' => '1年',
 '1只' => '1隻',
 '1余' => '1餘',
 '2只支持' => '2只支持',
 '2只支援' => '2只支援',
 '2周后' => '2周後',
 '2天后' => '2天後',
-'2年' => '2年',
 '2只' => '2隻',
 '2余' => '2餘',
 '3只支持' => '3只支持',
 '3只支援' => '3只支援',
 '3周后' => '3周後',
 '3天后' => '3天後',
-'3年' => '3年',
 '3只' => '3隻',
 '3余' => '3餘',
 '4只支持' => '4只支持',
 '4只支援' => '4只支援',
 '4周后' => '4周後',
 '4天后' => '4天後',
-'4年' => '4年',
 '4只' => '4隻',
 '4余' => '4餘',
 '5只支持' => '5只支持',
 '5只支援' => '5只支援',
 '5周后' => '5周後',
 '5天后' => '5天後',
-'5年' => '5年',
 '5只' => '5隻',
 '5余' => '5餘',
 '6只支持' => '6只支持',
 '6只支援' => '6只支援',
 '6周后' => '6周後',
 '6天后' => '6天後',
-'6年' => '6年',
 '6只' => '6隻',
 '6余' => '6餘',
 '7只支持' => '7只支持',
 '7只支援' => '7只支援',
 '7周后' => '7周後',
 '7天后' => '7天後',
-'7年' => '7年',
 '7只' => '7隻',
 '7余' => '7餘',
 '8只支持' => '8只支持',
 '8只支援' => '8只支援',
 '8周后' => '8周後',
 '8天后' => '8天後',
-'8年' => '8年',
 '8只' => '8隻',
 '8余' => '8餘',
 '9只支持' => '9只支持',
 '9只支援' => '9只支援',
 '9周后' => '9周後',
 '9天后' => '9天後',
-'9年' => '9年',
 '9只' => '9隻',
 '9余' => '9餘',
 '·范' => '·范',
@@ -3080,7 +3070,6 @@ public static $zh2Hant = [
 '、面点' => '、麵點',
 '。个中' => '。箇中',
 '〇周后' => '〇周後',
-'〇年' => '〇年',
 '〇只' => '〇隻',
 '〇余' => '〇餘',
 '“' => '「',
@@ -3107,8 +3096,6 @@ public static $zh2Hant = [
 '一干弟兄' => '一干弟兄',
 '一干弟子' => '一干弟子',
 '一干部下' => '一干部下',
-'一年' => '一年',
-'一年里' => '一年裡',
 '一斗斗' => '一斗斗',
 '一树百获' => '一樹百穫',
 '一准' => '一準',
@@ -3137,7 +3124,6 @@ public static $zh2Hant = [
 '七个' => '七個',
 '七周后' => '七周後',
 '七天后' => '七天後',
-'七年' => '七年',
 '七情六欲' => '七情六慾',
 '七扎' => '七紮',
 '七只' => '七隻',
@@ -3147,7 +3133,6 @@ public static $zh2Hant = [
 '三个' => '三個',
 '三周后' => '三周後',
 '三天后' => '三天後',
-'三年' => '三年',
 '三征七辟' => '三徵七辟',
 '三准' => '三準',
 '三扎' => '三紮',
@@ -3175,7 +3160,6 @@ public static $zh2Hant = [
 '上课钟' => '上課鐘',
 '上面糊' => '上面糊',
 '下文里' => '下文裡',
-'下于' => '下於',
 '下梁' => '下樑',
 '下注解' => '下注解',
 '下签了' => '下簽了',
@@ -3231,7 +3215,6 @@ public static $zh2Hant = [
 '丑月' => '丑月',
 '丑表功' => '丑表功',
 '丑角' => '丑角',
-'且于' => '且於',
 '世界杯' => '世界盃',
 '世纪里' => '世紀裡',
 '世纪钟' => '世紀鐘',
@@ -3254,7 +3237,6 @@ public static $zh2Hant = [
 '中岳' => '中嶽',
 '中庄子' => '中庄子',
 '中文里' => '中文裡',
-'中于' => '中於',
 '中签了' => '中簽了',
 '中签名' => '中簽名',
 '中签字' => '中簽字',
@@ -3329,7 +3311,6 @@ public static $zh2Hant = [
 '九个' => '九個',
 '九周后' => '九周後',
 '九天后' => '九天後',
-'九年' => '九年',
 '九谷' => '九穀',
 '九扎' => '九紮',
 '九只' => '九隻',
@@ -3502,7 +3483,6 @@ public static $zh2Hant = [
 '二只得' => '二只得',
 '二周后' => '二周後',
 '二天后' => '二天後',
-'二年' => '二年',
 '二缶钟惑' => '二缶鐘惑',
 '二老板' => '二老板',
 '二虎相斗' => '二虎相鬥',
@@ -3728,7 +3708,6 @@ public static $zh2Hant = [
 '五天后' => '五天後',
 '五峰县' => '五峯縣',
 '五岳' => '五嶽',
-'五年' => '五年',
 '五谷' => '五穀',
 '五扎' => '五紮',
 '五脏' => '五臟',
@@ -3739,7 +3718,6 @@ public static $zh2Hant = [
 '五余' => '五餘',
 '井干' => '井幹',
 '井里' => '井裡',
-'亚于' => '亞於',
 '交托' => '交託',
 '交游' => '交遊',
 '交哄' => '交鬨',
@@ -3774,8 +3752,6 @@ public static $zh2Hant = [
 '价川' => '价川',
 '任何钟' => '任何鐘',
 '任何钟表' => '任何鐘錶',
-'任教于' => '任教於',
-'任于' => '任於',
 '仿制' => '仿製',
 '伊于湖底' => '伊于湖底',
 '伊府面' => '伊府麵',
@@ -3797,9 +3773,7 @@ public static $zh2Hant = [
 '休征' => '休徵',
 '伙头' => '伙頭',
 '伴游' => '伴遊',
-'似于' => '似於',
 '但云' => '但云',
-'位于' => '位於',
 '位准' => '位準',
 '低洼' => '低洼',
 '住扎' => '住紮',
@@ -3852,13 +3826,11 @@ public static $zh2Hant = [
 '并购' => '併購',
 '并骨' => '併骨',
 '使其斗' => '使其鬥',
-'来于' => '來於',
 '侍仆' => '侍僕',
 '依依不舍' => '依依不捨',
 '依托' => '依託',
 '侵并' => '侵併',
 '局促' => '侷促',
-'便于' => '便於',
 '系数' => '係數',
 '系为' => '係為',
 '保险柜' => '保險柜',
@@ -3898,7 +3870,6 @@ public static $zh2Hant = [
 '傲霜斗雪' => '傲霜鬥雪',
 '传位于四太子' => '傳位于四太子',
 '傳位于四太子' => '傳位于四太子',
-'传于' => '傳於',
 '债累累' => '債纍纍',
 '傻里傻气' => '傻裡傻氣',
 '仅余' => '僅餘',
@@ -3935,7 +3906,6 @@ public static $zh2Hant = [
 '亿个' => '億個',
 '亿周后' => '億周後',
 '亿天后' => '億天後',
-'亿年' => '億年',
 '亿只' => '億隻',
 '亿余' => '億餘',
 '俭仆' => '儉僕',
@@ -3957,7 +3927,6 @@ public static $zh2Hant = [
 '尽自' => '儘自',
 '尽速' => '儘速',
 '尽量' => '儘量',
-'优于' => '優於',
 '优游' => '優遊',
 '兀术' => '兀朮',
 '元凶' => '元兇',
@@ -4005,7 +3974,6 @@ public static $zh2Hant = [
 '两个' => '兩個',
 '两周后' => '兩周後',
 '两天后' => '兩天後',
-'两年' => '兩年',
 '两杆' => '兩桿',
 '两扎' => '兩紮',
 '两虎共斗' => '兩虎共鬥',
@@ -4017,7 +3985,6 @@ public static $zh2Hant = [
 '八周后' => '八周後',
 '八天后' => '八天後',
 '八字胡' => '八字鬍',
-'八年' => '八年',
 '八扎' => '八紮',
 '八蜡' => '八蜡',
 '八只' => '八隻',
@@ -4036,7 +4003,6 @@ public static $zh2Hant = [
 '六个' => '六個',
 '六周后' => '六周後',
 '六天后' => '六天後',
-'六年' => '六年',
 '六楼后座' => '六樓后座',
 '六樓后座' => '六樓后座',
 '六谷' => '六穀',
@@ -4088,7 +4054,6 @@ public static $zh2Hant = [
 '出乖弄丑' => '出乖弄醜',
 '出乖露丑' => '出乖露醜',
 '出征收' => '出征收',
-'出于' => '出於',
 '出游' => '出遊',
 '出丑' => '出醜',
 '函数里' => '函數裡',
@@ -4097,7 +4062,6 @@ public static $zh2Hant = [
 '分多钟' => '分多鐘',
 '分子钟' => '分子鐘',
 '分子云' => '分子雲',
-'分布于' => '分布於',
 '分钟' => '分鐘',
 '分钟里' => '分鐘裡',
 '刑余' => '刑餘',
@@ -4143,7 +4107,6 @@ public static $zh2Hant = [
 '判断发' => '判斷發',
 '别辟' => '別闢',
 '利欲' => '利慾',
-'利于' => '利於',
 '刮起来' => '刮起來',
 '刮胡' => '刮鬍',
 '到山里' => '到山裡',
@@ -4192,11 +4155,8 @@ public static $zh2Hant = [
 '力争上游' => '力爭上遊',
 '功勋' => '功勳',
 '加氢精制' => '加氫精制',
-'劣于' => '劣於',
-'助于' => '助於',
 '劫余' => '劫餘',
 '勃郁' => '勃鬱',
-'胜于' => '勝於',
 '勤仆' => '勤僕',
 '勤朴' => '勤樸',
 '勋劳' => '勳勞',
@@ -4218,7 +4178,6 @@ public static $zh2Hant = [
 '北回线' => '北迴線',
 '北回铁路' => '北迴鐵路',
 '匪干' => '匪幹',
-'匿于' => '匿於',
 '区里有' => '區裡有',
 '区里的' => '區裡的',
 '十个' => '十個',
@@ -4229,7 +4188,6 @@ public static $zh2Hant = [
 '十出头' => '十出頭',
 '十周后' => '十周後',
 '十天后' => '十天後',
-'十年' => '十年',
 '十扎' => '十紮',
 '十只' => '十隻',
 '十余' => '十餘',
@@ -4244,7 +4202,6 @@ public static $zh2Hant = [
 '千只足夠' => '千只足夠',
 '千周后' => '千周後',
 '千天后' => '千天後',
-'千年' => '千年',
 '千扎' => '千紮',
 '千回百折' => '千迴百折',
 '千回百转' => '千迴百轉',
@@ -4255,7 +4212,6 @@ public static $zh2Hant = [
 '半制品' => '半制品',
 '半只可' => '半只可',
 '半只够' => '半只夠',
-'半于' => '半於',
 '半只' => '半隻',
 '协防' => '協防',
 '南京钟' => '南京鐘',
@@ -4275,7 +4231,6 @@ public static $zh2Hant = [
 '印累绶若' => '印纍綬若',
 '印制' => '印製',
 '印鉴' => '印鑑',
-'危于' => '危於',
 '卵与石斗' => '卵與石鬥',
 '卷须' => '卷鬚',
 '厂部' => '厂部',
@@ -4294,7 +4249,6 @@ public static $zh2Hant = [
 '反复' => '反覆',
 '反覆' => '反覆',
 '取舍' => '取捨',
-'取决于' => '取決於',
 '受雇' => '受僱',
 '受托' => '受託',
 '丛林里' => '叢林裡',
@@ -4400,7 +4354,6 @@ public static $zh2Hant = [
 '吊钟' => '吊鐘',
 '同人志' => '同人誌',
 '同伙' => '同夥',
-'同于' => '同於',
 '同余' => '同餘',
 '名单于' => '名單於',
 '后冠' => '后冠',
@@ -4498,7 +4451,6 @@ public static $zh2Hant = [
 '喂喲' => '喂喲',
 '喂!' => '喂!',
 '喂,' => '喂,',
-'善于' => '善於',
 '喜欢表' => '喜歡錶',
 '喜欢钟' => '喜歡鐘',
 '喜欢钟表' => '喜歡鐘錶',
@@ -4532,7 +4484,6 @@ public static $zh2Hant = [
 '向迩' => '嚮邇',
 '严云农' => '嚴云農',
 '嚴云農' => '嚴云農',
-'严于' => '嚴於',
 '嚼谷' => '嚼穀',
 '啰啰苏苏' => '囉囉囌囌',
 '啰苏' => '囉囌',
@@ -4544,7 +4495,6 @@ public static $zh2Hant = [
 '四分历史' => '四分歷史',
 '四周后' => '四周後',
 '四天后' => '四天後',
-'四年' => '四年',
 '四舍五入' => '四捨五入',
 '四舍六入' => '四捨六入',
 '四杆铁笔' => '四桿鐵筆',
@@ -4566,19 +4516,15 @@ public static $zh2Hant = [
 '回复邮件' => '回覆郵件',
 '回复:' => '回覆:',
 '回游' => '回遊',
-'因于' => '因於',
 '困倦起来' => '困倦起來',
-'困于' => '困於',
 '困兽之斗' => '困獸之鬥',
 '困兽犹斗' => '困獸猶鬥',
 '困斗' => '困鬥',
 '固定制' => '固定制',
 '固征' => '固徵',
-'囿于' => '囿於',
 '圈梁' => '圈樑',
 '圈里' => '圈裡',
 '国之桢干' => '國之楨榦',
-'国于' => '國於',
 '国历' => '國曆',
 '国历代' => '國歷代',
 '国历任' => '國歷任',
@@ -4597,22 +4543,21 @@ public static $zh2Hant = [
 '土制' => '土製',
 '在制品' => '在制品',
 '在山里' => '在山裡',
-'在于' => '在於',
 '地图里' => '地圖裡',
 '地心历表' => '地心曆表',
 '地志' => '地誌',
 '地丑德齐' => '地醜德齊',
-'å\9d\8fäº\8e' => 'å\9d\8fæ\96¼',
-'å\9d\8fæ\96¼' => 'å\9d\8fæ\96¼',
+'å\9d\90å\8f°é\90µ' => 'å\9d\90å\8f°é\90µ',
+'å\9d\90å\8f°é\93\81' => 'å\9d\90å\8f°é\90µ',
 '坐如钟' => '坐如鐘',
 '坐台' => '坐檯',
 '坐钟' => '坐鐘',
+'坑口里' => '坑口里',
 '坑里' => '坑裡',
 '坤范' => '坤範',
 '坦荡' => '坦蕩',
 '坦荡荡' => '坦蕩蕩',
 '坱郁' => '坱鬱',
-'垂于' => '垂於',
 '垂范' => '垂範',
 '垂发' => '垂髮',
 '型范' => '型範',
@@ -4626,7 +4571,6 @@ public static $zh2Hant = [
 '埔里社' => '埔裏社',
 '域里' => '域裡',
 '基干' => '基幹',
-'基于' => '基於',
 '基准' => '基準',
 '坚致' => '堅緻',
 '堙淀' => '堙澱',
@@ -4678,7 +4622,6 @@ public static $zh2Hant = [
 '多只须' => '多只須',
 '多周后' => '多周後',
 '多天后' => '多天後',
-'多于' => '多於',
 '多冲' => '多衝',
 '多丑' => '多醜',
 '多只' => '多隻',
@@ -4781,7 +4724,6 @@ public static $zh2Hant = [
 '好斗胆' => '好斗膽',
 '好斗膽' => '好斗膽',
 '好斗蓬' => '好斗蓬',
-'好于' => '好於',
 '好困' => '好睏',
 '好签' => '好籤',
 '好丑' => '好醜',
@@ -4791,7 +4733,6 @@ public static $zh2Hant = [
 '妖后' => '妖后',
 '妖气冲天' => '妖氣衝天',
 '妆台' => '妝檯',
-'始于' => '始於',
 '姓么' => '姓么',
 '委托' => '委託',
 '委托书' => '委託書',
@@ -4803,7 +4744,6 @@ public static $zh2Hant = [
 '奸淫' => '姦淫',
 '威棱' => '威稜',
 '婢仆' => '婢僕',
-'嫁祸于' => '嫁禍於',
 '嫌凶' => '嫌兇',
 '嫌好道丑' => '嫌好道醜',
 '嫩姜' => '嫩薑',
@@ -4819,7 +4759,6 @@ public static $zh2Hant = [
 '字码表' => '字碼表',
 '字里行间' => '字裡行間',
 '存折' => '存摺',
-'存于' => '存於',
 '孛里海' => '孛里海',
 '孝惠后' => '孝惠后',
 '孙杰' => '孫杰',
@@ -4827,7 +4766,6 @@ public static $zh2Hant = [
 '学家' => '學家',
 '学里' => '學裡',
 '宇宙志' => '宇宙誌',
-'安于' => '安於',
 '安沈铁路' => '安瀋鐵路',
 '宋王台' => '宋王臺',
 '宗周钟' => '宗周鐘',
@@ -4835,19 +4773,16 @@ public static $zh2Hant = [
 '官地为采' => '官地為寀',
 '官历' => '官曆',
 '官历史' => '官歷史',
-'定于' => '定於',
 '定准' => '定準',
 '定制' => '定製',
 '宜云' => '宜云',
 '宣泄' => '宣洩',
 '宦游' => '宦遊',
 '宫里' => '宮裡',
-'害于' => '害於',
 '宴游' => '宴遊',
 '家仆' => '家僕',
 '家里' => '家裡',
 '家丑' => '家醜',
-'容于' => '容於',
 '容范' => '容範',
 '宿舍' => '宿舍',
 '寄托在' => '寄托在',
@@ -4857,14 +4792,12 @@ public static $zh2Hant = [
 '寇仇' => '寇讎',
 '富余' => '富餘',
 '寒栗' => '寒慄',
-'寒于' => '寒於',
-'寓于' => '寓於',
+'寓禁于征' => '寓禁於徵',
 '寡欲' => '寡慾',
 '实干' => '實幹',
 '实累累' => '實纍纍',
 '实验里' => '實驗裡',
 '写字台' => '寫字檯',
-'宽于' => '寬於',
 '宽余' => '寬餘',
 '宽松' => '寬鬆',
 '宽松松' => '寬鬆鬆',
@@ -4886,7 +4819,6 @@ public static $zh2Hant = [
 '尊后' => '尊后',
 '对不准' => '對不準',
 '对折' => '對摺',
-'对于' => '對於',
 '对准' => '對準',
 '对准表' => '對準錶',
 '对准钟' => '對準鐘',
@@ -4946,9 +4878,7 @@ public static $zh2Hant = [
 '屋梁' => '屋樑',
 '屋里' => '屋裡',
 '屏风后' => '屏風後',
-'屑于' => '屑於',
 '屡顾尔仆' => '屢顧爾僕',
-'属于' => '屬於',
 '属托' => '屬託',
 '屯扎' => '屯紮',
 '屯里' => '屯裡',
@@ -4998,7 +4928,6 @@ public static $zh2Hant = [
 '巧历史' => '巧歷史',
 '巨制' => '巨製',
 '差之毫厘' => '差之毫厘',
-'差于' => '差於',
 '己丑' => '己丑',
 '已占卜' => '已占卜',
 '已占算' => '已占算',
@@ -5035,8 +4964,6 @@ public static $zh2Hant = [
 '并州' => '并州',
 '并日而食' => '并日而食',
 '并迭' => '并迭',
-'幸免于难' => '幸免於難',
-'幸于' => '幸於',
 '幸运胡' => '幸運鬍',
 '干上' => '幹上',
 '干下去' => '幹下去',
@@ -5123,7 +5050,6 @@ public static $zh2Hant = [
 '广舍' => '廣捨',
 '广播里' => '廣播裡',
 '延历' => '延曆',
-'建于' => '建於',
 '建筑前' => '建築前',
 '建筑后' => '建築後',
 '弄干' => '弄乾',
@@ -5168,7 +5094,6 @@ public static $zh2Hant = [
 '引斗' => '引鬥',
 '弘历' => '弘曆',
 '弘历史' => '弘歷史',
-'弱于' => '弱於',
 '弱水三千只取一瓢' => '弱水三千只取一瓢',
 '张三丰' => '張三丰',
 '張三丰' => '張三丰',
@@ -5183,7 +5108,6 @@ public static $zh2Hant = [
 '强制作用' => '強制作用',
 '强奸' => '強姦',
 '强干' => '強幹',
-'强于' => '強於',
 '别扭' => '彆扭',
 '别拗' => '彆拗',
 '别气' => '彆氣',
@@ -5194,11 +5118,9 @@ public static $zh2Hant = [
 '汇纂' => '彙纂',
 '汇辑' => '彙輯',
 '形单影只' => '形單影隻',
-'形于' => '形於',
 '彭于晏' => '彭于晏',
 '影后' => '影后',
 '影相吊' => '影相弔',
-'役于' => '役於',
 '往复式' => '往復式',
 '往日无仇' => '往日無讎',
 '往里' => '往裡',
@@ -5222,7 +5144,6 @@ public static $zh2Hant = [
 '从仆' => '從僕',
 '从图里' => '從圖裡',
 '从山里' => '從山裡',
-'从于' => '從於',
 '从里到外' => '從裡到外',
 '从里向外' => '從裡向外',
 '御岳山' => '御嶽山',
@@ -5279,7 +5200,6 @@ public static $zh2Hant = [
 '征风召雨' => '徵風召雨',
 '征验' => '徵驗',
 '心愿' => '心愿',
-'心于' => '心於',
 '心理' => '心理',
 '心细如发' => '心細如髮',
 '心系一' => '心繫一',
@@ -5406,18 +5326,14 @@ public static $zh2Hant = [
 '忙里偷闲' => '忙裡偷閒',
 '忠人之托' => '忠人之托',
 '忠仆' => '忠僕',
-'忠于' => '忠於',
 '快快当当' => '快快當當',
 '快冲' => '快衝',
 '怎么干' => '怎麼幹',
-'怒于' => '怒於',
 '怒气冲天' => '怒氣衝天',
 '怒火冲天' => '怒火衝天',
 '怒发冲冠' => '怒髮衝冠',
 '怜奈' => '怜奈',
 '思如泉涌' => '思如泉湧',
-'怠于' => '怠於',
-'急于' => '急於',
 '急冲而下' => '急衝而下',
 '性别扭曲' => '性別扭曲',
 '性征' => '性徵',
@@ -5463,7 +5379,6 @@ public static $zh2Hant = [
 '愛河里花子' => '愛河里花子',
 '爱河里花子' => '愛河里花子',
 '爱困' => '愛睏',
-'感于' => '感於',
 '愿朴' => '愿樸',
 '愿樸' => '愿樸',
 '愿而恭' => '愿而恭',
@@ -5508,13 +5423,11 @@ public static $zh2Hant = [
 '悬钟' => '懸鐘',
 '懿范' => '懿範',
 '恋恋不舍' => '戀戀不捨',
-'成于' => '成於',
 '成于思' => '成於思',
 '戬谷' => '戩穀',
 '截发' => '截髮',
 '战天斗地' => '戰天鬥地',
 '战栗' => '戰慄',
-'战于' => '戰於',
 '战斗' => '戰鬥',
 '戏里' => '戲裡',
 '戲院里' => '戲院里',
@@ -5621,14 +5534,10 @@ public static $zh2Hant = [
 '拉面部' => '拉面部',
 '拉面' => '拉麵',
 '拌面' => '拌麵',
-'拒人于' => '拒人於',
-'拒于' => '拒於',
 '拓朴' => '拓樸',
 '拔发' => '拔髮',
 '拔须' => '拔鬚',
 '拗别' => '拗彆',
-'拘于' => '拘於',
-'拙于' => '拙於',
 '拙朴' => '拙樸',
 '拼却' => '拚卻',
 '拼命' => '拚命',
@@ -5811,10 +5720,8 @@ public static $zh2Hant = [
 '提心吊胆' => '提心弔膽',
 '提摩太后书' => '提摩太後書',
 '提高后' => '提高後',
-'插于' => '插於',
 '换签' => '換籤',
 '换只' => '換隻',
-'换发' => '換髮',
 '握发' => '握髮',
 '揩干' => '揩乾',
 '揪采' => '揪採',
@@ -5824,7 +5731,6 @@ public static $zh2Hant = [
 '挥手表' => '揮手表',
 '揮手表' => '揮手表',
 '搋面' => '搋麵',
-'损于' => '損於',
 '搏斗' => '搏鬥',
 '捣鬼吊白' => '搗鬼弔白',
 '扼肮' => '搤肮',
@@ -5858,7 +5764,6 @@ public static $zh2Hant = [
 '撤并' => '撤併',
 '拨谷' => '撥穀',
 '撩斗' => '撩鬥',
-'播于' => '播於',
 '扑冬' => '撲鼕',
 '扑咚' => '撲鼕',
 '扑咚咚' => '撲鼕鼕',
@@ -5886,16 +5791,12 @@ public static $zh2Hant = [
 '放松' => '放鬆',
 '政斗' => '政鬥',
 '故云' => '故云',
-'敏于' => '敏於',
-'败于' => '敗於',
 '教学钟' => '教學鐘',
-'教于' => '教於',
 '教范' => '教範',
 '敢干' => '敢幹',
 '敢情欲' => '敢情欲',
 '敢斗了胆' => '敢斗了膽',
 '散伙' => '散夥',
-'散于' => '散於',
 '散荡' => '散蕩',
 '敦朴' => '敦樸',
 '敬挽' => '敬輓',
@@ -5946,15 +5847,12 @@ public static $zh2Hant = [
 '方便面' => '方便麵',
 '方向' => '方向',
 '方法里' => '方法裡',
-'于后' => '於後',
-'于征' => '於徵',
 '于海上' => '於海上',
 '于海边' => '於海邊',
 '于震中' => '於震中',
 '于震前' => '於震前',
 '于震后' => '於震後',
 '施舍' => '施捨',
-'施于' => '施於',
 '施舍之道' => '施舍之道',
 '旁征博引' => '旁徵博引',
 '旁注' => '旁註',
@@ -5967,7 +5865,6 @@ public static $zh2Hant = [
 '日历史' => '日歷史',
 '日里' => '日裡',
 '日志' => '日誌',
-'早于' => '早於',
 '旱干' => '旱乾',
 '升州' => '昇州',
 '升平' => '昇平',
@@ -5978,7 +5875,6 @@ public static $zh2Hant = [
 '明窗净几' => '明窗淨几',
 '明范' => '明範',
 '明鉴' => '明鑑',
-'易于' => '易於',
 '昔人有云' => '昔人有云',
 '星历' => '星曆',
 '星期后' => '星期後',
@@ -5990,7 +5886,6 @@ public static $zh2Hant = [
 '时钟' => '時鐘',
 '时间不准' => '時間不準',
 '晃荡' => '晃蕩',
-'晚于' => '晚於',
 '晚钟' => '晚鐘',
 '晞发' => '晞髮',
 '晨钟' => '晨鐘',
@@ -6065,7 +5960,6 @@ public static $zh2Hant = [
 '有只' => '有隻',
 '有余' => '有餘',
 '有发头陀寺' => '有髮頭陀寺',
-'服于' => '服於',
 '望了望' => '望了望',
 '望后石' => '望后石',
 '朝乾夕惕' => '朝乾夕惕',
@@ -6135,7 +6029,6 @@ public static $zh2Hant = [
 '枯干' => '枯乾',
 '架钟' => '架鐘',
 '某只' => '某隻',
-'染指于' => '染指於',
 '染殿后' => '染殿后',
 '染发' => '染髮',
 '柜上' => '柜上',
@@ -6150,7 +6043,6 @@ public static $zh2Hant = [
 '校准' => '校準',
 '校舍' => '校舍',
 '核准' => '核准',
-'格于' => '格於',
 '格范' => '格範',
 '格里历' => '格里曆',
 '格里高利历' => '格里高利曆',
@@ -6193,7 +6085,6 @@ public static $zh2Hant = [
 '杠杆' => '槓桿',
 '乐器钟' => '樂器鐘',
 '乐游原' => '樂遊原',
-'樊于期' => '樊於期',
 '梁上' => '樑上',
 '梁柱' => '樑柱',
 '樗里子' => '樗里子',
@@ -6258,7 +6149,6 @@ public static $zh2Hant = [
 '歌后' => '歌后',
 '歌钟' => '歌鐘',
 '欧游' => '歐遊',
-'止于' => '止於',
 '正官庄' => '正官庄',
 '正文里' => '正文裡',
 '正杰' => '正杰',
@@ -6269,10 +6159,8 @@ public static $zh2Hant = [
 '歲聿云暮' => '歲聿云暮',
 '历史里' => '歷史裡',
 '归并' => '歸併',
-'归于' => '歸於',
 '归余' => '歸餘',
 '歹斗' => '歹鬥',
-'死于' => '死於',
 '死里求生' => '死裡求生',
 '死里逃生' => '死裡逃生',
 '殖谷' => '殖穀',
@@ -6282,8 +6170,8 @@ public static $zh2Hant = [
 '殷师牛斗' => '殷師牛鬥',
 '殷鉴' => '殷鑑',
 '壳里' => '殼裡',
+'殿里' => '殿裡',
 '殿钟自鸣' => '殿鐘自鳴',
-'毁于' => '毀於',
 '毁钟为铎' => '毀鐘為鐸',
 '殴斗' => '毆鬥',
 '母后' => '母后',
@@ -6323,7 +6211,6 @@ public static $zh2Hant = [
 '污蔑' => '污衊',
 '汤卤' => '汤滷',
 '汤滷' => '汤滷',
-'汲于' => '汲於',
 '决斗' => '決鬥',
 '沈淀' => '沈澱',
 '沈郁' => '沈鬱',
@@ -6354,7 +6241,6 @@ public static $zh2Hant = [
 '泡面' => '泡麵',
 '波棱菜' => '波稜菜',
 '波发藻' => '波髮藻',
-'泥于' => '泥於',
 '注云' => '注云',
 '注释' => '注釋',
 '泰山梁木' => '泰山梁木',
@@ -6379,7 +6265,6 @@ public static $zh2Hant = [
 '洪钟' => '洪鐘',
 '汹涌' => '洶湧',
 '流征' => '流徵',
-'流于' => '流於',
 '流荡' => '流蕩',
 '流风余俗' => '流風餘俗',
 '流风余韵' => '流風餘韻',
@@ -6387,7 +6272,6 @@ public static $zh2Hant = [
 '浩荡' => '浩蕩',
 '浪荡' => '浪蕩',
 '浪游' => '浪遊',
-'浮于' => '浮於',
 '浮荡' => '浮蕩',
 '浮夸' => '浮誇',
 '浮松' => '浮鬆',
@@ -6428,7 +6312,6 @@ public static $zh2Hant = [
 '淑范' => '淑範',
 '泪干' => '淚乾',
 '泪如泉涌' => '淚如泉湧',
-'淡于' => '淡於',
 '淡蒙蒙' => '淡濛濛',
 '净余' => '淨餘',
 '净发' => '淨髮',
@@ -6465,7 +6348,6 @@ public static $zh2Hant = [
 '汤下面' => '湯下麵',
 '汤团' => '湯糰',
 '汤面' => '湯麵',
-'源于' => '源於',
 '准不准' => '準不準',
 '准例' => '準例',
 '准保' => '準保',
@@ -6502,10 +6384,8 @@ public static $zh2Hant = [
 '沟大曲' => '溝大麯',
 '沟谷' => '溝谷',
 '溟蒙' => '溟濛',
-'溢于' => '溢於',
 '温洛克期' => '溫洛克期',
 '溲面' => '溲麵',
-'溺于' => '溺於',
 '滃郁' => '滃鬱',
 '滑借' => '滑藉',
 '汇丰' => '滙豐',
@@ -6548,7 +6428,6 @@ public static $zh2Hant = [
 '潜水钟表' => '潛水鐘錶',
 '潭里' => '潭裡',
 '潮涌' => '潮湧',
-'溃于' => '潰於',
 '涩谷区' => '澀谷區',
 '澄江县' => '澂江縣',
 '澄澹精致' => '澄澹精致',
@@ -6689,10 +6568,8 @@ public static $zh2Hant = [
 '犖确' => '犖确',
 '荦确' => '犖确',
 '狂并潮' => '狂併潮',
-'狃于' => '狃於',
 '狄志杰' => '狄志杰',
 '狐借虎威' => '狐藉虎威',
-'猛于' => '猛於',
 '猛冲' => '猛衝',
 '猜三划五' => '猜三划五',
 '犹如表' => '猶如錶',
@@ -6717,7 +6594,6 @@ public static $zh2Hant = [
 '王余鱼' => '王餘魚',
 '珍肴异馔' => '珍肴異饌',
 '班里' => '班裡',
-'现于' => '現於',
 '球台' => '球檯',
 '理一个发' => '理一個髮',
 '理一次发' => '理一次髮',
@@ -6734,13 +6610,11 @@ public static $zh2Hant = [
 '瓷制' => '瓷製',
 '甄后' => '甄后',
 '瓮安' => '甕安',
-'甚于' => '甚於',
 '甜、咸' => '甜、鹹',
 '甜水面' => '甜水麵',
 '甜咸' => '甜鹹',
 '甜面酱' => '甜麵醬',
 '生力面' => '生力麵',
-'生于' => '生於',
 '生物钟' => '生物鐘',
 '生发生' => '生發生',
 '生华发' => '生華髮',
@@ -6748,26 +6622,22 @@ public static $zh2Hant = [
 '生锈' => '生鏽',
 '生发' => '生髮',
 '苏醒' => '甦醒',
-'用于' => '用於',
 '用法里' => '用法裡',
 '甩发' => '甩髮',
 '田子里' => '田子里',
 '田庄英雄' => '田庄英雄',
 '田里' => '田裡',
+'田里穗' => '田里穗',
 '由余' => '由余',
-'由于' => '由於',
 '甲胄' => '甲冑',
 '甲后路' => '甲后路',
 '男仆' => '男僕',
 '界里' => '界裡',
-'畏于' => '畏於',
 '留发展' => '留發展',
 '留发生' => '留發生',
 '留发行' => '留發行',
 '留长发' => '留長髮',
 '留发' => '留髮',
-'毕于' => '畢於',
-'毕业于' => '畢業於',
 '毕生发展' => '畢生發展',
 '画里' => '畫裡',
 '当准' => '當準',
@@ -6777,7 +6647,6 @@ public static $zh2Hant = [
 '疏松' => '疏鬆',
 '疑系' => '疑係',
 '疑凶' => '疑兇',
-'疲于' => '疲於',
 '疲困' => '疲睏',
 '病征' => '病徵',
 '病愈' => '病癒',
@@ -6819,7 +6688,6 @@ public static $zh2Hant = [
 '百周后' => '百周後',
 '百天后' => '百天後',
 '百子里' => '百子里',
-'百年' => '百年',
 '百拙千丑' => '百拙千醜',
 '百科里' => '百科裡',
 '百谷' => '百穀',
@@ -6855,7 +6723,6 @@ public static $zh2Hant = [
 '皱折' => '皺摺',
 '盆吊' => '盆弔',
 '盈余' => '盈餘',
-'益于' => '益於',
 '盒里' => '盒裡',
 '盛赞' => '盛讚',
 '盗采' => '盜採',
@@ -6866,14 +6733,12 @@ public static $zh2Hant = [
 '卢棱伽' => '盧稜伽',
 '荡气回肠' => '盪氣迴腸',
 '盲干' => '盲幹',
-'直于' => '直於',
 '直冲' => '直衝',
 '相并' => '相併',
 '相克制' => '相克制',
 '相克服' => '相克服',
 '相克' => '相剋',
 '相干' => '相干',
-'相于' => '相於',
 '相冲' => '相衝',
 '相斗' => '相鬥',
 '看法里' => '看法裡',
@@ -6889,8 +6754,6 @@ public static $zh2Hant = [
 '眼眶里' => '眼眶裡',
 '眼睛里' => '眼睛裡',
 '眼里' => '眼裡',
-'着眼于' => '着眼於',
-'着眼於' => '着眼於',
 '困乏' => '睏乏',
 '困倦' => '睏倦',
 '困觉' => '睏覺',
@@ -6913,7 +6776,6 @@ public static $zh2Hant = [
 '瞩托' => '矚託',
 '矜夸' => '矜誇',
 '短几' => '短几',
-'短于' => '短於',
 '短发生' => '短發生',
 '短发' => '短髮',
 '矮几' => '矮几',
@@ -6955,7 +6817,6 @@ public static $zh2Hant = [
 '祭吊' => '祭弔',
 '禁欲' => '禁慾',
 '禁欲主义' => '禁欲主義',
-'祸于' => '禍於',
 '御侮' => '禦侮',
 '御寇' => '禦寇',
 '御寒' => '禦寒',
@@ -6991,7 +6852,6 @@ public static $zh2Hant = [
 '秒钟' => '秒鐘',
 '秤杆' => '秤桿',
 '秦沈客运' => '秦瀋客運',
-'移祸于' => '移禍於',
 '稀松' => '稀鬆',
 '程十发' => '程十髮',
 '棱台' => '稜台',
@@ -7022,6 +6882,7 @@ public static $zh2Hant = [
 '谷旦' => '穀旦',
 '谷梁' => '穀梁',
 '谷壳' => '穀殼',
+'谷氨' => '穀氨',
 '谷物' => '穀物',
 '谷皮' => '穀皮',
 '谷神' => '穀神',
@@ -7029,6 +6890,7 @@ public static $zh2Hant = [
 '谷谷' => '穀穀',
 '谷米' => '穀米',
 '谷粒' => '穀粒',
+'谷胱' => '穀胱',
 '谷舱' => '穀艙',
 '谷苗' => '穀苗',
 '谷草' => '穀草',
@@ -7057,11 +6919,9 @@ public static $zh2Hant = [
 '窗帘' => '窗簾',
 '窝里' => '窩裡',
 '窝里斗' => '窩裡鬥',
-'穷于' => '窮於',
 '穷追不舍' => '窮追不捨',
 '穷发' => '窮髮',
 '窃钟掩耳' => '竊鐘掩耳',
-'立于' => '立於',
 '立范' => '立範',
 '童仆' => '童僕',
 '竞斗' => '競鬥',
@@ -7074,7 +6934,6 @@ public static $zh2Hant = [
 '笑里藏刀' => '笑裡藏刀',
 '笔杆' => '筆桿',
 '笔秃墨干' => '筆禿墨乾',
-'等于' => '等於',
 '笋干' => '筍乾',
 '筑前' => '筑前',
 '筑北' => '筑北',
@@ -7144,7 +7003,6 @@ public static $zh2Hant = [
 '精制住' => '精制住',
 '精制服' => '精制服',
 '精干' => '精幹',
-'精于' => '精於',
 '精准' => '精準',
 '精致' => '精緻',
 '精制' => '精製',
@@ -7197,17 +7055,14 @@ public static $zh2Hant = [
 '细如发' => '細如髮',
 '细致' => '細緻',
 '细炼' => '細鍊',
-'终于' => '終於',
 '组里' => '組裡',
 '结伴同游' => '結伴同遊',
 '结伙' => '結夥',
 '结扎' => '結紮',
 '结余' => '結餘',
 '结发' => '結髮',
-'绝于' => '絕於',
 '绞干' => '絞乾',
 '络腮胡' => '絡腮鬍',
-'给于' => '給於',
 '丝恩发怨' => '絲恩髮怨',
 '丝制' => '絲製',
 '丝发' => '絲髮',
@@ -7301,15 +7156,12 @@ public static $zh2Hant = [
 '坛子' => '罈子',
 '坛坛罐罐' => '罈罈罐罐',
 '坛騞' => '罈騞',
-'置于' => '置於',
 '置言成范' => '置言成範',
-'罢于' => '罷於',
 '罗马历' => '羅馬曆',
 '罗马历代' => '羅馬歷代',
 '罗马历史' => '羅馬歷史',
 '羁系' => '羈繫',
 '美容美发' => '美容美髮',
-'美于' => '美於',
 '美丑' => '美醜',
 '美发学' => '美髮學',
 '美发师' => '美髮師',
@@ -7331,7 +7183,6 @@ public static $zh2Hant = [
 '老仆' => '老僕',
 '老干部' => '老幹部',
 '老懞' => '老懞',
-'老于' => '老於',
 '老爷钟' => '老爺鐘',
 '老白干' => '老白乾',
 '老姜' => '老薑',
@@ -7343,7 +7194,6 @@ public static $zh2Hant = [
 '耕获' => '耕穫',
 '耳余' => '耳餘',
 '耶律术烈' => '耶律朮烈',
-'耿于' => '耿於',
 '聊斋志异' => '聊齋志異',
 '圣人历' => '聖人曆',
 '圣后' => '聖后',
@@ -7355,7 +7205,6 @@ public static $zh2Hant = [
 '闻风后' => '聞風後',
 '联系' => '聯繫',
 '声母后' => '聲母後',
-'听于' => '聽於',
 '肉干' => '肉乾',
 '肉欲' => '肉慾',
 '肉丝面' => '肉絲麵',
@@ -7441,7 +7290,6 @@ public static $zh2Hant = [
 '自制服' => '自制服',
 '自制的能' => '自制的能',
 '自制能力' => '自制能力',
-'自于' => '自於',
 '自然数里' => '自然數裡',
 '自由钟' => '自由鐘',
 '自制' => '自製',
@@ -7450,11 +7298,8 @@ public static $zh2Hant = [
 '臭气冲天' => '臭氣衝天',
 '至多' => '至多',
 '至多只' => '至多只',
-'至于' => '至於',
-'致于' => '致於',
 '台佟' => '臺佟',
 '台静农' => '臺靜農',
-'臻于' => '臻於',
 '舂谷' => '舂穀',
 '举手表' => '舉手表',
 '舉手表' => '舉手表',
@@ -7493,7 +7338,6 @@ public static $zh2Hant = [
 '苑里' => '苑裡',
 '若干' => '若干',
 '苦干' => '苦幹',
-'苦于' => '苦於',
 '苦里' => '苦裡',
 '苦斗' => '苦鬥',
 '苧麻' => '苧麻',
@@ -7540,8 +7384,6 @@ public static $zh2Hant = [
 '万个' => '萬個',
 '万周后' => '萬周後',
 '万天后' => '萬天後',
-'万年' => '萬年',
-'万年历' => '萬年曆',
 '万年历表' => '萬年曆錶',
 '万历' => '萬曆',
 '万历史' => '萬歷史',
@@ -7550,7 +7392,6 @@ public static $zh2Hant = [
 '万象' => '萬象',
 '万只' => '萬隻',
 '万余' => '萬餘',
-'落于' => '落於',
 '落腮胡' => '落腮鬍',
 '落发' => '落髮',
 '叶叶琴' => '葉叶琴',
@@ -7562,7 +7403,6 @@ public static $zh2Hant = [
 '葡萄干' => '葡萄乾',
 '董氏封发' => '董氏封髮',
 '葫芦里卖甚么药' => '葫蘆裡賣甚麼藥',
-'葬于' => '葬於',
 '蒙雾露' => '蒙霧露',
 '蒜发' => '蒜髮',
 '蒲席' => '蒲蓆',
@@ -7639,7 +7479,6 @@ public static $zh2Hant = [
 '借箸代筹' => '藉箸代籌',
 '借资' => '藉資',
 '蓝淀' => '藍澱',
-'藏于' => '藏於',
 '藏历' => '藏曆',
 '藏历史' => '藏歷史',
 '藏蒙歌儿' => '藏矇歌兒',
@@ -7657,7 +7496,6 @@ public static $zh2Hant = [
 '萝卜干' => '蘿蔔乾',
 '虎须' => '虎鬚',
 '虎斗' => '虎鬥',
-'处于' => '處於',
 '虚夸' => '虛誇',
 '号志' => '號誌',
 '虫部' => '虫部',
@@ -7686,7 +7524,6 @@ public static $zh2Hant = [
 '行事历史' => '行事歷史',
 '行凶' => '行兇',
 '行家里手' => '行家裡手',
-'行于' => '行於',
 '卫后庄公' => '衛後莊公',
 '卫星钟' => '衛星鐘',
 '冲上' => '衝上',
@@ -7740,7 +7577,6 @@ public static $zh2Hant = [
 '冲风' => '衝風',
 '衡鉴' => '衡鑑',
 '表面包' => '表面包',
-'衷于' => '衷於',
 '袋杆' => '袋桿',
 '袋里' => '袋裡',
 '袋表' => '袋錶',
@@ -7762,7 +7598,6 @@ public static $zh2Hant = [
 '里海' => '裏海',
 '里白' => '裏白',
 '里运河' => '裏運河',
-'补于' => '補於',
 '补注' => '補註',
 '装折' => '裝摺',
 '里勾外连' => '裡勾外連',
@@ -7879,12 +7714,10 @@ public static $zh2Hant = [
 '要冲' => '要衝',
 '复信' => '覆信',
 '复核' => '覆核',
-'见于' => '見於',
 '见棱见角' => '見稜見角',
 '见素抱朴' => '見素抱樸',
 '见钟不打' => '見鐘不打',
 '规范' => '規範',
-'视于' => '視於',
 '观采' => '觀採',
 '角抵' => '角牴',
 '角落发' => '角落發',
@@ -7954,7 +7787,6 @@ public static $zh2Hant = [
 '词干' => '詞幹',
 '词汇' => '詞彙',
 '词余' => '詞餘',
-'询于' => '詢於',
 '试制' => '試製',
 '詩云' => '詩云',
 '诗云' => '詩云',
@@ -8134,7 +7966,6 @@ public static $zh2Hant = [
 '趙惠后' => '趙惠后',
 '赵治勋' => '趙治勳',
 '趱干' => '趲幹',
-'足于' => '足於',
 '足球台' => '足球台',
 '跌扑' => '跌扑',
 '路图里' => '路圖裡',
@@ -8147,10 +7978,8 @@ public static $zh2Hant = [
 '踡局' => '踡跼',
 '逾闲' => '踰閑',
 '蹒局' => '蹣跼',
-'蹪于' => '蹪於',
 '蹭棱子' => '蹭稜子',
 '躁郁' => '躁鬱',
-'身于' => '身於',
 '身体发肤' => '身體髮膚',
 '躯干' => '軀幹',
 '车库里' => '車庫裡',
@@ -8159,7 +7988,6 @@ public static $zh2Hant = [
 '车里雅宾斯克' => '車里雅賓斯克',
 '轨范' => '軌範',
 '轩辟' => '軒闢',
-'较于' => '較於',
 '挽曲' => '輓曲',
 '挽歌' => '輓歌',
 '挽联' => '輓聯',
@@ -8168,7 +7996,6 @@ public static $zh2Hant = [
 '挽车' => '輓車',
 '挽输' => '輓輸',
 '挽辞' => '輓辭',
-'轻于' => '輕於',
 '轻松' => '輕鬆',
 '轻松松' => '輕鬆鬆',
 '轮奸' => '輪姦',
@@ -8193,7 +8020,6 @@ public static $zh2Hant = [
 '近日无仇' => '近日無讎',
 '返朴' => '返樸',
 '迥然回异' => '迥然迴異',
-'迫于' => '迫於',
 '回光返照' => '迴光返照',
 '回圈' => '迴圈',
 '回廊' => '迴廊',
@@ -8221,7 +8047,6 @@ public static $zh2Hant = [
 '回銮' => '迴鑾',
 '回响' => '迴響',
 '回风' => '迴風',
-'迷于' => '迷於',
 '迷蒙' => '迷濛',
 '追凶' => '追兇',
 '退伙' => '退夥',
@@ -8265,7 +8090,6 @@ public static $zh2Hant = [
 '这出' => '這齣',
 '通奸' => '通姦',
 '通心面' => '通心麵',
-'通于' => '通於',
 '通历' => '通曆',
 '通历史' => '通歷史',
 '通鉴' => '通鑑',
@@ -8334,17 +8158,13 @@ public static $zh2Hant = [
 '游错' => '遊錯',
 '游骑兵' => '遊騎兵',
 '游魂' => '遊魂',
-'过于' => '過於',
 '过水面' => '過水麵',
 '遏制' => '遏制',
 '道范' => '道範',
-'逊于' => '遜於',
 '递回' => '遞迴',
 '远游' => '遠遊',
 '遨游' => '遨遊',
-'适于' => '適於',
 '遮丑' => '遮醜',
-'迁于' => '遷於',
 '选手表明' => '選手表明',
 '选手表决' => '選手表決',
 '选手表现' => '選手表現',
@@ -8386,7 +8206,6 @@ public static $zh2Hant = [
 '部落发' => '部落發',
 '郭后' => '郭后',
 '都市里' => '都市裡',
-'都于' => '都於',
 '乡愿' => '鄉愿',
 '鄉愿' => '鄉愿',
 '郑凯云' => '鄭凱云',
@@ -8404,7 +8223,6 @@ public static $zh2Hant = [
 '酸姜' => '酸薑',
 '腌制' => '醃製',
 '醇朴' => '醇樸',
-'醉于' => '醉於',
 '醋坛' => '醋罈',
 '丑丫头' => '醜丫頭',
 '丑事' => '醜事',
@@ -8431,7 +8249,6 @@ public static $zh2Hant = [
 '丑恶' => '醜惡',
 '丑态' => '醜態',
 '丑毙了' => '醜斃了',
-'丑于' => '醜於',
 '丑末' => '醜末',
 '丑样' => '醜樣',
 '丑死' => '醜死',
@@ -8470,7 +8287,6 @@ public static $zh2Hant = [
 '里海茨' => '里海茨',
 '里铺' => '里舖',
 '重回' => '重回',
-'重于' => '重於',
 '重罗面' => '重羅麵',
 '重制' => '重製',
 '重复' => '重複',
@@ -8632,16 +8448,15 @@ public static $zh2Hant = [
 '鉴察' => '鑑察',
 '鉴往知来' => '鑑往知來',
 '鉴戒' => '鑑戒',
+'鉴于' => '鑑於',
 '鉴湖' => '鑑湖',
 '鉴藏' => '鑑藏',
 '鉴谅' => '鑑諒',
 '鉴证' => '鑑證',
 '鉴识' => '鑑識',
 '鉴赏' => '鑑賞',
-'鉴于' => '鑒於',
 '長几' => '長几',
 '长几' => '長几',
-'长于' => '長於',
 '长历' => '長曆',
 '长历史' => '長歷史',
 '长发公主' => '長髮公主',
@@ -8672,7 +8487,6 @@ public static $zh2Hant = [
 '闯荡' => '闖蕩',
 '闯炼' => '闖鍊',
 '关系' => '關係',
-'关于' => '關於',
 '辟佛' => '闢佛',
 '辟作' => '闢作',
 '辟划' => '闢劃',
@@ -8690,9 +8504,7 @@ public static $zh2Hant = [
 '防御' => '防禦',
 '防范' => '防範',
 '防锈' => '防鏽',
-'阻于' => '阻於',
 '阿里' => '阿里',
-'附于' => '附於',
 '附注' => '附註',
 '限制' => '限制',
 '院里' => '院裡',
@@ -8717,11 +8529,10 @@ public static $zh2Hant = [
 '阳谷' => '陽穀',
 '隆准许' => '隆准許',
 '隆准' => '隆準',
-'é\9a\8fäº\8e' => 'é\9a¨æ\96¼',
+'é\98\9fé\87\8c' => 'é\9a\8a裡',
 '隐占' => '隱佔',
 '隐几' => '隱几',
 '隱几' => '隱几',
-'隐于' => '隱於',
 '只字' => '隻字',
 '只影' => '隻影',
 '只手遮天' => '隻手遮天',
@@ -8732,7 +8543,6 @@ public static $zh2Hant = [
 '雅范' => '雅範',
 '集团' => '集團',
 '集数里' => '集數裡',
-'集于' => '集於',
 '集里' => '集裡',
 '集游法' => '集遊法',
 '雕梁画栋' => '雕樑畫棟',
@@ -8752,9 +8562,7 @@ public static $zh2Hant = [
 '鸡腿面' => '雞腿麵',
 '鸡蛋里挑骨头' => '雞蛋裡挑骨頭',
 '鸡只' => '雞隻',
-'离于' => '離於',
 '难舍' => '難捨',
-'难于' => '難於',
 '雨蒙蒙' => '雨濛濛',
 '雪窗萤几' => '雪窗螢几',
 '雪窗螢几' => '雪窗螢几',
@@ -8770,7 +8578,6 @@ public static $zh2Hant = [
 '零个' => '零個',
 '零周后' => '零周後',
 '零天后' => '零天後',
-'零年' => '零年',
 '零只' => '零隻',
 '零余' => '零餘',
 '电子表格' => '電子表格',
@@ -8841,7 +8648,6 @@ public static $zh2Hant = [
 '頂多' => '頂多',
 '顶多' => '頂多',
 '项链' => '項鍊',
-'顺于' => '順於',
 '顺钟向' => '順鐘向',
 '顺风后' => '順風後',
 '须根据' => '須根據',
@@ -9364,7 +9170,6 @@ public static $zh2Hant = [
 '盐卤' => '鹽滷',
 '盐余' => '鹽餘',
 '鹿場里' => '鹿場里',
-'丽于' => '麗於',
 '麟游' => '麟遊',
 '曲酒' => '麯酒',
 '曲尘' => '麴塵',
@@ -14143,8 +13948,6 @@ public static $zh2TW = [
 '发达国家' => '已開發國家',
 '巴塞罗那' => '巴塞隆納',
 '巴塞隆拿' => '巴塞隆納',
-'巴布亚新几内亚' => '巴布亞紐幾內亞',
-'巴布亞新畿內亞' => '巴布亞紐幾內亞',
 '巴士拉' => '巴斯拉',
 '巴巴多斯' => '巴貝多',
 '佈' => '布',
@@ -14165,7 +13968,6 @@ public static $zh2TW = [
 '账' => '帳',
 '干着急' => '干著急',
 '干着' => '幹著',
-'畿內亞' => '幾內亞',
 '几内亚比绍' => '幾內亞比索',
 '幾內亞比紹' => '幾內亞比索',
 '比利牛斯' => '庇里牛斯',
@@ -14228,6 +14030,8 @@ public static $zh2TW = [
 '數碼電視' => '數位電視',
 '調制解調器' => '數據機',
 '调制解调器' => '數據機',
+'斯堪的納維亞' => '斯堪地那維亞',
+'斯堪的纳维亚' => '斯堪地那維亞',
 '斯洛文尼亚' => '斯洛維尼亞',
 '斯洛文尼亞' => '斯洛維尼亞',
 '新罕布什尔' => '新罕布夏',
@@ -14386,6 +14190,7 @@ public static $zh2TW = [
 '新奥尔良' => '紐奧良',
 '新奧爾良' => '紐奧良',
 '新几内亚' => '紐幾內亞',
+'新幾內亞' => '紐幾內亞',
 '新西兰' => '紐西蘭',
 '新西蘭' => '紐西蘭',
 '紙煙' => '紙菸',
@@ -14707,7 +14512,6 @@ public static $zh2HK = [
 '·威尔士' => '·威爾士',
 '·威爾士' => '·威爾士',
 '一地里' => '一地裏',
-'一年里' => '一年裏',
 '三十六著' => '三十六着',
 '三極體' => '三極管',
 '旧金山' => '三藩市',
@@ -15398,6 +15202,7 @@ public static $zh2HK = [
 '地占' => '地佔',
 '地图里' => '地圖裏',
 '堪培拉' => '坎培拉',
+'坐台铁' => '坐台鐵',
 '坐台' => '坐枱',
 '坐著' => '坐着',
 '坐著作' => '坐著作',
@@ -15565,7 +15370,6 @@ public static $zh2HK = [
 '巴塞罗那' => '巴塞隆拿',
 '巴塞隆納' => '巴塞隆拿',
 '巴貝多' => '巴巴多斯',
-'巴布亞紐幾內亞' => '巴布亞新畿內亞',
 '巴士拉' => '巴斯拉',
 '巷里' => '巷裏',
 '市占' => '市佔',
@@ -15602,6 +15406,7 @@ public static $zh2HK = [
 '賓士' => '平治',
 '年代里' => '年代裏',
 '年里' => '年裏',
+'年里约' => '年里約',
 '干着' => '幹着',
 '幹著' => '幹着',
 '幹著名' => '幹著名',
@@ -16043,9 +15848,11 @@ public static $zh2HK = [
 '斥著者' => '斥著者',
 '斥著述' => '斥著述',
 '斥著錄' => '斥著錄',
+'斯堪地那維亞' => '斯堪的納維亞',
 '史瓦濟蘭' => '斯威士蘭',
 '斯洛維尼亞' => '斯洛文尼亞',
 '紐澳良' => '新奧爾良',
+'紐幾內亞' => '新幾內亞',
 '紐西蘭' => '新西蘭',
 '方法里' => '方法裏',
 '族里' => '族裏',
@@ -16222,6 +16029,7 @@ public static $zh2HK = [
 '殺著述' => '殺著述',
 '殺著錄' => '殺著錄',
 '壳里' => '殼裏',
+'殿里' => '殿裏',
 '茅利塔尼亞' => '毛里塔尼亞',
 '模里西斯' => '毛里裘斯',
 '毛里求斯' => '毛里裘斯',
@@ -16511,8 +16319,6 @@ public static $zh2HK = [
 '過著述' => '當著述',
 '當著錄' => '當著錄',
 '過著錄' => '當著錄',
-'几内亚' => '畿內亞',
-'幾內亞' => '畿內亞',
 '迭代' => '疊代',
 '疑著' => '疑着',
 '疑著作' => '疑著作',
@@ -17507,6 +17313,7 @@ public static $zh2HK = [
 '陪著述' => '陪著述',
 '陪著錄' => '陪著錄',
 '阴沟里翻船' => '陰溝裏翻船',
+'队里' => '隊裏',
 '隔著' => '隔着',
 '隔著作' => '隔著作',
 '隔著名' => '隔著名',
@@ -18082,7 +17889,6 @@ public static $zh2CN = [
 '涼著者' => '凉著者',
 '涼著述' => '凉著述',
 '湊合著' => '凑合着',
-'畿內亞' => '几内亚',
 '幾內亞比索' => '几内亚比绍',
 '凱薩琳' => '凯瑟琳',
 '嘉芙蓮' => '凯瑟琳',
@@ -18515,7 +18321,6 @@ public static $zh2CN = [
 '巴斯拉' => '巴士拉',
 '帕邁拉環礁' => '巴尔米拉环礁',
 '巴貝多' => '巴巴多斯',
-'巴布亞紐幾內亞' => '巴布亚新几内亚',
 '布殊' => '布什',
 '布吉納法索' => '布基纳法索',
 '布隆泉' => '布隆方丹',
@@ -18997,6 +18802,7 @@ public static $zh2CN = [
 '斥著者' => '斥著者',
 '斥著述' => '斥著述',
 '史丹福大學' => '斯坦福大学',
+'斯堪地那維亞' => '斯堪的纳维亚',
 '史達林' => '斯大林',
 '史瓦濟蘭' => '斯威士兰',
 '斯洛維尼亞' => '斯洛文尼亚',
index 794eae2..90b5be8 100644 (file)
        "editfont-monospace": "خط ثابت العرض",
        "editfont-sansserif": "خط بلا زوائد",
        "editfont-serif": "خط بزوائد",
+       "sunday": "الأحد",
+       "tuesday": "الثلاث",
+       "wednesday": "الأربعا",
+       "thursday": "الخميس",
+       "friday": "الجمعة",
+       "saturday": "السبت",
+       "sun": "الأحد",
+       "mon": "الإثنين",
+       "tue": "الثلاث",
+       "wed": "الأربعا",
+       "thu": "الخميس",
+       "fri": "الجمعة",
+       "sat": "السبت",
+       "january": "جانفي",
+       "february": "فيڥري",
+       "march": "مارس",
+       "april": "أڥريل",
+       "may_long": "ماي",
+       "june": "جوان",
+       "july": "جويلية",
+       "august": "أوت",
+       "september": "سبتمبر",
+       "october": "أكتوبر",
+       "november": "نوڥمبر",
+       "december": "ديسمبر",
+       "january-gen": "جانفي",
+       "february-gen": "فيڥري",
+       "march-gen": "مارس",
+       "april-gen": "أڥريل",
+       "may-gen": "ماي",
+       "june-gen": "جوان",
+       "july-gen": "جويلية",
+       "august-gen": "أوت",
+       "september-gen": "سبتمبر",
+       "october-gen": "أكتوبر",
+       "november-gen": "نوڥمبر",
+       "december-gen": "ديسمبر",
+       "jan": "جانفي",
+       "feb": "فيڥري",
+       "mar": "مارس",
+       "apr": "أڥريل",
+       "may": "ماي",
+       "jun": "جوان",
+       "jul": "جويلية",
+       "aug": "أوت",
+       "sep": "سبتمبر",
+       "oct": "أكتوبر",
+       "nov": "نوڥمبر",
+       "dec": "ديسمبر",
        "category_header": "صفحات تصنيف \"$1\"",
        "subcategories": "التصنيفات الفرعية",
        "category-media-header": "الوسائط في التصنيف \"$1\"",
        "broken-file-category": "صفحات تحتوي وصلات ملفات معطوبة",
        "about": "عن",
        "article": "صفحة محتوى",
-       "newwindow": "(تفتح في نافذة جديدة)",
+       "newwindow": "(تتحلّ في شبّاك جديد)",
+       "cancel": "بطّل",
        "mypage": "صفحتي",
        "mytalk": "نقاشي",
+       "returnto": "إرجع لـ$1",
+       "tagline": "من {{SITENAME}}",
+       "help": "معاونة",
+       "search": "لوّج",
+       "searchbutton": "لوّج",
+       "searcharticle": "إمشي",
+       "history": "تاريخ الپاج",
+       "history_short": "التاريخ",
+       "view": "شوفة",
+       "view-foreign": "ورّي على $1",
+       "edit": "بدّل",
+       "talkpagelinktext": "پاج الحديث",
+       "talk": "حديث",
+       "views": "شوفات",
+       "otherlanguages": "في لغات أخرين",
+       "redirectto": "تحويل لـ:",
+       "lastmodifiedat": "آخر تبديل لهذي الپاج كان نهار $1 في $2.",
+       "jumpto": "إمشي لـ:",
+       "jumptosearch": "لوّج",
+       "aboutsite": "على {{SITENAME}}",
        "copyright": "المحتوى متوفر تحت $1.",
+       "edithelp": "معاونة باش تبدّل پاج",
+       "mainpage": "الپاج الأولانيّة",
+       "mainpage-description": "الپاج الأولانيّة",
        "badaccess": "خطأ في السماح",
        "badaccess-group0": "ليس من المسموح لك تنفيذ الفعل الذي طلبته.",
        "badaccess-groups": "الفعل الذي طلبته مقصور على المستخدمين في {{PLURAL:$2||مجموعة|واحدة من مجموعتي|واحدة من مجموعات}}: $1.",
        "versionrequiredtext": "تلزم النسخة $1 من ميدياويكي لاستعمال هذه الصفحة. انظر [[Special:Version|صفحة النسخة]]",
        "youhavenewmessages": "توجد لديك $1 ($2).",
        "youhavenewmessagesmulti": "لديك رسائل جديدة على $1",
+       "editsection": "بدّل",
+       "editlink": "بدّل",
+       "viewsourcelink": "شوف المصدر",
+       "editsectionhint": "بدّل الطرف: $1",
        "viewdeleted": "أأعرض $1؟",
        "restorelink": "{{PLURAL:$1|$1 تعديل محذوف|تعديلا واحدا محذوفا|تعديلين محذوفين|$1 تعديلات محذوفة|$1 تعديلا محذوفا|$1 تعديلا محذوفا}}",
        "feedlinks": "التغذية:",
        "site-rss-feed": "$1 تلقيم أر إس إس",
        "page-rss-feed": "\"$1\" تلقيم أر إس إس",
        "page-atom-feed": "$1 تلقيم أتوم",
+       "red-link-title": "$1 (الپاج ما فمّاش)",
        "sort-descending": "ترتيب تنازلي",
        "sort-ascending": "ترتيب تصاعدي",
+       "nstab-main": "الپاج",
        "nstab-user": "صفحة مستخدم",
        "nstab-media": "صفحة وسيط",
-       "nstab-project": "صفحة مشروع",
+       "nstab-project": "پاج مشروع",
+       "nstab-image": "فيشياي",
        "nstab-template": "قالب",
        "nstab-help": "صفحة مساعدة",
        "nstab-category": "تصنيف",
+       "mainpage-nstab": "الپاج الأولانيّة",
        "nosuchaction": "لا يوجد فعل كهذا",
        "nosuchactiontext": "الفعل المحدد بواسطة المسار غير صحيح.\nربما تكون قد كتبت المسار بطريقة غير صحيحة، أو اتبعت وصلة غير صحيحة.\nهذا ربما يشير أيضا إلى علة في {{SITENAME}}.",
        "nosuchspecialpage": "لا توجد صفحة خاصة بهذا الاسم",
        "logouttext": "'''أنت الآن غير مسجل الدخول.'''\n\nتستطيع المتابعة باستعمال {{SITENAME}} كمجهول، أو <span class='plainlinks'>[$1 الدخول مرة أخرى]</span> بنفس الاسم أو باسم آخر.\nمن الممكن أن ترى بعض الصفحات كما لو أنك مسجل الدخول، وذلك حتى تقوم بإفراغ الصفحات المختزنة في المتصفح لديك.",
        "yourname": "اسم المستخدم:",
        "yourpassword": "كلمة السر:",
+       "userlogin-yourpassword-ph": "دخّل كلمة السر",
+       "createacct-yourpassword-ph": "دخّل كلمة السر",
        "yourpasswordagain": "أعد كتابة كلمة السر:",
+       "createacct-yourpasswordagain-ph": "دخّل كلمة السر مرة أخرى",
        "yourdomainname": "نطاقك:",
        "externaldberror": "هناك إما خطأ في دخول قاعدة البيانات الخارجية أو أنه غير مسموح لك بتحديث حسابك الخارجي.",
        "login": "ادخل",
        "gotaccount": "تمتلك حسابا بالفعل؟ '''$1'''.",
        "gotaccountlink": "ادخل",
        "userlogin-resetlink": "أنسيت بيانات الولوج؟",
+       "createacct-emailoptional": "الإيمايل (إختياري)",
+       "createacct-email-ph": "دخّل الإيمايل متاعك",
        "createaccountmail": "بواسطة البريد الإلكتروني",
        "createaccountreason": "السبب:",
+       "createacct-submit": "أعمل الحساب",
+       "createacct-benefit-heading": "{{SITENAME}} إتّعمل بعباد كيفك.",
+       "createacct-benefit-body3": "آخر {{PLURAL:$1|مساهم|مساهمين}}",
        "badretype": "كلمات السر التي أدخلتها لا تتطابق.",
        "userexists": "اسم المستخدم الذي تم إدخاله مستعمل بالفعل.\nالرجاء اختيار اسم مختلف.",
        "loginerror": "خطأ في الدخول",
        "login-abort-generic": "لم ينجح ولوجك - إجهاض",
        "loginlanguagelabel": "اللغة: $1",
        "suspicious-userlogout": "رفض طلب خروجك لأنه يبدو كأنه أرسل عن طريق متصفح معطوب أو وسيط تخزين.",
-       "pt-login": "Odkul",
+       "pt-login": "أدخل",
+       "pt-createaccount": "أعمل حساب",
+       "pt-userlogout": "أخرج",
        "php-mail-error-unknown": "خطأ غير معروف في وظيفة البريد PHP's mail()",
        "user-mail-no-addy": "لقد حاولت إرسال بريد إلكتروني دون عنوان بريد إلكتروني.",
        "resetpass_announce": "تم تسجيل دخولك بكلمة سر مؤقتة.\nللدخول بشكل نهائي، يجب عليك ضبط كلمة سر جديدة هنا:",
        "resetpass-submit-loggedin": "تغيير كلمة السر",
        "resetpass-wrong-oldpass": "كلمة سر حالية أو مؤقتة غير صحيحة.\nربما تكون غيرت كلمة السر الخاصة بك بنجاح أو طلبت كلمة سر مؤقتة جديدة.",
        "resetpass-temp-password": "كلمة سر مؤقتة:",
-       "passwordreset": "إعادة Ø¶Ø¨Ø· كلمة السر",
+       "passwordreset": "تبدÙ\8aÙ\84 كلمة السر",
        "passwordreset-disabled": "عُطّلت إعادة تعيين كلمة السر على هذه الويكي.",
        "passwordreset-username": "اسم المستخدم:",
        "passwordreset-domain": "النطاق:",
-       "passwordreset-capture": "أأعرض البريد الإلكتروني الناتج؟",
-       "passwordreset-capture-help": "إذا علّمت هذا الصندوق فسيعرض لك البريد الإلكتروني (الذي يحتوي كلمة سر مؤقتة) وسيرسل أيضا للمستخدم.",
        "passwordreset-email": "عنوان البريد الإلكتروني:",
        "passwordreset-emailtitle": "تفاصيل حساب {{SITENAME}}",
        "passwordreset-emailtext-ip": "احد ما (قد يكون انت$1)طلب مذكرة تفاصيل الحساب ل{{SITENAME}} ($4).المستخدم الاتي {{PLURAL:$3|الحساب هو|الحسابات هي}} قد قرن بهذا العنوان :\n\n$2\n\n{{PLURAL:$3|كلمة المرور المؤقتة|كلمات المرور المؤقة}}سينتهي في {{PLURAL:$5|يوم|ايام$5 }}\nمن الافضل ان تسجل الدخول وتختار كلمة مرور جديدة الان .\nإذا قام شخص آخر بهذا الطلب، أو إذا  تذكرت كلمة المرور الأصلية الخاصة بك،ولم تعد ترغب في تغييره، يمكنك تجاهل هذه الرسالة ومتابعة استخدام  كلمة المرورالقديمة.",
        "savearticle": "احفظ الصفحة",
        "preview": "معاينة",
        "showpreview": "أظهر معاينة",
-       "showdiff": "أظهر التغييرات",
+       "showdiff": "ورّي التبديلات",
        "anoneditwarning": "'''تحذير:''' لم تقم بالدخول.\nسيسجل عنوان الآيبي خاصتك في تاريخ هذه الصفحة.",
        "anonpreviewwarning": "''أنت غير مسجل الدخول. الحفظ سيسجل عنوان الأيبي الخاص بك في تاريخ هذه الصفحة.''",
        "missingsummary": "'''تنبيه:''' لم تقم بكتابة ملخص للتعديل.\nإذا قمت بضغط حفظ الصفحة مرة أخرى، فيتم حفظ تعديلك بدون ملخص.",
        "session_fail_preview_html": "'''عذرا! لم نستطع معالجة تعديلك بسبب فقدان بيانات الجلسة.'''\n\n''لأن {{SITENAME}} بها HTML الخام مفعلة، العرض المسبق مخفي كاحتياط ضد هجمات الجافا سكريبت.''\n\n'''إذا كانت هذه محاولة تعديل صادقة، من فضلك حاول مرة أخرى.\nإذا كانت مازالت لا تعمل، حاول [[Special:UserLogout|تسجيل الخروج]] ثم تسجيل الدخول مجددا.'''",
        "token_suffix_mismatch": "'''تعديلك تم رفضه لأن عميلك أخطأ في علامات الترقيم\nفي نص التعديل. تم رفض التعديل لمنع فساد نص المقالة.\nهذا يحدث أحيانا عندما تستخدم خدمة بروكسي مجهول معيبة مبنية على الوب.'''",
        "edit_form_incomplete": "'''بعض أجزاء من نموذج التعديل لم تصل إلى الخادم؛ تأكد من أن تعديلاتك لم تمس وحاول مجددا.'''",
-       "editing": "تحرÙ\8aر $1",
-       "creating": "Ø¥Ù\86شاء «$1»",
-       "editingsection": "تحرÙ\8aر $1 (Ù\82سÙ\85)",
+       "editing": "تبدÙ\8aÙ\84 $1",
+       "creating": "عÙ\85Ù\84اÙ\86 «$1»",
+       "editingsection": "تبدÙ\8aÙ\84 $1 (طرÙ\81)",
        "editingcomment": "تعديل $1 (قسم جديد)",
        "editconflict": "تضارب في التحرير: $1",
        "explainconflict": "لقد عدل شخص آخر هذه الصفحة بعد أن بدأت أنت بتحريرها.\nصندوق النصوص العلوي يحتوي على النص الموجود حاليا في الصفحة.\nوالتغييرات التي قمت أنت بها موجودة في الصندوق في أسفل الصفحة.\nيجب أن تقوم بدمج تغييراتك في النص الموجود حاليا.\n'''فقط''' ما هو موجود في الصندوق العلوي هو ما سيتم حفظه عند الضغط على زر \"حفظ الصفحة\".",
        "semiprotectedpagewarning": "'''ملاحظة:''' تمت حماية هذه الصفحة بحيث يمكن للمستخدمين المسجلين فقط تعديلها.\nآخر مدخلة سجل موفرة بالأسفل كمرجع:",
        "cascadeprotectedwarning": "'''تحذير:''' تمت حماية هذه الصفحة بحيث يستطيع المستخدمون ذوو الصلاحيات الإدارية فقط تعديلها، وذلك لأنها مدمجة في {{PLURAL:$1||الصفحة التالية والتي تمت حمايتها|الصفحتين التاليتين واللتين تمت حمايتها|الصفحات التالية والتي تمت حمايتها}} بخاصية \"حماية الصفحات المدمجة\":",
        "titleprotectedwarning": "'''تحذير:  هذه الصفحة تمت حمايتها بحيث أن [[Special:ListGroupRights|صلاحيات معينة]] مطلوبة لإنشائها.'''\nآخر مدخلة سجل موفرة بالأسفل كمرجع:",
-       "templatesused": "{{PLURAL:$1||اÙ\84Ù\82اÙ\84ب Ø§Ù\84Ù\85ستخدÙ\85|اÙ\84Ù\82اÙ\84باÙ\86 Ø§Ù\84Ù\85ستخدÙ\85اÙ\86|اÙ\84Ù\82Ù\88اÙ\84ب Ø§Ù\84Ù\85ستخدÙ\85Ø©}} Ù\81Ù\8a Ù\87Ø°Ù\87 Ø§Ù\84صÙ\81حة:",
+       "templatesused": "{{PLURAL:$1||اÙ\84Ù\82اÙ\84ب Ø§Ù\84Ù\85ستعÙ\85Ù\84Ø©|اÙ\84Ù\82Ù\88اÙ\84ب Ø§Ù\84Ù\85ستعÙ\85Ù\84Ø©}} Ù\81Ù\8a Ù\87Ø°Ù\8a Ø§Ù\84پاج:",
        "templatesusedpreview": "{{PLURAL:$1||القالب المستخدم|القالبان المستخدمان|القوالب المستخدمة}} في هذه المعاينة:",
        "templatesusedsection": "{{PLURAL:$1||القالب المستخدم|القالبان المستخدمان|القوالب المستخدمة}} في هذا القسم:",
+       "template-protected": "(محمي)",
        "template-semiprotected": "(حماية جزئية)",
        "hiddencategories": "{{PLURAL:$1|هذه الصفحة غير موجودة في أي تصنايف مخفية|هذه الصفحة موجودة في تصنيف مخفي واحد|هذه الصفحة موجودة في تصنيفين مخفيين|هذه الصفحة موجودة في $1 تصانيف مخفية|هذه الصفحة موجودة في $1 تصنيفا مخفيا|هذه الصفحة موجودة في $1 تصنيف مخفي}}:",
        "nocreatetext": "قام {{SITENAME}} بتحديد القدرة على إنشاء صفحات جديدة.\nيمكنك العودة وتحرير صفحة موجودة بالفعل، أو [[Special:UserLogin|الدخول أو تسجيل حساب]].",
        "sectioneditnotsupported-text": "تعديل الأقسام غير مدعوم في هذه الصفحة",
        "permissionserrors": "أخطاء السماحات",
        "permissionserrorstext": "لا تمتلك الصلاحية لفعل هذا، {{PLURAL:$1||للسبب التالي|للسببين التاليين|للأسباب التالية}}:",
-       "permissionserrorstext-withaction": "Ù\84ا ØªÙ\85Ù\84Ù\83 Ø§Ù\84صÙ\84احÙ\8aات Ù\84$2Ø\8c Ù\84Ù\84{{PLURAL:$1||سبب Ø§Ù\84تاÙ\84Ù\8a|سببÙ\8aÙ\86 Ø§Ù\84تاÙ\84Ù\8aÙ\8aÙ\86|أسباب Ø§Ù\84تاÙ\84Ù\8aØ©}}:",
+       "permissionserrorstext-withaction": "Ù\85ا Ø¹Ù\86دÙ\83Ø´ Ø§Ù\84Ø­Ù\82 Ø¨Ø´ $2Ø\8c Ø¹Ù\84Ù\89 Ø®Ø§Ø·Ø±{{PLURAL:$1||Ù\87ا Ø§Ù\84سبب|Ù\87ا Ø§Ù\84أسباب}}:",
        "recreate-moveddeleted-warn": "'''تحذير: أنت تقوم بإعادة إنشاء صفحة سبق حذفها.'''\n\nيجب عليك التيقن من أن الاستمرار بتحرير هذه الصفحة ملائم.\nسجلا الحذف والنقل لهذه الصفحة معروضان هنا للتيسير:",
-       "moveddeleted-notice": "Ù\87Ø°Ù\87 Ø§Ù\84صÙ\81حة ØªÙ\85 Ø­Ø°Ù\81Ù\87ا.\nسجلا الحذف والنقل للصفحة معروضان بالأسفل كمرجع.",
+       "moveddeleted-notice": "Ù\87ا Ø§Ù\84پاج ØªÙ\81سخت.\nسجلا الحذف والنقل للصفحة معروضان بالأسفل كمرجع.",
        "log-fulllog": "أظهر السجل الكامل",
        "edit-hook-aborted": "التعديل تم تركه بواسطة الخطاف.\nلم يعط تفسيرا.",
        "edit-gone-missing": "لم يمكن تحديث الصفحة.\nيبدو أنه تم حذفها.",
        "currentrev-asof": "المراجعة الحالية بتاريخ $1",
        "revision-info": "مراجعة $1 بواسطة $2",
        "previousrevision": "→ مراجعة أقدم",
-       "nextrevision": "Ù\85راجعة Ø£Ø­Ø¯Ø« ←",
+       "nextrevision": "Ù\85راجعة Ø£Ø¬Ø¯Ø¯ ←",
        "currentrevisionlink": "المراجعة الحالية",
        "cur": "الحالي",
        "next": "التالي",
        "rev-suppressed-unhide-diff": "'''أُخفيت''' إحدى مراجعتي هذا الفرق.\nيمكنك العثور على التفاصيل في [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} سجل الإخفاء].\nبإمكانك [$1 رؤية هذا الفرق] إذا أردت المتابعة.",
        "rev-deleted-diff-view": "'''حُذِفت''' إحدى مراجعتي هذا الفرق.\nيمكنك رؤية الفرق؛ ويمكنك العثور على التفاصيل في [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} سجل الحذف].",
        "rev-suppressed-diff-view": "'''أُخفيت''' إحدى مراجعتي هذا الفرق.\nيمكنك رؤية هذا الفرق؛ ويمكنك العثور على التفاصيل في [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} سجل الإخفاء].",
-       "rev-delundel": "أظÙ\87ر/أخÙ\81",
+       "rev-delundel": "ظÙ\87Ù\91ر/خبÙ\91Ù\8a",
        "rev-showdeleted": "أظهر",
        "revisiondelete": "حذف/استرجاع المراجعات",
        "revdelete-nooldid-title": "مراجعة هدف غير صحيحة",
        "revertmerge": "إلغاء الدمج",
        "mergelogpagetext": "بالأسفل قائمة بأحدث عمليات الدمج لتاريخ صفحة ما إلى أخرى.",
        "history-title": " «$1»: تاريخ المراجعة",
-       "difference-title": "«$1»: الفرق بين المراجعتين",
+       "difference-title": "«$1»: الفرق بينات المراجعتين",
        "difference-title-multipage": "«$1» و«$2»: الفرق بين الصفحتين",
        "difference-multipage": "(الفرق بين الصفحتين)",
-       "lineno": "Sţar $1:",
+       "lineno": "سطر $1:",
        "compareselectedversions": "قارن بين النسختين المختارتين",
        "showhideselectedversions": "أظهر/أخف المراجعات المختارة",
+       "editundo": "نحّي",
        "diff-multi-manyusers": "({{PLURAL:$1||مراجعة واحدة متوسطة غير معروضة أجراها|مراجعتان متوسطتان غير معروضتان أجراهما|$1 مراجعات متوسطة غير معروضة أجراها|$1 مراجعة متوسطة غير معروضة أجراها}} أكثر من {{PLURAL:$2||مستخدم واحد|مستخدمين|$2 مستخدمين|$2 مستخدمًا|$2 مستخدم}}.)",
-       "prevn": "{{PLURAL:$1|$1}} السابقة",
-       "nextn": "{{PLURAL:$1|$1}} التالية",
+       "searchresults": "نتايج التلويج",
+       "prevn": "{{PLURAL:$1|$1}} الفايتة",
+       "nextn": "{{PLURAL:$1|$1}} الجاية",
        "prevn-title": "$1 {{PLURAL:$1|نتيجة|نتيجة}} سابقة",
        "nextn-title": "$1 {{PLURAL:$1|نتيجة|نتيجة}} سابقة",
        "searchmenu-new": "'''أنشئ الصفحة \"[[:$1]]\" في هذا الويكي!'''",
+       "searchprofile-everything": "كلّ شي",
+       "searchprofile-articles-tooltip": "لوّج في $1",
+       "searchprofile-images-tooltip": "لوّج عالتصاور",
        "search-result-category-size": "{{PLURAL:$1|لا أعضاء|عضو واحد|عضوان|$1 أعضاء|$1 عضوًا|$1 عضو}} ({{PLURAL:$2|لا تصانيف فرعية|تصنيف فرعي واحد|تصنيفان فرعيان|$2 تصنيفات فرعية|$2 تصنيفًا فرعيًا|$2 تصنيف فرعي}} و{{PLURAL:$3|لا ملفات|ملف واحد|ملفان|$3 ملفات|$3 ملفًا|$3 ملف}})",
        "search-redirect": "(تحويلة $1)",
-       "search-suggest": "Ù\87Ù\84 كنت تقصد: $1",
+       "search-suggest": "Ù\8aاخÙ\8a كنت تقصد: $1",
        "searchrelated": "مرتبطة",
        "search-nonefound": "لا توجد نتائج تطابق الاستعلام.",
        "mypreferences": "تفضيلاتي",
        "prefs-help-email-others": "يمكنك أيضا اختيار للسماح للآخرين الاتصال بك عن طريق صفحة المستخدم أو نقاش المستخدم الخاص بك دون الحاجة إلى الكشف عن الهوية الخاصة بك.",
        "newuserlogpage": "سجل إنشاء المستخدمين",
        "nchanges": "{{PLURAL:$1|لا تغييرات|تغيير واحد|تغييران|$1 تغييرات|$1 تغييرا|$1 تغيير}}",
+       "enhancedrc-history": "تاريخ",
+       "recentchanges": "التبديلات الجدد",
        "recentchanges-legend": "خيارات أحدث التغييرات",
        "recentchanges-summary": "تابع أحدث التغييرات للويكي عبر هذه التلقيمة.",
        "recentchanges-feed-description": "تابع أحدث التغييرات للويكي عبر هذه التلقيمة.",
-       "recentchanges-label-newpage": "Ø£Ù\86شأ Ù\87ذا Ø§Ù\84تعدÙ\8aÙ\84 ØµÙ\81حة جديدة",
-       "recentchanges-label-minor": "Ù\87ذا ØªØ¹Ø¯Ù\8aÙ\84 Ø·Ù\81Ù\8aÙ\81",
-       "recentchanges-label-bot": "أجرÙ\89 Ù\87ذا Ø§Ù\84تعديل بوت",
+       "recentchanges-label-newpage": "عÙ\85Ù\84 Ù\87ذا Ø§Ù\84تبدÙ\8aÙ\84 Ù¾Ø§Ø¬ جديدة",
+       "recentchanges-label-minor": "Ù\87ذا ØªØ¨Ø¯Ù\8aÙ\84 ØµØºÙ\8aر",
+       "recentchanges-label-bot": "عÙ\85Ù\84 Ù\87ذا Ø§Ù\84تبديل بوت",
        "recentchanges-label-unpatrolled": "لم يراجع هذا التعديل إلى الآن",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (شوف زادة [[Special:NewPages|ليستة الپاجات الجدد]])",
        "rcnotefrom": "بالأسفل التغييرات منذ '''$2''' (إلى '''$1''' معروضة).",
-       "rclistfrom": "أظهر التغييرات بدءا من $3 $2",
+       "rclistfrom": "ورّي التبديلات بدءا من $3 $2",
        "rcshowhideminor": "$1 التعديلات الطفيفة",
+       "rcshowhideminor-hide": "خبّي",
        "rcshowhidebots": "$1 البوتات",
+       "rcshowhidebots-show": "ورّي",
        "rcshowhideliu": "$1 المستخدمين المسجلين",
+       "rcshowhideliu-hide": "خبّي",
        "rcshowhideanons": "$1 المستخدمين المجهولين",
+       "rcshowhideanons-hide": "خبّي",
        "rcshowhidepatr": "$1 التعديلات المراجعة",
        "rcshowhidemine": "$1 تعديلاتي",
+       "rcshowhidemine-hide": "خبّي",
        "rclinks": "أظهر آخر $1 تعديل في آخر $2 يوم<br />$3",
+       "hist": "تاريخ",
        "hide": "أخف",
-       "show": "اعرض",
+       "show": "ورّي",
+       "minoreditletter": "ص",
+       "newpageletter": "ج‌",
+       "boteditletter": "ب",
+       "rc-change-size-new": "$1 {{PLURAL:$1|أوكتاي|أوكتاي}} بعد التبديل",
        "rc-enhanced-expand": "عرض التفاصيل (يتطلب جافاسكريبت)",
        "rc-enhanced-hide": "أخفِ التفاصيل",
        "recentchangeslinked": "تغييرات ذات علاقة",
        "recentchangeslinked-title": "التغييرات المرتبطة ب \"$1\"",
-       "recentchangeslinked-summary": "Ù\87Ø°Ù\87 Ù\82ائÙ\85Ø© Ø¨Ø§Ù\84تغÙ\8aÙ\8aرات Ø§Ù\84تÙ\8a ØªÙ\85ت Ø­Ø¯Ù\8aثاÙ\8b Ù\84Ù\84صÙ\81حات Ø§Ù\84Ù\85Ù\88صÙ\88Ù\84Ø© Ù\85Ù\86 ØµÙ\81حة Ù\85عÙ\8aÙ\86Ø© (Ø£Ù\88 Ø¥Ù\84Ù\89 Ø§Ù\84أعضاء Ø¶Ù\85Ù\86 ØªØµÙ\86Ù\8aÙ\81 Ù\85عÙ\8aÙ\86).\nاÙ\84صÙ\81حات Ù\81Ù\8a [[Special:Watchlist|Ù\82ائÙ\85Ø© Ù\85راÙ\82بتÙ\83]] '''عرÙ\8aضة'''",
-       "recentchangeslinked-page": "اسÙ\85 Ø§Ù\84صÙ\81حة:",
+       "recentchangeslinked-summary": "Ù\87Ø°Ù\8a Ù\84Ù\8aستة Ø¨Ø§Ù\84تبدÙ\8aÙ\84ات Ø¥Ù\84Ù\91Ù\8a ØµØ§Ø±Ù\88ا Ù\85ا ØµØ§Ø±Ù\84Ù\87Ù\85Ø´ Ø¨Ø±Ø´Ø§ Ù\84Ù\84پاجات Ø¥Ù\84Ù\91Ù\8a Ù\85Ù\88جÙ\88د Ù\84Ù\8aاÙ\86 Ù\8aدÙ\91Ù\8a Ù\84Ù\8aÙ\87Ù\85 Ù\81Ù\8a Ù¾Ø§Ø¬ Ø¨Ø°Ø§ØªÙ\87ا (Ù\88Ù\84Ù\91ا Ù\81Ù\8a Ù¾Ø§Ø¬ Ù\85تاع ØªØµÙ\86Ù\8aÙ\81 Ù\85عÙ\8aÙ\86).\nاÙ\84پاجات Ù\81Ù\8a [[Special:Watchlist|Ù\84Ù\8aستة Ø§Ù\84پاجات Ø¥Ù\84Ù\91Ù\8a ØªÙ\91بعÙ\87ا]] '''Ù\85Ù\83تÙ\88بÙ\8aÙ\86 Ø¨Ø§Ù\84غÙ\84Ù\8aظ'''",
+       "recentchangeslinked-page": "إسÙ\85 Ø§Ù\84پاج:",
        "recentchangeslinked-to": "أظهر التغييرات للصفحات الموصولة للصفحة المعطاة عوضاً عن ذلك",
+       "upload": "صبّ فشياي",
        "uploadlogpage": "سجل الرفع",
        "filedesc": "ملخص:",
        "license": "ترخيص:",
+       "file-anchor-link": "فيشياي",
+       "filehist": "تاريخ الپاج",
        "filehist-help": "اضغط على وقت/زمن لرؤية الملف كما بدا في هذا الزمن.",
        "filehist-revert": "استرجع",
        "filehist-current": "حالي",
        "filehist-thumbtext": "تصغير للنسخة بتاريخ $1",
        "filehist-user": "مستخدم",
        "filehist-dimensions": "الأبعاد",
-       "imagelinks": "استخدام الملف",
+       "filehist-comment": "تعليق",
+       "imagelinks": "استعمال الدوسي",
        "linkstoimage": "{{PLURAL:$1||الصفحة التالية تصل|الصفحتان التاليتان تصلان|ال$1 صفحات التالية تصل|ال$1 صفحة التالية تصل}} إلى هذا الملف:",
        "nolinkstoimage": "لا توجد صفحات تصل لهذا الملف.",
        "sharedupload-desc-here": "هذا الملف من $1 ويمكن استخدامه بواسطة المشاريع الأخرى.\nالوصف على [$2 صفحة وصف الملف] هناك معروض بالأسفل.",
+       "upload-disallowed-here": "ما تنجّمش تبدّل هذي التصويرة.",
        "statistics": "إحصاءات",
-       "nmembers": "{{PLURAL:$1|لا أعضاء|عضو واحد|عضوان|$1 أعضاء|$1 عضوا|$1 عضو}}",
+       "nmembers": "{{PLURAL:$1|حتى عضو|عضو واحد||زوز أعضاء|$1 عضو}}",
        "prefixindex": "كل الصفحات بالبادئة",
        "usercreated": "{{GENDER:$3|أنشأه|أنشأته}} في $1 الساعة $2",
+       "newpages": "پاجات جدد",
        "move": "انقل",
        "pager-newer-n": "{{PLURAL:$1|أقدم 1|أقدم $1}}",
        "pager-older-n": "{{PLURAL:$1|أقدم 1|أقدم $1}}",
        "booksources": "مصادر كتاب",
-       "booksources-search-legend": "اÙ\84بحث Ø¹Ù\86 مصادر الكتب",
+       "booksources-search-legend": "اÙ\84تÙ\84Ù\88Ù\8aج Ø¹Ù\84Ù\89 مصادر الكتب",
        "log": "سجلات",
        "allpagessubmit": "اذهب",
        "categories": "تصنيفات",
        "listgrouprights-members": "(قائمة الأعضاء)",
        "emailuser": "إرسال رسالة لهذا المستخدم",
        "watchlist": "قائمة مراقبتي",
-       "mywatchlist": "Ù\82ائÙ\85Ø© Ù\85راÙ\82بتÙ\8a",
+       "mywatchlist": "Ù\84Ù\8aستة Ø§Ù\84پاجات Ø¥Ù\84Ù\91Ù\8a Ù\86تبÙ\91عÙ\87ا",
        "watchlistfor2": "ل$1 $2",
        "watch": "راقب",
        "unwatch": "أوقف المراقبة",
        "actioncomplete": "انتهاء العملية",
        "actionfailed": "الفعل فشل",
        "dellogpage": "سجل الحذف",
+       "rollbacklink": "رجّع",
        "protectlogpage": "سجل الحماية",
        "protectedarticle": "حمى \"[[$1]]\"",
        "undeletelink": "اعرض/استعد",
        "undeleteviewlink": "اعرض",
        "namespace": "النطاق",
        "invert": "اعكس الاختيار",
-       "contributions": "مساهماتي",
+       "blanknamespace": "(رئيسي)",
+       "contributions": "مساهمات {{GENDER:$1|المستعمل|المستعملة}}",
        "contributions-title": "مساهمات المستخدم $1",
        "mycontris": "مساهماتي",
+       "anoncontribs": "مساهمات",
        "contribsub2": "ل$1 ($2)",
-       "month": "Ù\85Ù\86 Ø³Ù\86Ø© (Ù\88أقدم):",
-       "year": "Ù\85Ù\86 Ø³Ù\86Ø© (Ù\88أقدم):",
+       "month": "Ù\85Ù\86 Ø´Ù\87ر (Ù\88 أقدم):",
+       "year": "Ù\85Ù\86 Ø¹Ø§Ù\85 (Ù\88 أقدم):",
        "sp-contributions-newbies": "اعرض مساهمات الحسابات الجديدة فقط",
        "sp-contributions-blocklog": "سجل المنع",
        "sp-contributions-uploads": "مرفوعات",
        "sp-contributions-username": "عنوان أيبي أو اسم مستخدم:",
        "sp-contributions-toponly": "أظهر أعلى المراجعات فقط",
        "whatlinkshere-title": "الصفحات التي تصل إلى \"$1\"",
+       "whatlinkshere-page": "الپاج:",
        "linkshere": "الصفحات التالية تصل إلى '''[[:$1]]''':",
        "nolinkshere": "لا توجد صفحات تصل إلى '''[[:$1]]'''.",
        "isredirect": "صفحة تحويل",
        "isimage": "وصلة ملف",
        "whatlinkshere-next": "{{PLURAL:$1|التالية|ال$1 التالية}}",
        "whatlinkshere-links": "← وصلات",
-       "whatlinkshere-hideredirs": "$1 Ø§Ù\84تحÙ\88Ù\8aÙ\84ات",
+       "whatlinkshere-hideredirs": "$1 تحويلات",
        "whatlinkshere-hidetrans": "$1 التضمينات",
-       "whatlinkshere-hidelinks": "$1 الوصلات",
+       "whatlinkshere-hidelinks": "$1 ليانات",
        "whatlinkshere-hideimages": "$1 وصلة صورة",
        "whatlinkshere-filters": "مرشحات",
        "ipboptions": "ساعتين:2 hours,يوم واحد:1 day,3 أيام:3 days,أسبوع واحد:1 week,أسبوعين:2 weeks,شهر واحد:1 month,3 أشهر:3 months,6 أشهر:6 months,سنة واحدة:1 year,دائم:infinite",
        "ipblocklist": "المستخدمون الممنوعون",
+       "blocklink": "بلوكي",
        "unblocklink": "ارفع المنع",
        "change-blocklink": "تغيير المنع",
        "blocklogpage": "سجل المنع",
        "blocklogentry": "منع \"[[$1]]\" لفترة زمنية مدتها $2 $3",
        "block-log-flags-nocreate": "إنشاء الحسابات ممنوع",
-       "movelogpage": "سجل النقل",
+       "movelogpage": "سجل التحويل",
        "revertmove": "استرجع",
        "export": "تصدير صفحات",
        "allmessagesname": "الاسم",
        "tooltip-pt-preferences": "تفضيلاتي",
        "tooltip-pt-watchlist": "قائمة الصفحات التي تراقب التغييرات التي تحدث بها",
        "tooltip-pt-mycontris": "قائمة مساهماتك",
+       "tooltip-pt-login": "ماذابيك لوكان تدخل للويكي، أما موش لازمك تعمل هكّا",
        "tooltip-pt-logout": "خروج",
+       "tooltip-pt-createaccount": "ماذابيك لوكان تعمل حساب و تدخل للويكي، أما موش لازمك تعمل هكّا",
+       "tooltip-ca-edit": "بدّل الپاج",
        "tooltip-ca-addsection": "ابدأ قسما جديدا",
+       "tooltip-ca-viewsource": "هذه الپاج محمية.\nتنجّم تشوف مصدرها.",
        "tooltip-ca-protect": "احم هذه الصفحة",
        "tooltip-ca-delete": "احذف هذه الصفحة",
-       "tooltip-ca-move": "عÙ\84Ù\85 Ù\87Ø°Ù\87 Ø§Ù\84صÙ\81حة",
-       "tooltip-ca-watch": "أضÙ\81 Ù\87Ø°Ù\87 Ø§Ù\84صÙ\81حة Ø¥Ù\84Ù\89 Ù\82ائÙ\85Ø© Ù\85راÙ\82بتÙ\83",
+       "tooltip-ca-move": "Ø­Ù\88Ù\91Ù\84 Ù\87Ø°Ù\8a Ø§Ù\84پاج",
+       "tooltip-ca-watch": "زÙ\8aد Ù\87ا Ø§Ù\84پاج Ù\84Ù\84Ù\8aستة Ø§Ù\84پاجات Ø¥Ù\84Ù\91Ù\8a ØªÙ\91بعÙ\87ا",
        "tooltip-ca-unwatch": "أزل هذه الصفحة من قائمة مراقبتك",
+       "tooltip-search": "لوّج في {{SITENAME}}",
+       "tooltip-search-go": "إمشي للپاج إلّي عندها هذا الإسم بالضبط إذا هي موجودة",
+       "tooltip-p-logo": "شوف الپاج الأولانيّة",
+       "tooltip-n-mainpage": "شوف الپاج الأولانيّة",
+       "tooltip-n-mainpage-description": "شوف الپاج الأولانيّة",
+       "tooltip-n-randompage": "خرّج پاج بالزهر",
        "tooltip-feed-atom": "تلقيم أتوم لهذه الصفحة",
        "tooltip-t-contributions": "رؤية قائمة مساهمات هذا المستخدم",
        "tooltip-t-emailuser": "أرسل رسالة لهذا المستخدم",
+       "tooltip-t-upload": "صبّ فيشيايات",
        "tooltip-ca-nstab-user": "اعرض صفحة المستخدم",
-       "tooltip-ca-nstab-special": "Ù\87Ø°Ù\87 ØµÙ\81حة Ø®Ø§ØµØ©Ø\8c Ù\84ا ØªØ³ØªØ·Ù\8aع Ø£Ù\86 ØªØ¹Ø¯Ù\84 Ø§Ù\84صÙ\81حة Ù\86Ù\81سÙ\87ا",
+       "tooltip-ca-nstab-special": "Ù\87Ø°Ù\8a Ù¾Ø§Ø¬ Ø³Ù¾Ø§Ø³Ù\8aاÙ\84Ø\8c Ù\88 Ù\85ا ØªÙ\86جÙ\91Ù\85Ø´ ØªØ¨Ø¯Ù\91Ù\84 Ù\81Ù\8aÙ\87ا Ø´Ù\8a",
        "tooltip-ca-nstab-project": "رؤية صفحة المحتوى",
        "tooltip-ca-nstab-image": "رؤية صفحة الملف",
        "tooltip-ca-nstab-template": "رؤية القالب",
        "tooltip-watch": "أضف هذه الصفحة إلى قائمة مراقبتك",
        "tooltip-undo": "\"رجوع\" تسترجع هذا التعديل وتفتح نافذة التعديل في نمط العرض المسبق. تسمح بإضافة سبب في الملخص.\n\"Annuler\" trajjeε eltabdila lekhra w tħel fenêtre mtaε  el tabdil mtaε elvue el msabqa. Tnajjem tqoul εlech f'ettalkhis.",
        "tooltip-summary": "أدخل ملخصا قصيرا",
-       "previousdiff": "â\86\92 Ø§Ù\84تعدÙ\8aÙ\84 Ø§Ù\84سابÙ\82",
-       "nextdiff": "اÙ\84تعدÙ\8aÙ\84 Ø§Ù\84Ù\84احÙ\82 ←",
+       "previousdiff": "â\86\92 Ø§Ù\84تبدÙ\8aÙ\84 Ø§Ù\84Ù\81اÙ\8aت",
+       "nextdiff": "اÙ\84تبدÙ\8aÙ\84 Ø§Ù\84جاÙ\8a ←",
        "file-info-size": "$1 × $2 بكسل حجم الملف: $3، نوع MIME: $4",
        "file-nohires": "لا توجد دقة أعلى متوفرة.",
        "svg-long-desc": "ملف SVG، أبعاده $1 × $2 بكسل، حجم الملف: $3",
+       "show-big-image": "الفيشياي الأصلي",
        "metadata": "بيانات ميتا",
        "metadata-help": "هذا الملف يحتوي على معلومات إضافية، غالبا ما تكون أضيفت من قبل الكاميرا الرقمية أو الماسح الضوئي المستخدم في إنشاء الملف.\nإذا كان الملف قد عدل عن حالته الأصلية، فبعض التفاصيل قد لا تعبر عن الملف المعدل.",
        "metadata-fields": "حقول معطيات الميتا الموجودة في هذه الرسالة سوف تعرض في صفحة الصورة عندما يكون جدول معطيات الميتا مضغوطا.\nالحقول الأخرى ستكون مخفية افتراضيا.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "exif-datetime": "نهار و وقت تبديل الفيشياي",
        "namespacesall": "الكل",
        "monthsall": "الكل",
        "watchlisttools-view": "اعرض التغييرات المرتبطة",
        "watchlisttools-edit": "اعرض قائمة المراقبة وعدلها",
        "watchlisttools-raw": "عدل قائمة المراقبة الخام",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|حديث]])",
        "duplicate-defaultsort": "'''تحذير:''' مفتاح الترتيب الافتراضي \"$2\" يتجاوز مفتاح الترتيب الافتراضي السابق \"$1\".",
        "external_image_whitelist": " #<pre>اترك هذا السطر تماما كما هو\n#ضع منثورات التعبيرات المنتظمة (فقط الجزء الذي يذهب بين //) بالأسفل\n#هذه ستتم مطابقتها مع مسارات الصور الخرجية (الموصولة بشكل مباشر)\n#هذه التي تطابق سيتم عرضها كصور، غير ذلك فقط وصلة إلى الصورة سيتم عرضها\n#السطور التي تبدأ ب# تتم معاملتها كتعليقات\n#هذا لا يتأثر بحالة الحروف\n\n#ضع كل منثورات التعبيرات المنتظمة فوق هذا السطر. اترك هذا السطر تماما كما هو</pre>",
-       "tag-filter": "مرشح [[Special:Tags|الوسوم]]:"
+       "tag-filter": "مرشح [[Special:Tags|الوسوم]]:",
+       "logentry-newusers-create": "إتحلّ حساب {{GENDER:$2|المستعمل|المستعملة}} $1",
+       "searchsuggest-search": "لوّج في {{SITENAME}}"
 }
index e7b42da..26b5857 100644 (file)
        "rcfilters-invalid-filter": "مرشح غير صحيح",
        "rcfilters-empty-filter": "لا مرشحات فعالة. كل المساهمات معروضة.",
        "rcfilters-filterlist-title": "مرشحات",
+       "rcfilters-filterlist-feedbacklink": "تقديم مراجعات لمرشحات (بيتا) الجديدة",
        "rcfilters-highlightbutton-title": "التعليم على النتائج",
        "rcfilters-highlightmenu-title": "اختر لونًا",
        "rcfilters-filterlist-noresults": "لم يتم العثور على مرشحات",
index 4f8b695..f3b72c6 100644 (file)
        "selfredirect": "<strong>Atención:</strong> Tas redirixendo esta páxina a ella mesma.\nSeique conseñaras un oxetivu enquivocáu pa la redireición, o que teas editando una páxina enquivocada. Si vuelves a facer clic en «{{int:savearticle}}», crearáse la redireición de toles maneres.",
        "missingcommenttext": "Por favor, escribi un comentariu abaxo.",
        "missingcommentheader": "<strong>Recordatoriu:</strong> Nun conseñasti un asuntu pa esti comentariu.\nSi calques nuevamente «{{int:savearticle}}», la to edición guardaráse ensin nengunu.",
-       "summary-preview": "Vista previa del resume:",
+       "summary-preview": "Vista previa del resume d'edición:",
        "subject-preview": "Vista previa del asuntu:",
        "previewerrortext": "Hebo un error al intentar entever los cambios.",
        "blockedtitle": "L'usuariu ta bloquiáu",
        "rcfilters-invalid-filter": "Filtru inválidu",
        "rcfilters-empty-filter": "Nun hai filtros activos. Amuésense toles contribuciones.",
        "rcfilters-filterlist-title": "Filtros",
+       "rcfilters-highlightbutton-title": "Resaltar resultaos",
+       "rcfilters-highlightmenu-title": "Seleiciona un color",
        "rcfilters-filterlist-noresults": "Nun s'alcontraron filtros",
        "rcfilters-filtergroup-registration": "Rexistru del usuariu",
        "rcfilters-filter-registered-label": "Rexistraos",
        "editcomment": "El resume de la edición yera: <em>$1</em>.",
        "revertpage": "Revertíes les ediciones de [[Special:Contributions/$2|$2]] ([[User talk:$2|alderique]]) hasta la cabera versión de [[User:$1|$1]]",
        "revertpage-nouser": "Revertíes les ediciones de (usuariu desaniciáu) a la cabera revisión de {{GENDER:$1|[[User:$1|$1]]}}",
-       "rollback-success": "Revertíes les ediciones de $1; camudáu a la última versión de $2.",
+       "rollback-success": "Revertíes les ediciones de {{GENDER:$3|$1}}; devueltu a la última revisión de {{GENDER:$4|$2}}.",
        "rollback-success-notify": "Revertíes les ediciones de $1 a la última revisión de $2. [$3 Ver cambeos]",
        "sessionfailure-title": "Fallu de sesión",
        "sessionfailure": "Paez qu'hai un problema cola to sesión; por precaución\ncancelóse l'aición que pidisti. Da-y al botón \"Atrás\" del\nnavegador pa cargar otra vuelta la páxina y vuelve a intentalo.",
index 22c7d42..a1cf8ed 100644 (file)
        "changeemail-no-info": "Для непасрэднага доступу да гэтай старонкі Вам неабходна ўвайсьці ў сыстэму.",
        "changeemail-oldemail": "Цяперашні адрас электроннай пошты:",
        "changeemail-newemail": "Новы адрас электроннай пошты:",
-       "changeemail-newemail-help": "Ð\9fоле Ñ\82Ñ\80Ñ\8dба Ð¿Ð°ÐºÑ\96нÑ\83Ñ\86Ñ\8c Ð¿Ñ\83Ñ\81Ñ\82Ñ\8bм, ÐºÐ°Ð»Ñ\96 Ð²Ñ\8b Ñ\85оÑ\87аÑ\86е Ð²Ñ\8bдалÑ\96Ñ\86Ñ\8c Ñ\81вой Ð°Ð´Ñ\80аÑ\81 Ñ\8dлекÑ\82Ñ\80оннай Ð¿Ð¾Ñ\88Ñ\82Ñ\8b. Пасьля выдаленьня вы ня зможаце ануляваць забыты пароль і ня будзеце атрымліваць лісты электроннай пошты з гэтай вікі.",
+       "changeemail-newemail-help": "Ð\9aалÑ\96 Ð²Ñ\8b Ñ\85оÑ\87аÑ\86е Ð²Ñ\8bдалÑ\96Ñ\86Ñ\8c Ñ\81вой Ð°Ð´Ñ\80аÑ\81 Ñ\8dлекÑ\82Ñ\80оннай Ð¿Ð¾Ñ\88Ñ\82Ñ\8b, Ð¿Ð°ÐºÑ\96нÑ\8cÑ\86е Ð³Ñ\8dÑ\82ае Ð¿Ð¾Ð»Ðµ Ð¿Ñ\83Ñ\81Ñ\82Ñ\8bм. Пасьля выдаленьня вы ня зможаце ануляваць забыты пароль і ня будзеце атрымліваць лісты электроннай пошты з гэтай вікі.",
        "changeemail-none": "(няма)",
        "changeemail-password": "Ваш пароль у {{GRAMMAR:месны|{{SITENAME}}}}:",
        "changeemail-submit": "Зьмяніць адрас электроннай пошты",
        "rev-suppressed-no-diff": "Вы ня можаце праглядзець гэтую розьніцу, таму што адна з вэрсіяў была <strong>выдаленая</strong>.",
        "rev-deleted-unhide-diff": "Адна з вэрсіяў гэтай старонкі была <strong>выдаленая</strong>.\nПадрабязнасьці могуць быць знойдзеныя ў [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} журнале выдаленьняў].\nВы можаце праглядзець [$1 розьніцу паміж вэрсіямі], калі жадаеце.",
        "rev-suppressed-unhide-diff": "Адна з вэрсіяў гэтага параўнаньня была <strong>схаваная</strong>.\nПадрабязнасьці могуць быць знойдзеныя ў [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} журнале хаваньняў].\nВы можаце [$1 паглядзець гэту розьніцу], калі жадаеце.",
-       "rev-deleted-diff-view": "Адна з вэрсіяў гэтага параўнаньня была '''выдаленая'''.\nВы можаце праглядзець гэтую розьніцу паміж вэрсіямі. Падрабязнасьці могуць быць знойдзеныя ў [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} журнале выдаленьняў].",
-       "rev-suppressed-diff-view": "Адна з вэрсіяў гэтага параўнаньня была '''схаваная'''.\nВы можаце праглядзець гэтую розьніцу паміж вэрсіямі; падрабязнасьці могуць быць знойдзеныя ў [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} журнале хаваньняў].",
+       "rev-deleted-diff-view": "Адна з вэрсіяў гэтага параўнаньня была <strong>выдаленая</strong>.\nВы можаце праглядзець гэтую розьніцу паміж вэрсіямі. Падрабязнасьці могуць быць знойдзеныя ў [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} журнале выдаленьняў].",
+       "rev-suppressed-diff-view": "Адна з вэрсіяў гэтага параўнаньня была <strong>схаваная</strong>.\nВы можаце праглядзець гэтую розьніцу паміж вэрсіямі; падрабязнасьці могуць быць знойдзеныя ў [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} журнале хаваньняў].",
        "rev-delundel": "паказаць/схаваць",
        "rev-showdeleted": "паказаць",
        "revisiondelete": "Выдаліць/аднавіць вэрсіі",
        "rcfilters-invalid-filter": "Няслушны фільтар",
        "rcfilters-empty-filter": "Няма актыўных фільтраў. Паказаны ўвесь унёсак.",
        "rcfilters-filterlist-title": "Фільтры",
+       "rcfilters-filterlist-feedbacklink": "Пакінуць водгук пра новыя (бэта) фільтры",
        "rcfilters-highlightbutton-title": "Вылучыць вынікі",
        "rcfilters-highlightmenu-title": "Абярыце колер",
        "rcfilters-filterlist-noresults": "Фільтры ня знойдзеныя",
        "statistics-users-active-desc": "Удзельнікі, якія выканалі нейкае дзеяньне цягам {{PLURAL:$1|апошняга $1 дня|апошніх $1 дзён|апошніх $1 дзён}}",
        "pageswithprop": "Старонкі з уласьцівасьцямі старонак",
        "pageswithprop-legend": "Старонкі з уласьцівасьцямі старонак",
-       "pageswithprop-text": "Ð\9dа Ð³Ñ\8dÑ\82ай Ñ\81Ñ\82аÑ\80онÑ\86Ñ\8b Ð°Ð´Ð»Ñ\8eÑ\81Ñ\82Ñ\80оÑ\9eваÑ\8eÑ\86Ñ\86а Ñ\81Ñ\82аÑ\80онкÑ\96, Ñ\8fкÑ\96Ñ\8f Ñ\9eжÑ\8bваÑ\8eÑ\86Ñ\8c Ð¿Ñ\8dÑ\9eнÑ\8bÑ\8f Ñ\9eлаÑ\81Ñ\8cÑ\86Ñ\96ваÑ\81Ñ\8cÑ\86Ñ\96 Ñ\81Ñ\82аÑ\80онак",
+       "pageswithprop-text": "Ð\9dа Ð³Ñ\8dÑ\82ай Ñ\81Ñ\82аÑ\80онÑ\86Ñ\8b Ð°Ð´Ð»Ñ\8eÑ\81Ñ\82Ñ\80оÑ\9eваÑ\8eÑ\86Ñ\86а Ñ\81Ñ\82аÑ\80онкÑ\96, Ñ\8fкÑ\96Ñ\8f Ñ\9eжÑ\8bваÑ\8eÑ\86Ñ\8c Ð¿Ñ\8dÑ\9eнÑ\83Ñ\8e Ñ\9eлаÑ\81Ñ\8cÑ\86Ñ\96ваÑ\81Ñ\8cÑ\86Ñ\8c Ñ\81Ñ\82аÑ\80онкÑ\96.",
        "pageswithprop-prop": "Імя ўласьцівасьці:",
        "pageswithprop-submit": "Паказаць",
        "pageswithprop-prophidden-long": "доўгае тэкставае значэньне ўласьцівасьці схавана ($1)",
        "authmanager-authn-autocreate-failed": "Аўтаматычнае стварэньне лякальнага рахунку не атрымалася: $1",
        "authmanager-change-not-supported": "Пададзеныя ўліковыя зьвесткі ня могуць быць зьмененыя, бо яны ня будуць выкарыстаныя.",
        "authmanager-create-disabled": "Стварэньне рахункаў адключанае.",
+       "authmanager-create-from-login": "Каб стварыць рахунак, калі ласка, запоўніце палі.",
+       "authmanager-create-not-in-progress": "Стварэньне рахунку не выконваецца або страчаныя зьвесткі пра сэсію. Калі ласка, пачніце наноў з самага пачатку.",
+       "authmanager-create-no-primary": "Пададзеныя ўліковыя зьвесткі ня могуць быць выкарыстаныя для стварэньня рахунку.",
+       "authmanager-link-no-primary": "Пададзеныя ўліковыя зьвесткі ня могуць быць выкарыстаныя для злучэньня рахункаў.",
+       "authmanager-link-not-in-progress": "Злучэньне рахункаў не выконваецца або страчаныя зьвесткі сэсіі. Калі ласка, пачніце ізноў спачатку.",
+       "authmanager-authplugin-setpass-failed-title": "Памылка зьмены паролю",
+       "authmanager-authplugin-setpass-failed-message": "Дадатак аўтэнтыфікацыі адмовіў зьмену паролю.",
        "authmanager-realname-label": "Сапраўднае імя",
        "authmanager-provider-temporarypassword": "Часовы пароль",
        "changecredentials": "Зьмена ўліковых зьвестак",
index 5abee6a..0f9d186 100644 (file)
        "jumpto": "Перайсці да:",
        "jumptonavigation": "рух",
        "jumptosearch": "знайсці",
-       "view-pool-error": "Ð\9dа Ð¶Ð°Ð»Ñ\8c, Ñ\83 Ð³Ñ\8dÑ\82Ñ\8b Ð¼Ð¾Ð¼Ð°Ð½Ñ\82 Ñ\81еÑ\80веÑ\80Ñ\8b Ð¿ÐµÑ\80агÑ\80Ñ\83жанÑ\8b.\nÐ\97анадÑ\82а Ð¼Ð½Ð¾Ð³Ñ\96Ñ\8f Ñ\87Ñ\8bÑ\82аÑ\87Ñ\8b Ñ\81пÑ\80абÑ\83Ñ\8eÑ\86Ñ\8c адкрыць гэтую старонку.\nКалі ласка, трохі пачакайце, перш чым адкрываць гэтую старонку ізноў.\n\n$1",
+       "view-pool-error": "Ð\9dа Ð¶Ð°Ð»Ñ\8c, Ñ\83 Ð³Ñ\8dÑ\82Ñ\8b Ð¼Ð¾Ð¼Ð°Ð½Ñ\82 Ñ\81еÑ\80веÑ\80Ñ\8b Ð¿ÐµÑ\80агÑ\80Ñ\83жанÑ\8b.\nÐ\92елÑ\8cмÑ\96 Ñ\88маÑ\82 Ñ\87Ñ\8bÑ\82аÑ\87оÑ\9e Ñ\81пÑ\80абÑ\83е адкрыць гэтую старонку.\nКалі ласка, трохі пачакайце, перш чым адкрываць гэтую старонку ізноў.\n\n$1",
        "generic-pool-error": "На жаль, у гэты момант серверы перагружаны.\nЗанадта многія карыстальнікі спрабуюць адкрыць гэты рэсурс.\nКалі ласка, трохі пачакайце, перш чым спрабаваць атрымаць доступ да гэтага рэсурсу ізноў.",
        "pool-timeout": "Выйшаў час чакання блакіроўкі",
        "pool-queuefull": "Чарга запытаў перапоўнена",
        "action-reupload-shared": "запісваць паўзверх гэтага файла ў супольным сховішчы",
        "action-upload_by_url": "загрузіць гэты файл з адраса URL",
        "action-writeapi": "ужываць API запісвання",
-       "action-delete": "сціраць гэтую старонку",
+       "action-delete": "выдаліць гэтую старонку",
        "action-deleterevision": "сціраць версіі старонак",
        "action-deletelogentry": "выдаленне запісаў у журнале",
        "action-deletedhistory": "бачыць сцёртую гісторыю гэтай старонкі",
        "recentchanges-label-minor": "Дробная па значэнні праўка",
        "recentchanges-label-bot": "Праўка зроблена праграмай-робатам",
        "recentchanges-label-unpatrolled": "Праўка яшчэ не атрымала адзнакі ўхваленасці (за ёй не сочыць \"патруль\")",
-       "recentchanges-label-plusminus": "Ð\90б'Ñ\91м Ñ\81Ñ\82аÑ\80онкÑ\96 Ð·Ð¼Ñ\8fнÑ\96Ñ\9eÑ\81Ñ\8f Ð½Ð° Ð³Ñ\8dÑ\82Ñ\83Ñ\8e Ð»Ñ\96Ñ\87бÑ\83 байтаў",
+       "recentchanges-label-plusminus": "Ð\90б'Ñ\91м Ñ\81Ñ\82аÑ\80онкÑ\96 Ð·Ð¼Ñ\8fнÑ\96Ñ\9eÑ\81Ñ\8f Ð½Ð° Ð³Ñ\8dÑ\82Ñ\8b Ð»Ñ\96к байтаў",
        "recentchanges-legend-heading": "<strong>Легенда:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (гл. асобна [[Special:NewPages|новыя старонкі]])",
        "recentchanges-submit": "Паказаць",
index f63d25e..4e4401e 100644 (file)
        "selfredirect": "<strong>चेतावनी:</strong> आप ई पन्ना के खुदे एही पर अनुप्रेषण क रहल बानी।\nया त आप अनुप्रेषण खातिर गलत लक्ष्य देत बानी, या आप गलत पन्ना के संपादन करत बानी।\nएक बेर अउरी \"{{int:savearticle}}\" क्लिक करब त, ओइसहूँ ई अनुप्रेषण बना दिहल जाई।",
        "missingcommenttext": "नीचे एगो टिप्पणी भरीं।",
        "missingcommentheader": "'''याद दियावल जात बा:''' रउआँ एह कमेंट खातिर कौनों बिसय नइखीं दिहले। अगर आप \"{{int:savearticle}}\" पर क्लिक करब तब राउर संपादन एकरे बिना सहेजा जाई।",
-       "summary-preview": "साराà¤\82श झलक:",
+       "summary-preview": "सà¤\82पादन à¤¸à¤¾à¤°à¤¾à¤\82श à¤\95 झलक:",
        "subject-preview": "बिसय के झलक:",
        "previewerrortext": "राउर बदलाव के झलक देखावे के कोसिस के समय कुछ गड़बड़ी हो गइल।",
        "blockedtitle": "प्रयोगकर्ता रोक दिहल गइल बा",
        "mergehistory-empty": "कौनों अवतरण विलय नइखे कइल जा सकत।",
        "mergehistory-done": " $1 के $3 {{PLURAL:$3|अवतरण|अवतरण सभ}} सफलता से [[:$2]] में विलय भइल।",
        "mergehistory-fail": "इतिहास विलय करे में अक्षम, पन्ना आ एकर टाइम पैरामीटर चेक करीं।",
+       "mergehistory-autocomment": "[[:$1]] के [[:$2]] में विलय कइल गइल",
+       "mergehistory-comment": "[[:$1]] के [[:$2]] में विलय कइल गइल: $3",
+       "mergehistory-same-destination": "स्रोत आ लक्ष्य पन्ना एकही ना होखे सकत बा",
        "mergehistory-reason": "कारण:",
+       "mergelog": "विलय लॉग",
        "revertmerge": "अलग करीं",
        "mergelogpagetext": "एक पन्ना इतिहास के दुसर पन्ना इतिहास में तुरंत विलय भइले के एगो सूची नीचे दिहल बा।",
        "history-title": "''$1'' के संशोधन इतिहास",
index ca7fb56..85b582e 100644 (file)
        "rcfilters-filter-bots-description": "স্বয়ংক্রিয় সরঞ্জাম দিয়ে করা সম্পাদনা।",
        "rcfilters-filter-humans-label": "মানুষ (বট নয়)",
        "rcfilters-filter-humans-description": "মানব সম্পাদক দ্বারা করা সম্পাদনা।",
-       "rcfilters-filtergroup-significance": "তাতà§\8dপর্য",
+       "rcfilters-filtergroup-significance": "তাà§\8eপর্য",
        "rcfilters-filter-minor-label": "অনুল্লেখ্য সম্পাদনা",
        "rcfilters-filter-major-label": "অ-অনুল্লেখ্য সম্পাদনা",
        "rcfilters-filtergroup-changetype": "পরিবর্তনের ধরন",
        "editcomment": "সম্পাদনা সারাংশ ছিল: \"''$1''\"।",
        "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|আলাপ]]) এর সম্পাদিত সংস্করণ হতে [[User:$1|$1]] এর সম্পাদিত সর্বশেষ সংস্করণে ফেরত যাওয়া হয়েছে।",
        "revertpage-nouser": "একজন গোপন ব্যবহারকারী কর্তৃক সম্পাদিত সম্পাদনাটি বাতিলপূর্বক {{GENDER:$1|[[User:$1|$1]]}}-এর সর্বশেষ সম্পাদনায় ফেরত যাওয়া হয়েছে।",
-       "rollback-success": "$1-এর সম্পাদনাগুলি পূর্বাবস্থায় ফিরিয়ে নেওয়া হয়েছে; $2-এর করা শেষ সংস্করণে পাতাটি ফেরত নেওয়া হয়েছে।",
+       "rollback-success": "{{GENDER:$3|$1}}-এর সম্পাদনাগুলি পূর্বাবস্থায় ফিরিয়ে নেওয়া হয়েছে; {{GENDER:$4|$2}}-এর করা শেষ সংস্করণে পাতাটি ফেরত নেওয়া হয়েছে।",
        "rollback-success-notify": "$1-এর সম্পাদনাগুলি বাতিল করা হয়েছে; \n$2-এর করা শেষ সংস্করণে ফেরত নেওয়া হয়েছে। [$3 পরিবর্তন দেখুন]",
        "sessionfailure-title": "সেশন পরিত্যক্ত",
        "sessionfailure": "আপনার প্রবেশ সেশনে একটি সমস্যা হয়েছে বলে মনে হচ্ছে;\nসেশন হাইজ্যাক প্রতিরোধের উপায় হিসেবে এই কাজটি বাতিল করা হয়েছে।\nঅনুগ্রহ ব্রাউজারের \"পিছনে\" বোতাম চাপুন এবং যে পাতা থেকে এসেছিলেন, তা পুনঃলোড করুন এবং আবার চেষ্টা করুন।",
index c1a13dd..7b6c458 100644 (file)
        "gotaccountlink": "اویدن به",
        "userlogin-resetpassword-link": "رازینإ گوڤأرتن تۈ ز ڤيرتۈن رأهڌإ",
        "userlogin-helplink2": "هومياري کردن سي ڤامإن أڤوڌن",
+       "createacct-emailrequired": "تيرنشۈن أنجومانامأ",
        "createacct-emailoptional": "تيرنشۈن أنجومانامأ",
        "createacct-email-ph": "تيرنشۈن أنجومانامأ تۈنأ بزنين",
+       "createacct-another-email-ph": "تيرنشۈن أنجومانامأ تۈنأ بزنين",
        "createaccountreason": "دلیل:",
        "createacct-reason": "دلیل",
        "createacct-submit": "هساڤ خوتۈنإ راسد کونين",
        "noemail": "وجود نداره نشانی امیل ضبط وابده زه کاریر \"$1\".",
        "passwordsent": "یه رمز تازه ارسال وابید به نشانی امیل ثبت وابده سی \"$1\".\nلطفا بعد از دریافت آن داخل سیستم بوین.",
        "eauthentsent": "یه ایمیل سی تایید آدرس ایمیل به آدرس مورنظر ارسال وابید. قبل زه یو که ایمیل دیگری قابل ارسال به این آدرس بوه، وا دستورهایی که در آن ایمیل اویده را جهت تأیید ای مساله که ای آدرس مال ایسانه اجرا کنین.",
+       "emaildisabled": "اي ديارگأ نترإ إنجومانامإ سيتۈن بفرشنإ",
        "accountcreated": "هساڤ راسد ڤابي",
+       "createaccount-title": "هساڤ سي {{SITENAME}} راسد ڤابي",
        "loginlanguagelabel": "زۈن:$1",
        "pt-login": "ڤامین اوڤیڌن",
        "pt-login-button": "ڤامین اوڤیڌن",
        "passwordreset-username": "نوم کارياري",
        "passwordreset-domain": "پوشگر",
        "passwordreset-email": "تيرنشۈن أنجومانامأ",
+       "passwordreset-emailtitle": "جوزيات هساڤ مإن{{SITENAME}}",
+       "passwordreset-invalidemail": "تيرنشۈن أنجومانامأ نادوروسد",
+       "changeemail-oldemail": "تيرنشۈن أنجومانامإ ايسني",
+       "changeemail-newemail": "تيرنشۈن أنجومانامإ تازأ:",
        "changeemail-none": "(هيش كوم)",
+       "changeemail-password": "رازينإ گوڤأرتن {{SITENAME}} ایسا:",
+       "changeemail-submit": "آلشد کردن أنجومانامأ",
+       "resettokens": "ز نۉ کردن نشۈنإیل",
+       "resettokens-tokens": "نشۈنإیل:",
+       "resettokens-token-label": "$1 (أرزایشت تازأ: $2)",
        "bold_sample": "متن گپ نما",
        "bold_tip": "متن گپ نما",
        "italic_sample": "متن شکسته",
        "exif-software": "نرم افزار ب کارگرهڌني",
        "exif-exifversion": "نوسقإ Exif",
        "exif-colorspace": "رنگ ڤأرگأ",
+       "exif-datetimeoriginal": "گات و ڤخت راسد ڤابيإن دۈنسمنديا",
        "exif-datetimedigitized": "گات و وخت دیجیتالی کردن",
        "exif-orientation-1": "عادي",
        "namespacesall": "همه",
index 95feb19..a47a9e4 100644 (file)
        "accmailtext": "Kaset ez eus bet ur ger-tremen dargouezhek evit [[User talk:$1|$1]] da $2. Cheñchet e c'hall ar ger-tremen evit ar gont nevez-mañ bezañ war ar bajenn ''[[Special:ChangePassword|cheñch ger-tremen]]'', ur wezh kevreet.",
        "newarticle": "(Nevez)",
        "newarticletext": "Heuliet hoc'h eus ul liamm a gas d'ur bajenn n'eo ket bet savet evit c'hoazh.\nA-benn krouiñ ar bajenn-se, krogit da skrivañ er prenestr skridaozañ dindan (gwelet ar [$1 bajenn skoazell] evit gouzout hiroc'h).\nM'emaoc'h en em gavet amañ dre fazi, klikit war bouton '''kent''' ho merdeer evit mont war ho kiz.",
-       "anontalkpagetext": "---- ''Homañ eo ar bajenn gaozeal evit un implijer(ez) dizanv n'eus ket krouet kont ebet evit c'hoazh pe na implij ket anezhi.\nSetu perak e rankomp ober gant ar chomlec'h IP niverel evit anavezout anezhañ/i.\nGallout a ra ur chomlec'h a seurt-se bezañ rannet etre meur a implijer(ez).\nMa'z oc'h un implijer(ez) dizanv ha ma stadit ez eus bet kaset deoc'h kemennadennoù na sellont ket ouzhoc'h, gallout a rit [[Special:CreateAccount|krouiñ ur gont]]pe [[Special:UserLogin|kevreañ]] kuit a vagañ muioc'h a gemmesk gant implijerien dizanv all.",
+       "anontalkpagetext": "<em>Homañ eo ar bajenn gaozeal evit un implijer dizanv n'en deus ket krouet kont ebet evit c'hoazh pe na implij ket anezhi</em>.\nSetu perak e rankomp ober gant ar chomlec'h IP niverel evit anavezout anezhañ.\nGallout a ra ur chomlec'h a seurt-se bezañ rannet etre meur a implijer.\nMa'z oc'h un implijer dizanv ha ma stadit ez eus bet kaset deoc'h kemennadennoù na sellont ket ouzhoc'h, gallout a rit [[Special:CreateAccount|krouiñ ur gont]] pe [[Special:UserLogin|kevreañ]] kuit a vagañ muioc'h a gemmesk gant implijerien dizanv all.",
        "noarticletext": "N'eus tamm skrid ebet war ar bajenn-mañ evit poent.\nGallout a rit [[Special:Search/{{PAGENAME}}|klask an titl anezhi]] e pajennoù all,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} klask en oberiadennoù liammet], pe [{{fullurl:{{FULLPAGENAME}}|action=edit}} krouiñ ar bajenn]</span>.",
        "noarticletext-nopermission": "N'eus, evit ar mare, tamm testenn ebet war ar bajenn-mañ.\nGallout a rit [[Special:Search/{{PAGENAME}}|klask titl ar bajenn-mañ]] war pajennoù all,\npe <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} klask er marilhoù kar]</span>, met n'oc'h ket aotreet da grouiñ ar bajenn-mañ.",
        "missing-revision": "N'eus ket eus adwel niv. $1 eus ar bajenn anvet « {{FULLPAGENAME}} ».\n\nC'hoarvezout a ra peurliesañ pa vez heuliet ul liamm istorel dispredet war-zu ur bajenn zo bet dilamet.\nGallout a reot kavout muioc'h a vunudoù e [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} renabl an dilamadurioù].",
        "userpage-userdoesnotexist": "N'eo ket enrollet ar gont \"<nowiki>$1</nowiki>\". Merkit ma fell deoc'h krouiñ/kemmañ ar bajenn-mañ.",
        "userpage-userdoesnotexist-view": "N'eo ket enrollet ar gont implijer \"$1\".",
        "blocked-notice-logextract": "Stanket eo an implijer-mañ evit poent.\nDindan emañ merket moned diwezhañ marilh ar stankadennoù, d'ho kelaouiñ :",
-       "clearyourcache": "Notenn :''' Goude bezañ enrollet ho pajenn e rankot freskaat krubuilh ho merdeer a-benn gwelet ar c'hemmoù.\n* '''Firefox / Safari:''' Derc'hel da bouezañ war ''Pennlizherenn'' en ur glikañ war ''Adkargañ'', pe pouezañ war ''Ctrl-F5'' pe ''Ctrl-R'' (''⌘-R'' war ur Mac); \n* ''''Google Chrome:''' Pouezañ war ''Ctrl-Pennlizh-R'' (''⌘-Shift-R'' war ur Mac)\n* '''Internet Explorer:''' Derc'hel da bouezañ war ''Ctrl'' en ur glikañ war ''Freskaat,'' pe pouezañ war ''Ctrl-F5''\n* ''''Konqueror: '''Klikañ war ''Adkargañ'' pe pouezañ war ''F5;'' \n* '''Opera:''' Riñsañ ar grubuilh e ''Ostilhoù → Penndibaboù''",
+       "clearyourcache": "<strong>Notenn :</strong> Goude bezañ enrollet ho pajenn e rankot freskaat krubuilh ho merdeer a-benn gwelet ar c'hemmoù.\n* <strong>Firefox / Safari:</strong> Derc'hel da bouezañ war <em>Pennlizherenn</em> en ur glikañ war <em>Adkargañ</em>, pe pouezañ war <em>Ctrl-F5</em> pe <em>Ctrl-R</em> (<em>⌘-R</em> war ur Mac); \n* <strong>Google Chrome:</strong> Pouezañ war <em>Ctrl-Pennlizh-R</em> (<em>⌘-Shift-R</em> war ur Mac)\n* <strong>Internet Explorer :</strong> Derc'hel da bouezañ war <em>Ctrl</em> en ur glikañ war <em>Freskaat</em>, pe pouezañ war <em>Ctrl-F5</em>\n* <strong>Konqueror :</strong> Klikañ war <em>Adkargañ</em> pe pouezañ war <em>F5</em>\n* <strong>Opera :</strong> Mont da <em>Arventennoù → lañser</em> (<em>Opera → Penndibaboù</em> war ur Mac) ha goude mont da <em>Prevezded & surentez → Riñsañ roadennoù ar grubuilh → Skeudennoù krubuilhet ha restroù</em>.",
        "usercssyoucanpreview": "'''Tun :''' Grit gant ar bouton \"{{int:showpreview}}\" evit testiñ ho follenn CSS nevez a-raok enrollañ anezhi.",
        "userjsyoucanpreview": "'''Tun :''' Grit gant ar bouton \"{{int:showpreview}}\" evit testiñ ho follenn JS nevez a-raok enrollañ anezhi.",
        "usercsspreview": "'''Dalc'hit soñj n'emaoc'h ken nemet o rakwelet ho follenn CSS deoc'h.'''\n'''N'eo ket bet enrollet evit c'hoazh!'''",
        "previewnote": "'''Diwallit mat, n'eus ken ur rakweled eus an destenn-mañ.'''\nN'eo ket bet enrollet ho kemmoù evit c'hoazh !",
        "continue-editing": "Mont d'an takad kemmañ",
        "previewconflict": "Gant ar rakweled e teu testenn ar bajenn war wel evel ma vo pa vo bet enrollet.",
-       "session_fail_preview": "'''Ho tigarez! N'eus ket bet tu da enrollañ ho kemmoù rak kollet eo bet roadennoù an dalc'h.'''\nKlaskit en-dro mar plij.\nMa ne'z a ket en-dro c'hoazh, klaskit [[Special:UserLogout|digevreañ]] hag adkevreañ war-lerc'h.",
-       "session_fail_preview_html": "'''Ho tigarez! N'omp ket bet gouest da enrollañ ho kemmoù rak kollet ez eus bet roadennoù e-kerzh an dalc'h.'''\n\n''Gweredekaet eo al linennoù HTML e {{SITENAME}}. Rak-se eo kuzh ar rakweledoù a-benn en em zifenn diouzh an tagadennoù JavaScript.''\n\n'''Mard e oa onest ar c'hemmoù hoc'h eus klasket degas, klaskit en-dro. '''\nMar ned a ket en-dro, klaskit [[Special:UserLogout|digevreañ]] ha kevreañ en-dro.",
+       "session_fail_preview": "Ho tigarez ! N'eus ket bet tu da enrollañ ho kemmoù rak kollet eo bet roadennoù an dalc'h.\n\nMarteze n'oc'h ket kevreet ken. <strong>Gwiriit emaoc'h mat kevreet ha klaskit en-dro</strong>.\n\nMa ne'z a ket en-dro c'hoazh, klaskit [[Special:UserLogout|digevreañ]] hag adkevreañ war-lerc'h. Gwiriit mat e asant ho merdeer resev toupinoù a-berzh al lec'hienn-mañ ivez.",
+       "session_fail_preview_html": "Ho tigarez ! N'omp ket bet gouest da enrollañ ho kemmoù rak kollet ez eus bet roadennoù e-kerzh an dalc'h.\n\n<em>Gweredekaet eo al linennoù HTML e {{SITENAME}}. Rak-se eo kuzh ar rakweledoù a-benn en em zifenn diouzh an tagadennoù JavaScript.</em>\n\n<strong>Ma oa reizh ar c'hemmoù hoc'h eus klasket degas, klaskit en-dro.</strong>\nMa ned a ket en-dro, klaskit [[Special:UserLogout|digevreañ]] hag adkevreañ goude. Gwiriit e asant mat ho merdeer degemer toupinoù a-berzh al lec'hienn-mañ ivez.",
        "token_suffix_mismatch": "'''Distaolet eo bet ar c'hemmoù degaset ganeoc'h abalamour ma oa bet kemmesket an arouezennoù poentadur gant ho merdeer en daveer kemmañ. Distaolet eo bet ar c'hemmoù kuit na vije breinet ar bajennad skrid.\nC'hoarvezout a ra a-wechoù pa implijit ur servijer proksi dreinek dizanav.'''",
        "edit_form_incomplete": "'''Darn eus ar furmskrid kemmañ zo chomet hep tizhout ar servijer ; gwiriit ervat emañ mat ho kemmoù tre evel m'int bet graet ganeoc'h ha klaskit en-dro.'''",
        "editing": "Oc'h aozañ $1",
        "permissionserrors": "Fazi aotre",
        "permissionserrorstext": "N'oc'h ket aotreet d'ober kement-mañ evit {{PLURAL:$1|an abeg-mañ|an abegoù-mañ}} :",
        "permissionserrorstext-withaction": "N'oc'h ket aotreet da $2, evit an {{PLURAL:$1|abeg-mañ|abeg-mañ}} :",
+       "contentmodelediterror": "N'hallit ket kemmañ an adweladenn-mañ peogwir ez eo par he fatrom danvez da <code>$1</code>, ar pezh zo disheñvel diouzh ar patrom danvez implijet bremañ war ar bajenn <code>$2</code>.",
        "recreate-moveddeleted-warn": "'''Diwallit : Emaoc'h o krouiñ ur bajenn zo bet diverket c'hoazh.'''\n\nEn em soñjit ervat ha talvoudus eo kenderc'hel krouiñ ar bajenn.\nDeoc'h da c'houzout, aze emañ ar marilhoù diverkañ hag adenvel :",
        "moveddeleted-notice": "Diverket eo bet ar bajenn-mañ.\nDindan emañ ar marilh diverkañ hag adenvel.",
+       "moveddeleted-notice-recent": "Ho tigarez, nevez ziverket eo bet ar bajenn-mañ (e-kerzh an 24 eurvezh tremenet).\nDindan emañ ar marilhoù diverkañ hag adenvel evit ho kelaouiñ.",
        "log-fulllog": "Gwelet ar marilh klok",
        "edit-hook-aborted": "C'hwitet ar c'hemmañ gant un astenn.\nAbeg dianav.",
        "edit-gone-missing": "Dibosupl hizivaat ar bajenn.\nDiverket eo bet evit doare.",
        "editpage-invalidcontentmodel-title": "N'eo ket skoret ar patrom danvez",
        "editpage-invalidcontentmodel-text": "N'eo ket skoret ar patrom danvez \"$1\".",
        "editpage-notsupportedcontentformat-title": "Furmad endalc'had ha n'eo ket kemeret e karg",
+       "editpage-notsupportedcontentformat-text": "N'eo ket skoret ar patrom $1 gant ar patrom danvez $2.",
        "content-model-wikitext": "wikitestenn",
        "content-model-text": "testenn blaen",
        "content-model-javascript": "Javascript",
        "content-json-empty-object": "Elfenn goullo",
        "content-json-empty-array": "Taolenn c'houllo",
        "deprecated-self-close-category": "Pajennoù a ra gant tikedennoù HTML emserriñ direizh",
+       "deprecated-self-close-category-desc": "Er bajenn-mañ ez eus tikedennoù HTML emserriñ, evel <code>&lt;b/></code> pe <code>&lt;span/></code>.  Cheñch a raio o emzalc'h a-raok pell evit bezañ diouzh an erbedadennoù HTML5. Gant se eo dispredet implijout anezho er wikitestenn.",
+       "duplicate-args-warning": "<strong>Taolit evezh : Emañ </strong> [[:$1]] o c'hervel [[:$2]] gant muioc'h eget un talvoud evit an arventenn \"$3\". N'eus nemet an talvoud pourchaset da ziwezhañ a vo implijet.",
+       "duplicate-args-category": "Pajennoù a ra gant arguzennoù eilet er galvoù patrom",
+       "duplicate-args-category-desc": "Er bajenn-mañ ez eus galvoù patroù a ra gant arguzennoù eilet, evel <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> pe <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "expensive-parserfunction-warning": "<strong>Diwallit :</strong>: Re a c'halvoù koustus e-keñver an arc'hwelioù parser zo er bajenn-mañ.\n\nDleout a rafe bezañ nebeutoc'h eget $2 {{PLURAL:$2|galv}}, ha {{PLURAL:$1|$1 galv}} zo.",
        "expensive-parserfunction-category": "Pagjennoù enno re a c'halvoù koustus e-keñver an arc'hwelioù parser.",
        "post-expand-template-inclusion-warning": "Diwallit : re a batromoù zo war ar bajenn-mañ.\nLod anezho a vo lakaet a-gostez.",
        "undo-summary": "Dizober kemmoù $1 a-berzh [[Special:Contributions/$2|$2]] ([[User talk:$2|kaozeal]])",
        "undo-summary-username-hidden": "Dizober ar reizhadenn $1 gant un implijer kuzhet",
        "cantcreateaccount-text": "Stanket eo bet ar c'hrouiñ kontoù adal ar chomlec'h IP ('''$1''') gant [[User:$3|$3]].\n\nAn abeg roet gant $3 zo ''$2''",
+       "cantcreateaccount-range-text": "Berzet eo bet gant [[User:$3|$3]] ar c'hrouiñ kontoù adalek ar chomlec'hioù IP el lijorennoù <strong>$1</strong> m'emañ ho chomlec'h IP (<strong>$4</strong>), \n\n<em>$2</em> eo an abeg roet gant $3",
        "viewpagelogs": "Gwelet ar marilhoù evit ar bajenn-mañ",
        "nohistory": "Ar bajenn-mañ n'he deus tamm istor ebet.",
        "currentrev": "Stumm a-vremañ pe stumm red",
        "history-feed-description": "Istor ar c'hemmoù degaset war ar bajenn-mañ eus ar wiki",
        "history-feed-item-nocomment": "$1 d'an $2",
        "history-feed-empty": "Ar bajenn goulennet n'eus ket anezhi.\nMarteze eo bet diverket eus ar wiki, pe adanvet.\nImplijit [[Special:Search|klaskit er wiki]] evit kavout pajennoù all a c'hallfe klotañ.",
+       "history-edit-tags": "Kemmañ tikedennoù ar stummoù diuzet",
        "rev-deleted-comment": "(diverradenn ar c'hemm diverket)",
        "rev-deleted-user": "(anv implijer diverket)",
-       "rev-deleted-event": "(elfenn dilamet)",
+       "rev-deleted-event": "(munudoù ar marilh bet dilamet)",
        "rev-deleted-user-contribs": "[anv implijer pe chomlec'h IP diverket - kemm kuzhet diouzh an degasadennoù]",
        "rev-deleted-text-permission": "'''Diverket''' eo bet ar stumm-mañ eus ar bajenn.\nMarteze e kavot munudoù war [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} roll ar pajennoù diverket].",
+       "rev-suppressed-text-permission": "<strong>Diverket</strong> eo bet ar stumm-mañ eus ar bajenn.\nGallout a reot kavout ar munudoù e [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} marilh an diverkadennoù].",
        "rev-deleted-text-unhide": "!'''Diverket''' eo bet ar stumm-mañ eus ar bajenn.\nMarteze e kavot munudoù war [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} marilh ar pajennoù diverket].\nGallout a rit [$1 gwelet ar stumm-se] c'hoazh mar fell deoc'h kenderc'hel.",
        "rev-suppressed-text-unhide": "'''Diverket''' eo bet ar stumm-mañ eus ar bajenn.\nTitouroù zo da gaout war [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} marilh ar pajennoù diverket].\nGallout a rit [$1 gwelet ar stumm-se] c'hoazh mar fell deoc'h kenderc'hel.",
        "rev-deleted-text-view": "'''Diverket''' eo bet ar stumm-mañ eus ar bajenn.\nGallout a rit sellet outañ ; titouroù all a gavot war [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} marilh ar pajennoù diverket].",
        "rev-showdeleted": "diskouez",
        "revisiondelete": "Diverkañ/diziverkañ stummoù",
        "revdelete-nooldid-title": "N'eus stumm pal ebet evit an degasadennoù",
-       "revdelete-nooldid-text": "Pe n'eo ket bet spisaet ganeoc'h ar stumm(où) pal da implijout an arc'hwel-mañ evito. pe n'eus ket eus ar stummoù spisaet, pe emaoc'h o klask kuzhat ar stumm red.",
+       "revdelete-nooldid-text": "Pe n'eus ket bet spisaet ganeoc'h stumm pal ebet da lakaat an arc'hwel-mañ da vont en-dro warnañ, pe n'eus ket eus ar stummoù spisaet, pe emaoc'h o klask kuzhat ar stumm red.",
        "revdelete-no-file": "N'eus ket eus ar restr spisaet ganeoc'h.",
        "revdelete-show-file-confirm": "Ha sur oc'h e fell deoc'h gwelet stumm diverket ar restr \"<nowiki>$1</nowiki>\" deiziataet eus an $2 da $3?",
        "revdelete-show-file-submit": "Ya",
+       "revdelete-selected-text": "{{PLURAL:$1|Stummoù diuzet|Stumm diuzet}} of [[:$2]]:",
+       "revdelete-selected-file": "{{PLURAL:$1|Stumm eus ar restr diuzet}} evit [[:$2]] :",
        "logdelete-selected": "{{PLURAL:$1|Darvoud eus ar marilh diuzet}} :",
+       "revdelete-text-text": "Dont a raio c'hoazh war wel ar stummoù diverket en istor ar bajenn met ne c'hallo ket an dud gwelet darn eus an danvez ken.",
        "revdelete-text-file": "Dalc'het e vo da welet stummoù restroù dilamet en istor ar restr, nemet ne c'hallo ket an dud mont da welet un darn anezho.",
        "logdelete-text": "Gwelet e vo c'hoazh dilamadennoù er marilhoù, nemet ne c'hallo ket an dud mont da welet un darn anezho.",
        "revdelete-text-others": "Ar verourien a c'hallo c'hoazh mont da welet petra zo e-barzh, hag eilpennañ an dilamadenn, nemet ha reolennoù strishoc'h ouzhpenn a vefe.",
        "revdelete-legend": "Lakaat strishadurioù gwelet",
        "revdelete-hide-text": "Testenn ar stumm",
        "revdelete-hide-image": "Kuzhat danvez ar restr",
-       "revdelete-hide-name": "Kuzhat an ober hag ar vukadenn",
+       "revdelete-hide-name": "Kuzhat ar pal hag an arventennoù",
        "revdelete-hide-comment": "Notenn ar c'hemm",
        "revdelete-hide-user": "Anv implijer pe chomlec'h IP an aozer",
        "revdelete-hide-restricted": "Diverkañ ar roadennoù kement d'ar verourien ha d'ar re all",
        "revdelete-unsuppress": "Lemel ar strishadurioù war ar stummoù assavet",
        "revdelete-log": "Abeg :",
        "revdelete-submit": "Lakaat da dalvezout evit an {{PLURAL:$1|adweladenn|adweladennoù}} diuzet",
-       "revdelete-success": "''Gweluster ar stummoù hizivaet mat.'''",
+       "revdelete-success": "Gweluster ar stummoù hizivaet.",
        "revdelete-failure": "''Dibosupl hizivaat gweluster ar stumm :'''\n$1",
-       "logdelete-success": "'''Gweluster ar marilh arventennet evel m'eo dleet.'''",
+       "logdelete-success": "Kemmet eo bet gweluster ar marilh.",
        "logdelete-failure": "'''N'eus ket bet gallet termeniñ gweluster ar marilh :'''\n$1",
        "revdel-restore": "Cheñch ar gweluster",
        "pagehist": "Istor ar bajenn",
        "mergehistory-go": "Diskouez ar stummoù a c'haller kendeuziñ",
        "mergehistory-submit": "Kendeuziñ ar stummoù",
        "mergehistory-empty": "N'haller ket kendeuziñ stumm ebet.",
-       "mergehistory-done": "Kendeuzet ez eus bet $3 {{PLURAL:$3|stumm|stumm}} eus $1 e [[:$2]].",
+       "mergehistory-done": "Kendeuzet ez eus bet $3 {{PLURAL:$3|stumm}} eus $1 e [[:$2]].",
        "mergehistory-fail": "Dibosupl kendeuziñ an istorioù. Gwiriit ar bajenn hag arventennoù an deiziadoù.",
        "mergehistory-fail-bad-timestamp": "Merk amzer direizh.",
        "mergehistory-fail-invalid-source": "Pajenn darzh direizh.",
        "mergehistory-fail-invalid-dest": "Pajenn vuket direizh.",
+       "mergehistory-fail-no-change": "N'eus ket bet kendeuzet stumm ebet p'eo bet kendeuzet an istor. Gwiriit en-dro ar bajenn hag an arventennoù amzer.",
+       "mergehistory-fail-permission": "Re izel eo ho kwirioù evit gallout kendeuziñ an istor.",
+       "mergehistory-fail-self-merge": "Mammenn ha pal ar bajenn n'hall ket bezañ heñvel.",
+       "mergehistory-fail-timestamps-overlap": "En em frikañ a ra stummoù ar vammenn pe dont a reont war-lerc'h stummoù pal.",
        "mergehistory-fail-toobig": "Ne c'haller ket kendeuziñ an istorioù o vezañ ma vefe mont en tu all d'ar harzh a $1 reizhadenn da zilec'hiañ.",
        "mergehistory-no-source": "N'eus ket eus ar bajenn orin $1.",
        "mergehistory-no-destination": "N'eus ket eus ar bajenn dal $1.",
        "search-category": "(rummad $1)",
        "search-file-match": "(klotañ a ra gant endalc'had ar restr)",
        "search-suggest": "N'hoc'h eus ket soñjet kentoc'h e : $1",
+       "search-rewritten": "O tiskouez disoc'hoù evit $1. Klask $2 kentoc'h.",
        "search-interwiki-caption": "Raktresoù kar",
        "search-interwiki-default": "Disoc'hoù eus $1 :",
        "search-interwiki-more": "(muioc'h)",
        "prefs-tokenwatchlist": "Jedouer",
        "prefs-diffs": "Diforc'hioù",
        "prefs-help-prefershttps": "Efediñ a ray an dibarzh-mañ kentañ gwech ma kevreoc'h.",
+       "prefswarning-warning": "Kemmet eo bet ho penndibaboù ganeoc'h, met enrollet n'int ket bet avat.\nMar kuitait ar bajenn-mañ hep klikañ war \"$1\" ne vo ket nevesaet ho penndibaboù",
        "prefs-tabs-navigation-hint": "Titourig : Gallout a rit implijout an touchennoù bir kleiz ha bir dehoù evit merdeiñ etre an ivinelloù e roll an ivinelloù.",
        "userrights": "Merañ statud an implijerien",
        "userrights-lookup-user": "Diuzañ un implijer",
        "userrights-user-editname": "Lakait un anv implijer :",
        "editusergroup": "Kargañ strolladoù implijerien",
        "editinguser": "O kemmañ gwirioù an {{GENDER:$1|implijer|implijerez}} <strong>[[User:$1|$1]]</strong> $2",
-       "userrights-editusergroup": "Kemmañ strolladoù an implijer",
-       "userrights-viewusergroup": "Gwelet ar strolladoù implijerien",
+       "viewinguserrights": "Gwelet gwirioù an {{GENDER:$1|implijer|implijerez}} <strong>[[User:$1|$1]]</strong> $2",
+       "userrights-editusergroup": "Kemmañ strolladoù an {{GENDER:$1|implijer|implijerez}}",
+       "userrights-viewusergroup": "Gwelet strolladoù an {{GENDER:$1|implijer|implijerez}}",
        "saveusergroups": "Enrollañ strolladoù an {{GENDER:$1|implijer|implijerez}}",
        "userrights-groupsmember": "Ezel eus :",
        "userrights-groupsmember-auto": "Ezel emplegat eus :",
-       "userrights-groups-help": "Cheñch strollad an implijer a c'hallit ober.\n* Ul log asket a verk emañ an implijer er strollad.\n* Ul log diask a verk n'emañ ket an implijer er strollad.\n* Ur * a verk n'hallit ket dilemel ar strollad ur wech bet ouzhpennet, pe ar c'hontrol.",
+       "userrights-groups-help": "Cheñch strolladoù an implijer a c'hallit ober.\n* Ul log asket a verk emañ an implijer er strollad.\n* Ul log diask a verk n'emañ ket an implijer er strollad.\n* Ur * a verk n'hallit ket dilemel ar strollad ur wech bet ouzhpennet ganeoc'h, pe ar c'hontrol.\n* Ur # a verk a c'hallit astenn termen echuiñ ar strollad hepken ; n'hallit ket berraat anezhañ.",
        "userrights-reason": "Abeg :",
        "userrights-no-interwiki": "N'oc'h ket aotreet da gemmañ ar gwirioù implijer war wikioù all.",
        "userrights-nodatabase": "N'eus ket eus an diaz titouroù $1 pe n'eo ket lec'hel.",
        "userrights-expiry-options": "1 deiz:1 day,1 sizhun:1 week,1 miz:1 month,3 miz:3 months,6 miz:6 months, bloaz:1 year",
        "userrights-invalid-expiry": "Direizh eo termen echuiñ ar strollad \"$1\".",
        "userrights-expiry-in-past": "Re gozh eo termen echuiñ ar strollad \"$1\".",
+       "userrights-cannot-shorten-expiry": "N'hallit ket astenn termen echuiñ ar strollad \"$1\". N'eus nemet an implijerien aotreet da ouzhpennañ ha lemel ar strollad-mañ a c'hall astenn an termen.",
        "userrights-conflict": "Bec'h zo abalamour da gemmoù e gwirioù an implijerien. Adwelit an traoù, mar plij, ha kadarnait ho kemmoù.",
        "group": "Strollad :",
        "group-user": "Implijerien",
        "right-reupload-shared": "Gwaskañ restroù ent lec'hel war an diellaoueg vedia rannet",
        "right-upload_by_url": "Enporzhiañ ur restr adal ur chomlec'h URL",
        "right-purge": "Spujañ krubuilh ar pajennoù hep kadarnaat",
-       "right-autoconfirmed": "Kemmañ ar pajennoù damwarezet",
+       "right-autoconfirmed": "Na vezañ trubuilhet gant ar bevennoù kas liammet ouzh ar chomlec'hioù IP",
        "right-bot": "Plediñ ganti evel gant un argerzh emgefre",
        "right-nominornewtalk": "Arabat diskouez ar c'hemenn \"Kemennoù nevez zo ganeoc'h\" pa vez lakaet kemmoù dister e pajenn gaozeal un implijer",
        "right-apihighlimits": "Kreskiñ ar bevennoù er goulennoù API",
        "right-deletedtext": "Gwelet ar skrid diverket hag an diforc'hioù etre ar stummoù diverket",
        "right-browsearchive": "Klask pajennoù bet diverket",
        "right-undelete": "Assevel ur bajenn",
-       "right-suppressrevision": "Teuler ur sell war ar stummoù kuzhet ouzh ar verourien hag assevel anezho",
+       "right-suppressrevision": "Gwelet, kuzhat ha diguzhat stummoù resis pajennoù zo diouzh selloù an implijerien all",
+       "right-viewsuppressed": "Gwelet ar stummoù kuzhet diouzh an implijerien all",
        "right-suppressionlog": "Gwelet ar marilhoù prevez",
        "right-block": "Mirout ouzh an implijerien all a gemmañ pajennoù pelloc'h",
        "right-blockemail": "Mirout ouzh un implijer a gas posteloù",
        "right-hideuser": "Stankañ un implijer, en ur guzhat anezhañ diouzh ar re all",
        "right-ipblock-exempt": "Tremen dreist an IPoù stanket, ar stankadennoù emgefre hag ar bloc'hadennoù IP stanket",
        "right-unblockself": "En em zistankañ",
-       "right-protect": "Kemmañ live gwareziñ ar pajennoù ha kemmañ ar pajennoù gwarezet",
+       "right-protect": "Kemmañ live gwareziñ ar pajennoù ha kemmañ ar pajennoù gwarezet dre skalierad",
        "right-editprotected": "Aozañ ar pajennoù gwarezet evel \"{{int:protect-level-sysop}}\"",
        "right-editsemiprotected": "Aozañ ar pajennoù gwarezet evel \"{{int:protect-level-autoconfirmed}}\"",
+       "right-editcontentmodel": "Kemmañ patrom danvez ur bajenn bennak",
        "right-editinterface": "Kemmañ an etrefas implijer",
        "right-editusercssjs": "Kemmañ restroù CSS ha JS implijerien all",
        "right-editusercss": "Kemmañ restroù CSS implijerien all",
        "right-editmyusercss": "Aozañ ho restroù implijer CSS deoc'h-c'hwi",
        "right-editmyuserjs": "Aoazañ ho restroù JavaScript implijer deoc'h-c'hwi",
        "right-viewmywatchlist": "Gwelet ho roll-evezhiañ deoc'h-c'hwi",
+       "right-editmywatchlist": "Kemmañ ho roll evezhiañ deoc'h-c'hwi. Notit mat e vo c'hoazh ouzhpennet pajennoù hep ar gwir-mañ gant obererezhioù zo.",
        "right-viewmyprivateinfo": "Gwelet ho roadennoù prevez deoc'h-c'hwi (da sk. chomlec'h postel, anv gwirion)",
        "right-editmyprivateinfo": "Aozañ ho roadennoù prevez deoc'h-c'hwi (da sk. chomlec'h postel, anv gwirion)",
        "right-editmyoptions": "Kemmañ ho penndibaboù",
        "right-siteadmin": "Prennañ ha dibrennañ ar bank-titouroù",
        "right-override-export-depth": "Ezporzhiañ ar pajennoù en ur lakaat e-barzh ar pajennoù liammet betek un donder a 5 live",
        "right-sendemail": "Kas ur postel d'an implijerien all",
+       "right-managechangetags": "Krouiñ ha gweredekaat/diweredekaat [[Special:Tags|tikedennoù]]",
+       "right-applychangetags": "Lakaat [[Special:Tags|an tikedennoù]] e pleustr asambles gant kemmoù an-unan",
+       "right-changetags": "Ouzhpennañ ha dilemel [[Special:Tags|tikedennoù]], diwar ziviz, war adweladennoù hiniennel pe monedoù marilh.",
+       "right-deletechangetags": "Diverkañ[[Special:Tags|tikedennoù]] a-ziwar an diaz roadennoù",
+       "grant-generic": "Pakad aotreoù \"$1\"",
+       "grant-group-page-interaction": "Etreober gant pajennoù",
+       "grant-group-file-interaction": "Etreober gant mediaoù",
+       "grant-group-watchlist-interaction": "Etreober gant ho roll evezhiañ",
        "grant-group-email": "Kas ur postel",
+       "grant-group-high-volume": "Seveniñ ur pikol obererezh",
+       "grant-group-customization": "Personeladur ha penndibaboù",
+       "grant-group-administration": "Seveniñ oberoù melestradurel",
+       "grant-group-private-information": "Gwelet ar roadennoù prevez diwar ho penn",
        "grant-group-other": "Obererezh liesseurt",
        "grant-blockusers": "Stankañ ha distankañ implijerien",
        "grant-createaccount": "Krouiñ kontoù",
        "action-editcontentmodel": "Kemmañ patrom danvez ur bajenn",
        "action-managechangetags": "krouiñ ha gweredekaat/diweredekaat tikedennoù",
        "action-applychangetags": "lakaat e pleustr an tikedennoù a-gevret gant ho kemmoù",
+       "action-changetags": "ouzhpennañ ha dilemel tikedennoù diwar ziviz diouzh adweladennoù hiniennel pe monedoù marilh",
        "action-deletechangetags": "Diverkañ tikedennoù a-ziwar an diaz-roadennoù",
        "action-purge": "spurjañ ar bajenn-mañ",
        "nchanges": "$1 {{PLURAL:$1|kemm|kemm}}",
        "rcfilters-invalid-filter": "Sil direizh",
        "rcfilters-empty-filter": "Sil oberiant ebet. War wel emañ an holl gemmoù.",
        "rcfilters-filterlist-title": "Siloù",
+       "rcfilters-filterlist-feedbacklink": "Reiñ ho soñj diwar-benn ar siloù (beta) nevez",
        "rcfilters-highlightbutton-title": "Lakaat an disoc'hoù war wel",
        "rcfilters-highlightmenu-title": "Dibabit ul liv",
        "rcfilters-filterlist-noresults": "N'eus bet kavet sil ebet",
        "rcfilters-filter-categorization-label": "Kemmoù rummad",
        "rcfilters-filter-categorization-description": "Roll ar pajennoù ouzhpennet da rummadoù zo pe dilamet diouto.",
        "rcfilters-filter-logactions-label": "Obererezhioù enrollet",
+       "rcfilters-filter-logactions-description": "Obererezhioù melestradurel, krouiñ kontoù, diverkañ pajennoù, enporzhiañ...",
        "rcnotefrom": "Setu aze {{PLURAL:$5|ar c'hemm|ar c'hemmoù}} c'hoarvezet abaoe an <strong>$3, $4</strong> (<strong>$1</strong> d'ar muiañ).",
        "rclistfrom": "Diskouez ar c'hemmoù diwezhañ abaoe an/ar $3 $2",
        "rcshowhideminor": "$1 ar c'hemmoù dister",
        "recentchangeslinked-page": "Anv ar bajenn :",
        "recentchangeslinked-to": "Diskouez ar c'hemmoù war-du ar pajennoù liammet kentoc'h eget re ar bajenn lakaet",
        "recentchanges-page-added-to-category": "[[:$1]] ouzhpennet d'ar rummad",
-       "recentchanges-page-removed-from-category": "Diverket eo bet [[$1]] diouzh ar rummad",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] ouzhpennet d'ar rummad, [[Special:WhatLinksHere/$1|emañ ensoc'het ar bajenn-mañ e diabarzh pajennoù all]]",
+       "recentchanges-page-removed-from-category": "Diverket eo bet [[:$1]] diouzh ar rummad",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] dilamet diouzh ar rummad, [[Special:WhatLinksHere/$1|emañ ensoc'het ar bajenn-mañ e diabarzh pajennoù all]]",
        "autochange-username": "Kemm emgefre gant MediaWiki",
        "upload": "Kargañ war ar servijer",
        "uploadbtn": "Kargañ ur restr",
        "uploaderror": "Fazi enporzhiañ",
        "upload-recreate-warning": "'''Diwallit''' : Diverket pe dilec'hiet ez eus bet ur restr gant an anv-se.'''\n\nDeoc'h da c'houzout, setu aze marilh an diverkañ hag an dilec'hiañ evit ar bajenn-mañ.",
        "uploadtext": "Grit gant ar furmskrid a-is evit enporzhiañ restroù war ar servijer.\nEvit sellet pe klask skeudennoù bet enporzhiet a-raok sellit ouzh [[Special:FileList|roll ar skeudennoù]]. Kavet e vo ar skeudennoù enporzhiet war [[Special:Log/upload|marilh ar pajennoù enporzhiet]] hag an diverkadennoù war [[Special:Log/delete|istor an diverkadennoù]].\n\nEvit enklozañ ur skeudenn en ur pennad, lakait er pennad-se ul liamm skrivet evel-henn :\n*'''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:anv_ar_restr.jpg]]</nowiki></code>''' evit diskouez ar restr en he spider brasañ ;\n*'''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:anv_ar_restr.png|deskrivadenn]]</nowiki></code>''' evit ober gant ur munud 200 piksel ledander er ur voest a-gleiz enni \"testenn zeskrivañ\" da zeskrivadenn\n*'''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:anv_ar_restr.ogg]]</nowiki></code>''' evit sevel ul liamm war-eeun war-du ar restr hep diskouez anezhi.",
-       "upload-permitted": "Seurtoù restroù aotreet : $1.",
-       "upload-preferred": "Seurtoù restroù gwellañ : $1.",
-       "upload-prohibited": "Seurtoù restroù berzet : $1.",
+       "upload-permitted": "{{PLURAL:$2|Seurt|Seurtoù}} restr aotreet : $1.",
+       "upload-preferred": "{{PLURAL:$2|Seurt|Seurtoù}} restr karetañ : $1.",
+       "upload-prohibited": "{{PLURAL:$2|Seurt|Seurtoù}} restr berzet : $1.",
        "uploadlogpage": "Marilh ar pajennoù enporzhiet",
        "uploadlogpagetext": "Setu a-is marilh ar restroù diwezhañ bet karget war ar servijer.\nS.o [[Special:NewFiles|rann ar skeudennoù nevez]] evit kaout ur sell gwiroc'h",
        "filename": "Anv ar restr",
        "largefileserver": "Brasoc'h eo ar restr-mañ eget ar pezh a c'hall ar servijer aotren.",
        "emptyfile": "Evit doare eo goullo ar restr bet karget ganeoc'h. Moarvat eo abalamour d'an tipo en anv ar restr. Gwiriit mat e fell deoc'h pellgargañ ar restr-mañ.",
        "windows-nonascii-filename": "N'eo ket skoret anvioù ar restroù enno arouezennoù dibar gant ar wiki-mañ.",
-       "fileexists": "Ur restr all gant an anv-se zo c'hoazh.\nTrugarez da wiriañ <strong>[[:$1]]</strong> ma n'oc'h ket sur e fell deoc'h kemmañ anezhi.\n[[$1|thumb]]",
+       "fileexists": "Ur restr all gant an anv-mañ zo c'hoazh.\nTrugarez da wiriañ <strong>[[:$1]]</strong> ma n'{{GENDER:|oc'h}} ket sur e fell deoc'h kemmañ anezhi.\n[[$1|thumb]]",
        "filepageexists": "Amañ <strong>[[:$1]]</strong> eo bet krouet ar bajenn zeskrivañ evit ar restr-mañ, padal n'eus restr ebet dezhi an anv-se evit c'hoazh.\nAn diverradenn skrivet ganeoc'h ne vo ket gwelet war ar bajenn zeskrivañ.\nMar fell deoc'h e teufe ho tiverradenn war wel eno eo ret deoc'h-c'hwi kemmañ anezhi hoc'h-unan.\n[[$1|thumb]]",
-       "fileexists-extension": "Bez' ez eus dija ur restr gant an anv-se war-bouez nebeut : [[$2|thumb]]\n* Anv ar restr emeur oc'h enporzhiañ : <strong>[[:$1]]</strong>\n* Anv ar restr zo anezhi dija : <strong>[[:$2]]</strong>\nDibabit un anv all mar plij.",
+       "fileexists-extension": "Bez' ez eus ur restr gant an hevelep anv koulz lavaret : [[$2|thumb]]\n* Anv ar restr emeur oc'h enporzhiañ : <strong>[[:$1]]</strong>\n* Anv ar restr zo anezhi c'hoazh : <strong>[[:$2]]</strong>\nDibab un anv all a fell deoc'h kentoc'h marteze ?",
        "fileexists-thumbnail-yes": "Evit doare ez eus ur skeudenn krennet he ment eus ar restr ''(thumbnail)''. [[$1|thumb]]\nGwiriit ar restr <strong>[[:$1]]</strong>.\nMard eo an hevelep skeudenn ha hini ar restr orin, ha heñvel he ment, n'eo ket dav pellgargañ ur stumm krennet ouzhpenn.",
        "file-thumbnail-no": "Kregiñ a ra anv ar restr gant <strong>$1</strong>.\nEvit doare eo ur skeudenn krennet he ment ''(thumbnail)''.\nMa'z eus ganeoc'h ur skeudenn uhel he fizhder, pellgargit anezhi; a-hend-all cheñchit anv ar restr.",
        "fileexists-forbidden": "Ur restr all gant an anv-se zo c'hoazh ha n'hall ket bezan diverket.\nMar fell deoc'h enporzhiañ ho restr memes tra, kit war ho kiz ha grit gant un anv all [[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "Ur restr all dezhi an hevelep anv zo c'hoazh er c'havlec'h eskemm restroù.\nMar fell deoc'h enporzhiañ ar restr-mañ da vat, kit war ho kiz hag enporzhiit anezhi adarre dindan un anv all. [[File:$1|thumb|center|$1]]",
+       "fileexists-no-change": "Rik-heñvel ouzh ar stumm a-vremañ eus <strong>[[:$1]]</strong> eo an enporzhiadenn-mañ.",
+       "fileexists-duplicate-version": "Rik-heñvel ouzh {{PLURAL:$2|ur stumm koshoc'h|stummoù koshoc'h}} eus <strong>[[:$1]]</strong> eo an enporzhiadenn-mañ.",
        "file-exists-duplicate": "Un eil eus ar {{PLURAL:$1|restr|restroù}} da-heul eo ar restr-mañ :",
        "file-deleted-duplicate": "Diverket ez eus bet c'hoazh ur restr heñvel-poch ouzh ar restr-mañ ([[:$1]]). Gwelloc'h e vefe deoc'h teuler ur sell war istor diverkadenn ar bajenn-se a-raok hec'h enporzhiañ en-dro.",
+       "file-deleted-duplicate-notitle": "Ur restr rik-heñvel ouzh homañ zo bet dilamet c'hoazh, hag an titl zo bet diverket. Gwelloc'h e vefe deoc'h gwelet gant unan bennak a c'hall gwelet roadennoù ar restroù diverket evit gwiriañ an traoù a-raok mont da adenporzhiañ anezhi.",
        "uploadwarning": "Kemenn diwall en ur ezporzhiañ",
        "uploadwarning-text": "Cheñchit deskrivadur ar restr a-is ha klaskit en-dro.",
        "savefile": "Enrollañ ar restr",
        "uploaddisabledtext": "Diweredekaet eo an enporzhiañ restroù.",
        "php-uploaddisabledtext": "Diweredekaet eo bet ar pellgargañ e PHP. Gwiriit an dibarzh arventennoù file_uploads.",
        "uploadscripted": "Er restr-mañ ez eus kodoù HTML pe skriptoù a c'hallfe bezañ kammgomprenet gant ur merdeer Kenrouedad.",
+       "upload-scripted-pi-callback": "Dibosupl eo enporzhiañ ur restr enni kemennoù plediñ gant ur follenn stil XML.",
+       "uploaded-script-svg": "Kavet ez eus bet ul elfenn skriptadus \"$1\" er restr SVG enporzhiet.",
+       "uploaded-hostile-svg": "Kavet ez eus bet ur CSS diasur en elfenn stil ur restr SVG.",
+       "uploaded-event-handler-on-svg": "N'eo ket aotreet spisaat perzhioù merañ darvoudoù <code>$1=\"$2\"</code> er restroù SVG.",
+       "uploaded-href-attribute-svg": "N'eo aotreet ar perzhioù href ere restroù SVG nemet evit liammañ ouzh palioù http:// pe https://, <code>&lt;$1 $2=\"$3\"&gt;</code> kavet.",
+       "uploaded-href-unsafe-target-svg": "Kavet ez eus bet un href war-zu roadennoù diasur er restr SVG bet enporzhiet : URI pal <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-animate-svg": "Kavet ez eus bet un dikedenn \"vevaet\" a c'hallfe cheñch an href, en ur ober gant ar perzh \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> er restr SVG enporzhiet.",
+       "uploaded-setting-event-handler-svg": "Stanket eo kefluniañ perzhioù dre ar merer darvoudoù, <code>&lt;$1 $2=\"$3\"&gt;</code> kavet er restr SVG bet enporzhiet.",
+       "uploaded-setting-href-svg": "Difennet eo ober gant an dikedenn \"set\" evit ouzhpennañ ur perzh \"href\" d'an elfenn kar.",
+       "uploaded-wrong-setting-svg": "Difennet eo ober gant an dikedenn \"set\" evit ouzhpennañ ur pal a-bell/roadenn/skript d'ur perzh bennak. Kavet eo bet <code>&lt;set to=\"$1\"&gt;</code> er restr SVG enporzhiet.",
+       "uploaded-setting-handler-svg": "Stanket eo an SVG a spisa ar perzh \"handler\" gant a-bell/roadennoù/skript. Kavet eo bet <code>$1=\"$2\"</code> er restr SVG enporzhiet.",
+       "uploaded-remote-url-svg": "Stanket eo an SVG a spisa ur perzh stil gant un URL a-bell. Kavet eo bet <code>$1=\"$2\"</code> er restr SVG enporzhiet.",
+       "uploaded-image-filter-svg": "Kavet ez eus bet ur sil skeudennoù gant un URL : <code>&lt;$1 $2=\"$3\"&gt;</code> er restr SVG enporzhiet.",
+       "uploadscriptednamespace": "Un anv esaouenn berzet zo er restr SVG \"<nowiki>$1</nowiki>\".",
        "uploadinvalidxml": "N'eus ket bet gallet dielfennañ an XML er restr ezporzhiet.",
        "uploadvirus": "Viruzet eo ar restr! Titouroù : $1",
        "uploadjava": "Ur restr ZIP a ra gant Java .class eo homañ.\nN'haller ket enporzhiañ restroù Java peogwir e c'haller mont dreist da vevennoù surentez ganto.",
        "upload-options": "Dibaboù kargañ",
        "watchthisupload": "Evezhiañ ar bajenn-mañ",
        "filewasdeleted": "Ur restr gant an anv-mañ zo bet enporzhiet dija ha diverket goude-se. Mat e vefe deoc'h gwiriañ an $1 a-raok hec'h enporzhiañ en-dro.",
+       "filename-thumb-name": "Tennañ a ra da ditl ur munud. Na enpotzhiit ket munudoù skeudennoù zo er wiki dija. Ma n'eo ket unan, cheñchit anv ar restr evit ma vefe splannoc'h ha na grogfe ket evel titl ur munud.",
        "filename-bad-prefix": "Anv ar restr emaoc'h oc'h enporzhiañ a grog gant '''\"$1\"''', da lavaret eo un anv dizeskrivus roet alies ent emgefre gant luc'hskeudennerezioù niverel. Dibabit un anv splannoc'h evit deskrivañ ar restr.",
        "filename-prefix-blacklist": " #<!-- lezel al linenn-mañ tre ha tre evel m'emañ --> <pre>\n# Setu penaos emañ an ereadur :\n#   * Pep tra adal un arouezenn \"#\" betek dibenn al linenn a ya d'ober un notenn\n#   * Pep linenn n'eo ket goullo zo ur rakger evit anvioù restroù heverk roet ent emgefre gant luc'hskeudennerezioù niverel\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # pellgomzerioù hezoug zo\nIMG # jenerik\nJD # Jenoptik\nMGP # Pentax\nPICT # misc.\n #</pre> <!-- leave this line exactly as it is -->",
        "upload-proto-error": "Protokol direizh",
        "upload-too-many-redirects": "Re a adkasoù zo en URL-mañ.",
        "upload-http-error": "Ur fazi HTTP zo bet : $1",
        "upload-copy-upload-invalid-domain": "N'haller ket seveniñ enporzhiadennoù a-bell adalek an domani-mañ.",
+       "upload-foreign-cant-upload": "N'eo ket kefluniet ar wiki-mañ evit enporzhiañ restroù d'ar c'havlec'h diellaouiñ diavaez goulennet.",
+       "upload-foreign-cant-load-config": "N'eus ket bet gallet kargañ ar c'hefluniadur enporzhiañ restroù diavaez d'ar c'havlec'h diellaouiñ.",
+       "upload-dialog-disabled": "Diweredekaet eo enporzhiañ restroù dre ar prenestr kaozeal-mañ war ar wiki-mañ.",
        "upload-dialog-title": "Kargañ ar restr",
        "upload-dialog-button-cancel": "Nullañ",
        "upload-dialog-button-back": "Kent",
        "upload-dialog-button-upload": "Enporzhiañ",
        "upload-form-label-infoform-title": "Munudoù",
        "upload-form-label-infoform-name": "Anv",
+       "upload-form-label-infoform-name-tooltip": "Un anv deskrivus nemetken evit ar restr a servijo da anv restr. Gallout a rit implijout ur yezh plaen gant esaouennoù. Arabat lakaat astenn ar restr.",
        "upload-form-label-infoform-description": "Deskrivadur",
+       "upload-form-label-infoform-description-tooltip": "Grit un tamm diverrañ eus perzhioù heverkañ al labour.\nEvit ur skeudenn, merkit ar pep pouezusañ eus ar pezh a weler, an degouezh pe al lec'h.",
        "upload-form-label-usage-title": "Implij",
        "upload-form-label-usage-filename": "Anv ar restr",
        "upload-form-label-own-work": "Setu aze ma zammig labour din-me",
        "upload-form-label-infoform-categories": "Rummadoù",
        "upload-form-label-infoform-date": "Deiziad",
+       "upload-form-label-own-work-message-generic-local": "Kadarnaat a ran emaon oc'h enporzhiañ ar restr-mañ en ur zoujañ d'an termenoù implijout ha d'ar reolennoù perc'henniezh a dalvez war {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-generic-local": "Ma n'oc'h ket gouest da enporzhiañ ar restr-mañ en ur zoujañ da reolennoù implij {{SITENAME}}, serrit ar prenestr-mañ ha klaskit un doare all.",
+       "upload-form-label-not-own-work-local-generic-local": "Gallout a ri klask gant [[Special:Upload|ar bajenn enporzhiañ dre ziouer]] ivez.",
+       "upload-form-label-own-work-message-generic-foreign": "Kompren mat a ran emaon oc'h enporzhiañ ar restr-mañ en ur c'havlec'h rannet. Kadarnaat a ran e ran se en ur zoujañ d'an termenoù servij hag ar reolennoù war ar berc'henniezh.",
+       "upload-form-label-not-own-work-message-generic-foreign": "Ma n'oc'h ket gouest da enporzhiañ ar restr-mañ en ur zoujañ da reolennoù ar c'havlec'h rannet, serrit ar prenestr-mañ ha klaskit un doare all.",
+       "upload-form-label-not-own-work-local-generic-foreign": "Marteze hoc'h eus c'hoazh da glask en ur implijout [[Special:Upload|ar bajenn enporzhiañ war {{SITENAME}}]], ma c'hall ar restr-mañ bezañ enporzhiet eno en ur zoujañ d'o reolennoù implijout.",
        "backend-fail-stream": "Dibosupl eo lenn ar restr $1.",
        "backend-fail-backup": "Dibosupl enrollañ ar restr $1.",
        "backend-fail-notexists": "N'eus ket eus ar restr $1.",
        "backend-fail-read": "Dibosupl lenn ar restr $1.",
        "backend-fail-create": "Dibosupl eo krouiñ ar restr $1.",
        "backend-fail-maxsize": "Dibosupl skrivañ er restr $1 peogwir eo brasoc'h eget {{PLURAL:$2|un okted|$2 okted}}.",
-       "backend-fail-readonly": "Emañ an dermenell stokañ \"$1\" e mod lenn hepken. Setu aze an abeg a oa bet roet : \"$2\".",
+       "backend-fail-readonly": "Emañ an dermenell stokañ \"$1\" e mod lenn hepken. Setu aze an abeg a oa bet roet : <em>$2</em>.",
        "backend-fail-synced": "Emañ ar restr \"$1\" en ur stad direizhet en termenelloù stokañ diabarzh",
        "backend-fail-connect": "Dibosupl kevreañ ouzh termenell stokañ ar restr \"$1\".",
        "backend-fail-internal": "C'hoarvezet ez eus ur fazi dianav e termenell stokañ ar restr \"$1\".",
        "uploadstash-errclear": "N'eus ket bet gallet riñsañ ar restroù.",
        "uploadstash-refresh": "Freskaat roll ar restroù",
        "uploadstash-thumbnail": "gwelet ar munud",
+       "uploadstash-exception": "Dibosupl stokañ an enporzhiadenn er sanailh ($1) : \"$2\".",
        "invalid-chunk-offset": "Direizh eo offset ar rannad",
        "img-auth-accessdenied": "Moned nac'het",
        "img-auth-nopathinfo": "Mankout a ra ar PATH_INFO.\nN'eo ket kefluniet ho servijer evit reiñ an titour-mañ.\nMarteze eo diazezet war CGI ha n'hall ket skorañ img_auth.\nGwelet https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization",
        "filerevert-submit": "Disteuler",
        "filerevert-success": "'''Distroet eo bet [[Media:$1|$1]]''' da [stumm $4 an $3, $2].",
        "filerevert-badversion": "N'eus stumm lec'hel kent ebet eus ar restr-mañ d'ar mare spisaet.",
+       "filerevert-identical": "Heñvel-mik eo stumm a-vremañ ar restr ouzh an hini zo bet diuzet.",
        "filedelete": "Diverkañ $1",
        "filedelete-legend": "Diverkañ ar restr",
        "filedelete-intro": "War-nes diverkañ '''[[Media:$1|$1]]''' a-gevret gant e istor emaoc'h.",
        "filedelete-maintenance": "Evit ar mare eo diweredekaet an diverkañ hag an assevel restroù, amzer d'ober un tamm trezalc'h.",
        "filedelete-maintenance-title": "Dibosupl diverkañ ar restr",
        "mimesearch": "Klask MIME",
-       "mimesearch-summary": "Aotren a ra ar bajenn-mañ ar silañ restroù evit ar seurt restroù MIME. Enmont : seurt/isseurt, evel <code>skeudenn/jpeg</code>.",
+       "mimesearch-summary": "Aotren a ra ar bajenn-mañ silañ restroù dre o seurt MIME. Enmont : seurt danvez/isseurt pe seurt danvez, evel <code>skeudenn/jpeg</code>.",
        "mimetype": "Seurt MIME :",
        "download": "pellgargañ",
        "unwatchedpages": "Pajennoù n'int ket evezhiet",
        "listredirects": "Roll an adkasoù",
        "listduplicatedfiles": "Roll restroù gant doublennoù",
+       "listduplicatedfiles-summary": "Hemañ zo ur roll restroù m'eo stumm diwezhañ ur restr un eilad eus stumm diwezhañ ur restr bennak all. Ne vez kemeret e kont nemet ar restroù lec'hel.",
+       "listduplicatedfiles-entry": "[[$3|{{PLURAL:$2|un doubl|$2 doubl}}]] en deus [[:File:$1|$1]].",
        "unusedtemplates": "Patromoù dizimplij",
        "unusedtemplatestext": "Rollet eo amañ an holl bajennoù zo en esaouenn anv \"{{ns:template}}\" ha n'int ket implijet war pajenn ebet. Ho pet soñj da wiriañ mat hag-eñ n'eus ket liammoù all war-du ar patromoù-se a-raok diverkañ anezho.",
        "unusedtemplateswlh": "liammoù all",
        "statistics-users-active-desc": "Implijerien o deus degaset da nebeutañ ur c'hemm {{PLURAL:$1|an deiz paseet|e-kerzh an $1 deiz diwezhañ}}",
        "pageswithprop": "Pajennoù gant ur perzh pajenn",
        "pageswithprop-legend": "Pajennoù gant ur perzh pajenn",
+       "pageswithprop-text": "Rollañ a ra ar bajenn-mañ ar pajennoù a ra gant ur perzh pajenn dibar",
        "pageswithprop-prop": "Anv ar perzh :",
        "pageswithprop-submit": "Mont",
        "pageswithprop-prophidden-long": "talvoud perzh testenn hir kuzhet ($1)",
        "uncategorizedcategories": "Rummadoù dirumm",
        "uncategorizedimages": "Restroù hep rummad",
        "uncategorizedtemplates": "Patromoù hep rummad",
+       "uncategorized-categories-exceptionlist": " # Ur roll rummadoù zo ennañ na zlefent ket bezañ meneget war Special:UncategorizedCategories. Unan dre linenn, en ur gregiñ gant \"*\". Ne vez ket kemeret e kont al linennoù a grog gant un arouezenn all (zoken gant esaouennoù c'houllo). Ober gant \"#\" evit ouzhpennañ evezhiadennoù.",
        "unusedcategories": "Rummadoù dizimplij",
        "unusedimages": "Skeudennoù en o-unan",
        "wantedcategories": "Rummadoù goulennet a vank",
        "wantedpages": "Pajennoù goulennet ar muiañ",
+       "wantedpages-summary": "Roll ar pajennoù a vank, gant ar muiañ a liammoù o kas war o zu, hep kontañ ar pajennoù n'eus nemet adkasoù o kas war o zu. Evit kaout roll ar pajennoù a vank gant adkasoù o kas war o zu, sellet ouzh [[{{#special:BrokenRedirects}}|roll an adkasoù a-dreuz]].",
        "wantedpages-badtitle": "Titl direizh er strollad disoc'hoù : $1",
        "wantedfiles": "Restroù a vank",
        "wantedfiletext-cat": "Ober a reer gant ar restroù da-heul koulskoude n'eus ket anezho. Gallout a reer rollañ kavlec'hioù diavaez ha pa vefe anezho. <del>Barrennet</del> e vo an holl falspozitivoù-se. Ouzhpenn-se emañ renablet an holl bajennoù zo enno restroù n'eus ket anezho e [[:$1]].",
        "deadendpagestext": "Ar pajennoù da-heul n'int ket liammet ouzh pajenn ebet all eus {{SITENAME}}.",
        "protectedpages": "Pajennoù gwarezet",
        "protectedpages-indef": "Gwarezoù da badout hepken",
+       "protectedpages-summary": "Rollañ a ra ar bajenn-mañ ar pajennoù zo gwarezet evit ar mare. Evit kaout roll ar pajennoù n'haller ket krouiñ, sellet ouzh [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Gwarez dre skalierad hepken",
        "protectedpages-noredirect": "Kuzhat an adkasoù",
        "protectedpagesempty": "N'eus pajenn gwarezet ebet gant an arventennoù-mañ evit poent.",
        "protectedpages-unknown-timestamp": "Dianav",
        "protectedpages-unknown-performer": "Implijer dianav",
        "protectedtitles": "Titloù gwarezet",
+       "protectedtitles-summary": "Rollañ a ra ar bajenn-mañ an titloù n'haller ket implijout evit krouiñ pajennoù. Evit kaout roll ar pajennoù krouet gwarezet, sellet ouzh [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "N'eus bet gwarezet titl ebet dezhañ an arventennoù-se evit poent.",
        "protectedtitles-submit": "Diskwel an titloù",
        "listusers": "Roll an implijerien",
        "apihelp": "Skoazell an API",
        "apihelp-no-such-module": "N'eo ket bet kavet ar vodulenn \"$1\".",
        "apisandbox": "Poull-traezh API",
+       "apisandbox-jsonly": "Rekis eo JavaScript evit implijout poull-traezh an API.",
        "apisandbox-api-disabled": "Diweredekaet eo API war al lec'hienn-mañ.",
-       "apisandbox-intro": "Grit gant ar bajenn-mañ evit amprouiñ '''servij Web API MediaWiki'''.\nKit da deuler ur sell war [https://www.mediawiki.org/wiki/API:Main_page titouroù an API] evit gouzout hiroc'h war an doare da embreger API. Da skouer :\n[https://www.mediawiki.org/wiki/API#A_simple_example gwelet danvez ur bennbajenn]. Dibabit un oberiadenn bennak evit gwelet skouerioù all",
+       "apisandbox-intro": "Grit gant ar bajenn-mañ evit amprouiñ <strong>servij Web API MediaWiki</strong>.\nKit da deuler ur sell war [[mw:API:Main page|teuliadur API]] evit gouzout hiroc'h war an doare da embreger API. Da skouer :\n[https://www.mediawiki.org/wiki/API#A_simple_example gwelet danvez ur bajenn zegemer]. Dibabit un oberiadenn bennak evit gwelet skouerioù all.\n\nNotit mat : ha pa vefe ar bajenn-mañ ur poull-traezh, an oberiadennoù a rit amañ a c'hall kemmañ ar wiki.",
        "apisandbox-fullscreen": "Dispakañ ar banell",
+       "apisandbox-fullscreen-tooltip": "Brasaat panell ar poull-traezh evit leuniañ prenestr ar merdeer.",
        "apisandbox-unfullscreen": "Diskouez ar bajenn",
+       "apisandbox-unfullscreen-tooltip": "Bihanaat panell ar poull-traezh evit ma vefe hegerz liammoù merdeiñ MediaWiki.",
        "apisandbox-submit": "Sevel ar goulenn",
        "apisandbox-reset": "Riñsañ",
        "apisandbox-retry": "Klask en-dro",
+       "apisandbox-loading": "O kargañ titouroù modulenn \"$1\" an API...",
+       "apisandbox-load-error": "C'hoarvezet ez eus ur fazi en ur gargañ modulenn \"$1\" an API : $2",
+       "apisandbox-no-parameters": "N'eus arventenn ebet d'ar vodulenn API-mañ.",
        "apisandbox-helpurls": "Liammoù skoazell",
        "apisandbox-examples": "Skouerioù",
        "apisandbox-dynamic-parameters": "Arventenn ouzhpenn",
        "apisandbox-dynamic-parameters-add-label": "Ouzhpennañ un arventenn:",
        "apisandbox-dynamic-parameters-add-placeholder": "Anv an arventenn",
+       "apisandbox-dynamic-error-exists": "Bez' ez eus c'hoazh eus un arventenn anvet \"$1\".",
+       "apisandbox-deprecated-parameters": "Arventennoù dispredet",
+       "apisandbox-fetch-token": "Leuniañ emgefre ar jedouer",
+       "apisandbox-submit-invalid-fields-title": "Direizh eo maeziennoù zo",
+       "apisandbox-submit-invalid-fields-message": "Reizhit ar maeziennoù merket ha klaskit en-dro.",
        "apisandbox-results": "Disoc'hoù",
+       "apisandbox-sending-request": "O kas ur reked API...",
+       "apisandbox-loading-results": "O resev ur reked API...",
+       "apisandbox-results-error": "C'hoarvezet ez eus ur fazi en ur gargañ respont ar reked API : $1.",
+       "apisandbox-request-selectformat-label": "Diskouez roadennoù ar reked evel :",
+       "apisandbox-request-format-url-label": "Neudennad reked an URL",
        "apisandbox-request-url-label": "Goulenn URL :",
-       "apisandbox-request-time": "Pad ar goulenn: $1",
+       "apisandbox-request-json-label": "Goulenn JSON :",
+       "apisandbox-request-time": "Pad ar goulenn : {{PLURAL:$1|$1 ms}}",
+       "apisandbox-results-fixtoken": "Reizhañ ar jedouer ha kas en-dro",
+       "apisandbox-results-fixtoken-fail": "N'eus ket bet gallet adtapout ar jedouer \"$1\".",
+       "apisandbox-alert-page": "Direizh eo maeziennoù ar bajenn-mañ.",
        "apisandbox-alert-field": "Talvoud ar vaezienn-mañ n'eo ket reizh.",
        "apisandbox-continue": "Kenderc'hel",
        "apisandbox-continue-clear": "Riñsañ",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} a [https://www.mediawiki.org/wiki/API:Query#Continuing_queries gendalc'ho] ar reked diwezhañ ; {{int:apisandbox-continue-clear}} a ziverko an arventennoù a denn d'ar c'hendalc'h.",
+       "apisandbox-param-limit": "Merkañ <kbd>max</kbd> evit ober gant ar vevenn vrasañ.",
        "apisandbox-multivalue-all-namespaces": "$1 (An holl esaouennoù anv)",
        "apisandbox-multivalue-all-values": "$1 (An holl dalvoudoù)",
        "booksources": "Oberennoù dave",
        "booksources-search": "Klask",
        "booksources-text": "Ur roll liammoù a gas da lec'hiennoù all ma werzher levrioù kozh ha nevez a gavot a-is; marteze e kavot eno titouroù pelloc'h war al levrioù a glaskit :",
        "booksources-invalid-isbn": "Evit doare n'eo ket reizh an ISBN merket; gwiriit ha n'oc'h ket faziet en ur eilañ adal ar vammenn orin.",
+       "magiclink-tracking-rfc": "Pajennoù a ra gant liammoù hud RFC",
+       "magiclink-tracking-rfc-desc": "Ober a ra ar bajenn-mañ gant liammoù hud RFC. Gwelet [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] evit an doare da dreuzlec'hiañ.",
+       "magiclink-tracking-pmid": "Pajennoù a ra gant liammoù hud PMID",
+       "magiclink-tracking-pmid-desc": "Ober a ra ar bajenn-mañ gant liammoù hud PMID. Gwelet [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] evit an doare da dreuzlec'hiañ.",
        "magiclink-tracking-isbn": "Pajennoù a ra gant liammoù burzhudus ISBN",
+       "magiclink-tracking-isbn-desc": "Ober a ra ar bajenn-mañ gant liammoù hud ISBN. Gwelet [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] evit an doare da dreuzlec'hiañ.",
        "specialloguserlabel": "Implijer :",
-       "speciallogtitlelabel": "Bukadenn (titl pe implijer) :",
+       "speciallogtitlelabel": "Pal (titl pe {{ns:user}}:anv implijer) :",
        "log": "Marilhoù",
        "logeventslist-submit": "Diskouez",
        "all-logs-page": "An holl varilhoù foran",
        "logempty": "Goullo eo istor ar bajenn-mañ.",
        "log-title-wildcard": "Klask an titloù a grog gant an destenn-mañ",
        "showhideselectedlogentries": "Diskouez/kuzhat penngerioù ar marilh bet diuzet",
+       "log-edit-tags": "Kemmañ tikedennoù an enmontoù marilh diuzet",
        "checkbox-select": "Diuzañ : $1",
        "checkbox-all": "An holl",
        "checkbox-none": "Hini ebet",
        "activeusers-intro": "Setu aze ur roll eus an implijerien zo bet oberiant mui pe vui e-pad an $1 {{PLURAL:$1|deiz|deiz}} diwezhañ.",
        "activeusers-count": "$1 {{PLURAL:$1|oberiadenn}} abaoe an {{PLURAL:$3|deiz|$3 deiz}} diwezhañ",
        "activeusers-from": "Diskouez an implijerien adal :",
+       "activeusers-groups": "Diskouez an implijerien zo ezel eus ar strolladoù :",
+       "activeusers-excludegroups": "Skarzhañ an implijerien ezel eus ar strolladoù :",
        "activeusers-noresult": "N'eus bet kavet implijer ebet.",
        "activeusers-submit": "Diskouez an implijerien oberiant",
        "listgrouprights": "Gwirioù ar strolladoù implijer",
        "listgrouprights-removegroup-self": "Gallout a ra tennañ {{PLURAL:$2|ar strollad|strolladoù}} eus kont an-unan : $1",
        "listgrouprights-addgroup-self-all": "Gallout a ra ouzhpennañ an holl strolladoù da gont an-unan",
        "listgrouprights-removegroup-self-all": "Gallout a ra tennañ kuit an holl strolladoù eus kont an-unan.",
+       "listgrouprights-namespaceprotection-header": "Strishadurioù esaouennoù anv",
        "listgrouprights-namespaceprotection-namespace": "Esaouenn anv",
        "listgrouprights-namespaceprotection-restrictedto": "Gwir(ioù) hag a aotre an implijer da aozañ",
        "listgrants": "Aotreoù",
        "trackingcategories-msg": "Rummad evezhiañ",
        "trackingcategories-name": "Anv ar gemennadenn",
        "trackingcategories-desc": "Dezverkoù evit degemer rummadoù",
+       "restricted-displaytitle-ignored": "Pajennoù gant titloù diskwel lezet a-gostez",
+       "restricted-displaytitle-ignored-desc": "Ar bajenn-mañ zo dezhi un <code><nowiki>{{DISPLAYTITLE}}</nowiki></code> zo bet laosket a-gostez peogwir n'eo ket kevatal d'an titl zo d'ar bajenn bremañ.",
+       "noindex-category-desc": "Ar bajenn-mañ n'eo ket menegeret gant ar robotoù rak ar ger hud <code><nowiki>__NOINDEX__</nowiki></code> zo enni hag emañ en un esaouenn anv m'eo aotreet ar merkañ.",
        "broken-file-category-desc": "Er bajenn-mañ ez eus ul liamm restr torr (ul liamm da enframmañ ur restr pa n'eus ket eus ar restr-se).",
        "trackingcategories-nodesc": "N'eus deskrivadur ebet.",
        "trackingcategories-disabled": "Diweredekaet eo ar rummad",
        "rollbacklinkcount": "disteurel $1 {{PLURAL:$1|kemm}}",
        "rollbacklinkcount-morethan": "disteurel ouzhpenn $1 {{PLURAL:$1|kemm}}",
        "rollbackfailed": "C'hwitet eo bet an distaoladenn",
+       "rollback-missingparam": "Arventennoù rekis d'ar reked a vank.",
+       "rollback-missingrevision": "Dibosupl kargañ roadennoù ar stumm.",
        "cantrollback": "Dibosupl da zisteuler: an aozer diwezhañ eo an hini nemetañ da vezañ kemmet ar pennad-mañ",
        "alreadyrolled": "Dibosupl eo disteuler ar c'hemm diwezhañ graet d'ar bajenn [[:$1]] gant [[User:$2|$2]] ([[User talk:$2|Kaozeal]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);\nkemmet pe distaolet eo bet c'hoazh gant unan bennak all.\n\nAr c'hemm diwezhañ d'ar bajenn-mañ a oa bet graet gant [[User:$3|$3]] ([[User talk:$3|Kaozeal]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Diverradenn ar c'hemm a oa : <em>$1</em>.",
        "rollback-success": "Disteuler kemmoù $1; distreiñ da stumm diwezhañ $2.",
        "sessionfailure-title": "Fazi dalc'h",
        "sessionfailure": "Evit doare ez eus ur gudenn gant ho talc'h;\nNullet eo bet an ober-mañ a-benn en em wareziñ diouzh an tagadennoù preizhañ.\nKlikit war \"kent\" hag adkargit ar bajenn oc'h deuet drezi; goude klaskit en-dro.",
+       "changecontentmodel": "Cheñch patrom danvez ur bajenn",
+       "changecontentmodel-legend": "Cheñch ar patrom danvez",
        "changecontentmodel-title-label": "Anv ar bajenn",
+       "changecontentmodel-model-label": "Patrom danvez nevez",
        "changecontentmodel-reason-label": "Abeg :",
        "changecontentmodel-submit": "Kemmañ",
+       "changecontentmodel-success-title": "Cheñchet eo bet ar patrom danvez",
+       "changecontentmodel-success-text": "Kemmet eo bet patrom danvez [[:$1]].",
+       "changecontentmodel-cannot-convert": "N'hall ket danvez [[:$1]] bezañ troet en ur seurt $2.",
+       "changecontentmodel-emptymodels-title": "N'eus patrom danvez hegerz ebet",
        "logentry-contentmodel-change-revertlink": "disteuler",
        "logentry-contentmodel-change-revert": "disteuler",
        "protectlogpage": "Log_gwareziñ",
        "block-log-flags-hiddenname": "anv implijer kuzhet",
        "range_block_disabled": "Diweredekaet eo bet ar stankañ stuc'hadoù IP.",
        "ipb_expiry_invalid": "amzer termen direizh.",
+       "ipb_expiry_old": "Tremenet eo an termen echuiñ.",
        "ipb_expiry_temp": "Peurbadus e rank bezañ bloc'hadoù an implijerien guzh.",
        "ipb_hide_invalid": "Ne c'haller ket dilemel ar gont-mañ : Ouzhpenn {{PLURAL:$1|ur c'hemm|$1 kemm}} zo enni.",
        "ipb_already_blocked": "Stanket eo \"$1\" dija",
        "thumbnail-temp-create": "Dibosupl krouiñ ur restr vunut padennek",
        "thumbnail-dest-create": "Dibosupl enrollañ ar munud.",
        "thumbnail_invalid_params": "Arventennoù direizh evit ar munud",
+       "thumbnail_toobigimagearea": "Restr brasoc'h e ventoù eget $1",
        "thumbnail_dest_directory": "Dibosupl krouiñ ar c'havlec'h pal",
        "thumbnail_image-type": "N'eo ket skoret ar seurt skeudennoù",
        "thumbnail_gd-library": "Kefluniadur diglok al levraoueg GD : dibosupl kavout an arc'hwel $1",
        "import-interwiki-history": "Eilañ holl stummoù istor ar bajenn-mañ",
        "import-interwiki-templates": "Lakaat e-barzh an holl batromoù",
        "import-interwiki-submit": "Enporzhiañ",
+       "import-mapping-default": "Enporzhiañ d'al lec'hiadurioù dre ziouer",
+       "import-mapping-namespace": "Enporzhiañ d'un esaouenn anv :",
        "import-upload-filename": "Anv ar restr :",
        "import-comment": "Notenn :",
        "importtext": "Ezporzhiit ar restr adal ar wiki orin en ur ober gant an arc'hwel [[Special:Export|ezporzhiañ]].\nEnrollit ar bajenn war hoc'h urzhiataer ha kargit anezhi amañ.",
        "patrol-log-page": "Log gwiriañ",
        "patrol-log-header": "Setu ur marilh eus ar stummoù patrouilhet.",
        "log-show-hide-patrol": "$1 istor ar stummoù gwiriet",
+       "log-show-hide-tag": "$1 marilh an dikedenn",
        "confirm-markpatrolled-button": "Mat eo",
        "deletedrevision": "Diverket stumm kozh $1.",
        "filedeleteerror-short": "Fazi e-ser diverkañ ar restr : $1",
        "tag-filter": "Silañ an [[Special:Tags|tikedennoù]] :",
        "tag-filter-submit": "Silañ",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Dikedenn|Tikedenn}}]] : $2)",
+       "tag-mw-contentmodelchange": "cheñch ar patrom danvez",
        "tags-title": "Tikedennoù",
        "tags-intro": "Rollañ a ra ar bajenn-mañ an tikedennoù a c'hall ar meziant implijout da verkañ kemmoù hag o zalvoudegezh.",
        "tags-tag": "Anv an dikedenn",
        "tags-activate": "gweredekaat",
        "tags-deactivate": "diweredekaat",
        "tags-hitcount": "$1 {{PLURAL:$1|kemm|kemm}}",
+       "tags-manage-no-permission": "N'oc'h ket aotreet da verañ ar c'hemmañ tikedennoù.",
+       "tags-manage-blocked": "N'hallit ket merañ ar c'hemmañ tikedennoù e-keit hag {{GENDER:$1|emaoc'h}} stanket.",
        "tags-create-heading": "Krouiñ un dikedenn nevez",
        "tags-create-tag-name": "Anv an dikedenn :",
        "tags-create-reason": "Abeg :",
        "tags-create-submit": "Krouiñ",
        "tags-create-no-name": "Rekis eo merkañ anv un dikedenn.",
+       "tags-create-already-exists": "Bez' ez eus eus an tikedenn \"$1\" c'hoazh.",
+       "tags-create-warnings-below": "Kenderc'hel da grouiñ an dikedenn a fell deoc'h ?",
        "tags-delete-title": "Diverkañ an dikedenn",
        "tags-delete-reason": "Abeg :",
        "tags-delete-not-found": "N'eus ket eus an dikedenn \"$1\".",
index a58366f..3bef8c9 100644 (file)
        "thursday": "četvrtak",
        "friday": "petak",
        "saturday": "subota",
-       "sun": "Ned",
-       "mon": "Pon",
-       "tue": "Uto",
-       "wed": "Sri",
-       "thu": "Ä\8cet",
-       "fri": "Pet",
-       "sat": "Sub",
+       "sun": "ned",
+       "mon": "pon",
+       "tue": "uto",
+       "wed": "sri",
+       "thu": "Ä\8det",
+       "fri": "pet",
+       "sat": "sub",
        "january": "januar",
        "february": "februar",
        "march": "mart",
        "anontalk": "Razgovor",
        "navigation": "Navigacija",
        "and": "&#32;i",
-       "qbfind": "Pronađite",
+       "qbfind": "Pronađi",
        "qbbrowse": "Potraži",
        "qbedit": "Uredi",
        "qbpageoptions": "Opcije stranice",
        "viewdeleted_short": "Pogledaj {{PLURAL:$1|jednu obrisanu izmjenu|$1 obrisane izmjene|$1 obrisanih izmjena}}",
        "protect": "Zaštiti",
        "protect_change": "promijeni",
-       "protectthispage": "Zaštitite ovu stranicu",
+       "protectthispage": "Zaštiti ovu stranicu",
        "unprotect": "Promijeni zaštitu",
        "unprotectthispage": "Promijeni zaštitu ove stranice",
        "newpage": "Nova stranica",
        "tool-link-emailuser": "Pošalji e-poruku {{GENDER:$1|korisniku|korisnici}}",
        "userpage": "Pogledaj korisničku stranicu",
        "projectpage": "Pogledaj stranicu projekta",
-       "imagepage": "Pogledajte stranicu datoteke",
+       "imagepage": "Pogledaj stranicu datoteke",
        "mediawikipage": "Pogledaj stranicu sa porukama",
-       "templatepage": "Pogledajte stranicu za šablone",
+       "templatepage": "Pogledaj stranicu za šablone",
        "viewhelppage": "Pogledajte stranicu za pomoć",
        "categorypage": "Pogledaj stranicu kategorije",
        "viewtalkpage": "Pogledaj razgovor",
        "redirectedfrom": "(Preusmjereno sa $1)",
        "redirectpagesub": "Preusmjerenje",
        "redirectto": "Preusmjerenje na:",
-       "lastmodifiedat": "Ova stranica je posljednji put izmijenjena u $2 na $1.",
+       "lastmodifiedat": "Ova stranica je posljednji put izmijenjena na dan $1 u $2.",
        "viewcount": "Ovoj stranici je pristupljeno {{PLURAL:$1|$1 put|$1 puta}}.",
        "protectedpage": "Zaštićena stranica",
        "jumpto": "Idi na:",
        "pool-servererror": "Usluga brojača poola nije dostupna ($1).",
        "poolcounter-usage-error": "Greška pri upotrebi: $1",
        "aboutsite": "O {{GRAMMAR:dativ|{{SITENAME}}}}",
-       "aboutpage": "Project:O_projektu_{{SITENAME}}",
+       "aboutpage": "Project:O {{GRAMMAR:dativ|{{SITENAME}}}}",
        "copyright": "Sadržaj je dostupan pod licencom $1 osim ako je navedeno drugačije.",
        "copyrightpage": "{{ns:project}}:Autorska_prava",
        "currentevents": "Novosti",
        "databaseerror-query": "Upit: $1",
        "databaseerror-function": "Funkcija: $1",
        "databaseerror-error": "Greška: $1",
-       "laggedslavemode": "'''Upozorenje''': Stranica, možda, nije ažurirana.",
+       "laggedslavemode": "<strong>Upozorenje:</strong> Moguće je da stranica nije ažurirana.",
        "readonly": "Baza je zaključana",
        "enterlockreason": "Unesite razlog za zaključavanje, uključujući procjenu vremena otključavanja",
        "readonlytext": "Baza podataka trenutno je zaključana za nove unose i druge izmjene, vjerovatno zbog rutinskog održavanja, nakon čega će biti vraćena u uobičajeno stanje.\n\nSistemski administrator koji ju je zaključao naveo je sljedeće objašnjenje: $1",
        "internalerror": "Unutrašnja greška",
        "internalerror_info": "Interna greška: $1",
        "internalerror-fatal-exception": "Fatalna greška tipa \"$1\"",
-       "filecopyerror": "Ne može se kopirati \"$1\" na \"$2\".",
-       "filerenameerror": "Ne može se promjeniti ime datoteke \"$1\" u \"$2\".",
+       "filecopyerror": "Ne mogu kopirati datoteku \"$1\" na \"$2\".",
+       "filerenameerror": "Ne mogu preimenovati datoteku \"$1\" u \"$2\".",
        "filedeleteerror": "Ne mogu obrisati datoteku \"$1\".",
        "directorycreateerror": "Nije moguće napraviti direktorijum \"$1\".",
        "directoryreadonlyerror": "Direktorij \"$1\" je samo za čitanje.",
        "directorynotreadableerror": "Direktorij \"$1\" nije čitljiv.",
-       "filenotfound": "Ne može se naći datoteka \"$1\".",
+       "filenotfound": "Ne mogu pronaći datoteku \"$1\".",
        "unexpected": "Neočekivana vrijednost: \"$1\"=\"$2\".",
-       "formerror": "Greška: ne može se poslati upitnik",
-       "badarticleerror": "Ova akcija ne može biti izvršena na ovoj stranici.",
-       "cannotdelete": "Ne može se obrisati stranica ili datoteka \"$1\".\nMoguće je da ju je neko već obrisao.",
+       "formerror": "Greška: ne mogu poslati upitnik.",
+       "badarticleerror": "Ova radnja se ne može izvršiti na ovoj stranici.",
+       "cannotdelete": "Ne mogu obrisati stranicu ili datoteku \"$1\".\nMoguće je da ju je neko već obrisao.",
        "cannotdelete-title": "Ne mogu obrisati stranicu \"$1\"",
        "delete-hook-aborted": "Brisanje je prekinuo softverski priključak.\nNije ponuđeno nikakvo objašnjenje.",
        "no-null-revision": "Ne mogu napraviti novu ništavnu reviziju za stranicu \"$1\"",
        "login": "Prijavi me",
        "login-security": "Potvrdite svoj identitet",
        "nav-login-createaccount": "Prijavi se / Registruj se",
-       "userlogin": "Prijavi se / Registruj se",
+       "userlogin": "Prijavi se / napravi račun",
        "userloginnocreate": "Prijavi se",
        "logout": "Odjavi me",
        "userlogout": "Odjavi me",
        "userexists": "Korisničko ime je već u upotrebi.\nIzaberite drugo.",
        "loginerror": "Greška pri prijavljivanju",
        "createacct-error": "Došlo je do greške pri otvaranju naloga",
-       "createaccounterror": "Ne može se napraviti račun: $1",
-       "nocookiesnew": "Korisnički nalog je napravljen, ali niste prijavljeni.\n{{SITENAME}} koristi kolačiće (cookies) da bi se korisnici prijavili.\nVi ste isključili kolačiće na Vašem računaru.\nMolimo Vas da ih uključite, a onda se prijavite sa svojim novim korisničkim imenom i lozinkom.",
-       "nocookieslogin": "{{SITENAME}} koristi kolačiće (''cookies'') da bi se korisnici prijavili.  Vi ste onemogućili kolačiće na Vašem kompjuteru.  Molimo Vas da ih omogućite i da pokušate ponovo sa prijavom.",
+       "createaccounterror": "Ne mogu napraviti račun: $1",
+       "nocookiesnew": "Korisnički račun je napravljen, ali niste prijavljeni.\n{{SITENAME}} koristi kolačiće (cookies) za prijavu korisnika.\nVama su kolačići onemogućeni.\nOmogućite ih pa se onda prijavite s novim korisničkim imenom i lozinkom.",
+       "nocookieslogin": "{{SITENAME}} koristi kolačiće (''cookies'') za prijavu korisnika.\nVama su kolačići onemogućeni.\nOmogućite ih i pokušajte ponovo.",
        "nocookiesfornew": "Korisnički račun nije napravljen, jer nismo mogli da potvrdimo njegov izvor.\nProvjerite da li su cookies omogućeni, ponovo učitajte ovu stranicu i pokušajte ponovo.",
        "createacct-loginerror": "Račun je uspješno napravljen, ali Vas nije bilo moguće automatski prijaviti. Prijavite se [[Special:UserLogin|ručno]].",
        "noname": "Niste izabrali ispravno korisničko ime.",
-       "loginsuccesstitle": "Prijavljen",
+       "loginsuccesstitle": "Prijava uspješna",
        "loginsuccess": "<strong>Prijavili ste se na {{GRAMMAR:akuzativ|{{SITENAME}}}} kao \"$1\".</strong>",
        "nosuchuser": "Ne postoji korisnik s imenom \"$1\".\nKorisnička imena razlikuju velika i mala slova.\nProvjerite jeste li ga tačno upisali ili [[Special:CreateAccount|otvorite novi račun]].",
        "nosuchusershort": "Ne postoji korisnik s imenom \"$1\".\nProvjerite jeste li dobro ukucali.",
        "nouserspecified": "Morate izabrati korisničko ime.",
        "login-userblocked": "Ovaj korisnik je blokiran. Prijava nije dopuštena.",
        "wrongpassword": "Lozinka koju ste unijeli je netačna.\nPokušate ponovno.",
-       "wrongpasswordempty": "Lozinka koju ste unijeli je bila prazna.\nMolimo Vas da pokušate ponovno.",
+       "wrongpasswordempty": "Niste upisali lozinku.\nPokušajte ponovo.",
        "passwordtooshort": "Lozinka mora imati najmanje {{PLURAL:$1|1 znak|$1 znaka|$1 znakova}}.",
        "passwordtoolong": "Lozinke ne mogu biti duže od {{PLURAL:$1|jednog znaka|$1 znaka|$1 znakova}}.",
        "passwordtoopopular": "Ovo je često korištena lozinka i ne može se koristiti. Molimo Vas da izaberete jaču lozinku.",
        "emailauthenticated": "Vaša adresa e-pošte potvrđena je $2 u $3.",
        "emailnotauthenticated": "Vaša adresa e-pošte još nije potvrđena.\nNijedna e-poruka neće biti poslana za bilo koju uslugu od sljedećih.",
        "noemailprefs": "Unesite e-mail adresu za osposobljavanje slijedećih usluga.",
-       "emailconfirmlink": "Potvrdite Vašu e-mail adresu",
+       "emailconfirmlink": "Potvrdite svoju adresu e-pošte",
        "invalidemailaddress": "Ova e-mail adresa ne može biti prihvaćena jer je u neodgovarajućem obliku.\nMolimo vas da unesete ispravnu adresu ili ostavite prazno polje.",
        "cannotchangeemail": "Na ovom wikiju ne možete promijeniti e-mail adresu računa.",
        "emaildisabled": "Ova web-stranica ne može da šalje e-poruke.",
        "headline_sample": "Naslov",
        "headline_tip": "Podnaslov",
        "nowiki_sample": "Dodaj neformatirani tekst ovdje",
-       "nowiki_tip": "Ignoriši viki formatiranje teksta",
+       "nowiki_tip": "Zanemari wikiformatiranje",
        "image_sample": "ime_slike.jpg",
        "image_tip": "Uklopljena slika",
        "media_sample": "ime_medija_fajla.ogg",
        "media_tip": "Putanja ka multimedijalnoj datoteci",
-       "sig_tip": "Vaš potpis sa trenutnim vremenom",
+       "sig_tip": "Vaš potpis s trenutnim vremenom",
        "hr_tip": "Horizontalna linija (koristite oskudno)",
        "summary": "Sažetak:",
        "subject": "Tema:",
        "blankarticle": "<strong>Upozorenje:</strong> Napravili ste praznu stranicu.\nAko ponovno kliknete \"{{int:savearticle}}\", napravit ćete praznu stranicu bez sadržaja.",
        "anoneditwarning": "<strong>Upozorenje:</strong> Niste prijavljeni. \nVaša IP adresa će biti javno vidljiva ako napravite neku izmjenu. Ako se <strong>[$1 prijavite]</strong> ili <strong>[$2 napravite račun]</strong>, vaše izmjene će biti pripisane vašem korisničkom imenu, zajedno sa drugim pogodnostima.",
        "anonpreviewwarning": "''Niste prijavljeni. Nakon spremanja izmjena vaša IP adresa će biti zapisana u historiji uređivanja ove stranice.''",
-       "missingsummary": "'''Napomena:''' Niste unijeli sažetak izmjene.\nAko kliknete na Sačuvaj, Vaša izmjena će biti sačuvana bez sažetka.",
+       "missingsummary": "<strong>Napomena:</strong> Niste unijeli sažetak izmjene.\nAko ponovo kliknete na \"{{int:savearticle}}\", Vaša izmjena će biti sačuvana bez sažetka.",
        "selfredirect": "<strong>Upozorenje:</strong> Preusmjerili ste stranicu na samu sebe.\nMožda ste naveli pogrešan cilj preusmjeravanja ili ste uređivali pogrešnu stranicu.\nAko ponovno kliknete \"{{int:savearticle}}\", ipak će nastati preusmjerenje.",
-       "missingcommenttext": "Molimo unesite komentar ispod.",
+       "missingcommenttext": "Unesite komentar ispod.",
        "missingcommentheader": "<strong>Podsjetnik:</strong> Niste napisali temu za ovaj komentar.\nAko ponovo kliknete na \"{{int:savearticle}}\", vaša izmjena će biti sačuvana bez teme/naslova.",
        "summary-preview": "Pregled sažetka:",
        "subject-preview": "Pregled teme:",
        "autoblockedtext": "Vaša IP-adresa automatski je blokirana jer ju je koristio drugi korisnik, a blokirao ju je $1.\nNaveden je sljedeći razlog:\n\n:''$2''\n\n* Početak blokade: $8\n* Kraj blokade: $6\n* Blokirani korisnik: $7\n\nMožete kontaktirati sa $1 ili nekim drugim iz grupe [[{{MediaWiki:Grouppage-sysop}}|administratora]] i zahtijevati da Vas deblokira.\n\nZapamtite da ne možete koristiti opciju \"pošalji e-mail ovom korisniku\" sve dok ne unesete validnu e-mail adresu pri registraciji u Vašim [[Special:Preferences|korisničkim postavkama]] i dok niste spriječeni (blokadom) da je koristite.\n\nVaša trenutna IP-adresa je $3, a ID blokade je $5.\nMolimo da navedete sve gore navedene detalje u zahtjevu za deblokadu.",
        "blockednoreason": "razlog nije naveden",
        "whitelistedittext": "Morate biti $1 da biste uređivali stranice.",
-       "confirmedittext": "Morate potvrditi Vašu e-mail adresu prije nego počnete mijenjati stranice.\nMolimo da postavite i verifikujete Vašu e-mail adresu putem Vaših [[Special:Preferences|korisničkih opcija]].",
+       "confirmedittext": "Morate potvrditi svoju adresu e-pošte prije nego počnete mijenjati stranice.\nPostavite i potvrdite svoju adresu e-pošte u [[Special:Preferences|korisničkim postavkama]].",
        "nosuchsectiontitle": "Ne mogu pronaći sekciju",
        "nosuchsectiontext": "Pokušali ste uređivati sekciju koja ne postoji.\nMožda je premještena ili obrisana dok ste pregledavali stranicu.",
        "loginreqtitle": "Potrebna je prijava",
        "loginreqlink": "prijavljeni",
        "loginreqpagetext": "Morate biti $1 da biste vidjeli druge stranice.",
        "accmailtitle": "Šifra poslana.",
-       "accmailtext": "Nasumično odabrana šifra za [[User talk:$1|$1]] je poslata na adresu $2.\n\nŠifra/lozinka za ovaj novi račun može biti promijenjena na stranici ''[[Special:ChangePassword|izmjene šifre]]'' nakon prijave.",
+       "accmailtext": "Nasumično odabrana lozinka za [[User talk:$1|$1]] poslana je na $2. Lozinka se <em>[[Special:ChangePassword|može promijeniti]]</em> nakon prijave.",
        "newarticle": "(Novi)",
        "newarticletext": "Došli ste na stranicu koja još nema sadržaja.\n*Ako želite unijeti sadržaj, počnite tipkati u prozor ispod ovog teksta.\n*Ako Vam treba pomoć, idite na [$1 stranicu za pomoć].\n*Ako ste ovamo dospjeli slučajno, kliknite na dugme \"Nazad\" (''Back'') u Vašem internetskom pregledniku.",
        "anontalkpagetext": "----\n<em>Ovo je stranica za razgovor s anonimnim korisnikom koji još nije napravio račun ili ga ne koristi.</em>\nZbog toga moramo koristiti brojčanu IP-adresu kako bismo ga prepoznali.\nTakvu adresu može dijeliti više korisnika.\nAko ste anonimni korisnik i smatrate da su Vam upućene nebitne primjedbe, molimo Vas da [[Special:CreateAccount|napravite račun]] ili se [[Special:UserLogin|prijavite]] da biste izbjegli buduću zabunu s ostalim anonimnim korisnicima.",
        "clearyourcache": "<strong>Napomena:</strong> Nakon što sačuvate izmjene, možda ćete morati osvježiti keš preglednika da biste vidjeli izmjene.\n* <strong>Firefox / Safari:</strong> Držite <em>Shift</em> i kliknite na <em>Reload</em> ili pritisnite <em>Ctrl-F5</em> ili <em>Ctrl-R</em> (<em>⌘-R</em> na Macu)\n* <strong>Google Chrome:</strong> Pritisnite <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> na Macu)\n* <strong>Internet Explorer:</strong> Držite <em>Ctrl</em> i kliknite na <em>Refresh</em> ili pritisnite <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Idite na <em>Menu → Settings</em> (<em>Opera → Preferences</em> na Macu) i zatim <em>Privacy & security → Clear browsing data → Cached images and files</em>.",
        "usercssyoucanpreview": "'''Pažnja:''' Koristite dugme \"{{int:showpreview}}\" da testirate svoj novi CSS prije nego što sačuvate.",
        "userjsyoucanpreview": "'''Pažnja:''' Koristite dugme \"{{int:showpreview}}\" da testirate svoj novi JavaScript prije nego što sačuvate.",
-       "usercsspreview": "'''Zapamtite ovo je samo izgled Vašeg CSS-a.'''\n'''Ovaj pregled još uvijek nije sačuvan!'''",
-       "userjspreview": "'''Zapamtite ovo je samo izgled vaše JavaScript-e, još uvijek nije sačuvan!'''",
+       "usercsspreview": "<strong>Zapamtite da je ovo samo pregled Vašeg CSS-a.\nStranica još nije sačuvana!</strong>",
+       "userjspreview": "<strong>Zapamtite da je ovo samo pregled Vašeg JavaScripta.\nStranica još nije sačuvana!</strong>",
        "sitecsspreview": "'''Zapamtite ovo je samo izgled ovog CSS-a.'''\n'''Još uvijek nije sačuvan!'''",
        "sitejspreview": "'''Zapamtite ovo je samo izgled ovog koda JavaScripte.'''\n'''Još uvijek nije sačuvan!'''",
-       "userinvalidcssjstitle": "'''Upozorenje:''' Ne postoji interfejs pod imenom \"$1\".\nNe zaboravite da imena stranica s .css i .js kodom počinju malim slovom, npr, {{ns:user}}:Foo/vector.css, a ne {{ns:user}}:Foo/Vector.css.",
+       "userinvalidcssjstitle": "<strong>Upozorenje:</strong> Ne postoji tema \"$1\".\nNe zaboravite da imena stranica s .css i .js kodom počinju malim slovom, npr, {{ns:user}}:Foo/vector.css, a ne {{ns:user}}:Foo/Vector.css.",
        "updated": "(Osvježeno)",
        "note": "'''Pažnja:'''",
        "previewnote": "<strong>Ne zaboravite da je ovo samo pregled.</strong>\nVaše izmjene još nisu sačuvane!",
        "continue-editing": "Idi na područje uređivanja",
-       "previewconflict": "Ovaj pregled prikazuje kako će tekst u gornjem polju\nizgledati ako kliknete \"Sačuvaj članak\".",
+       "previewconflict": "Ovaj pregled prikazuje kako će tekst u gornjem polju izgledati ako odlučite sačuvati stranicu.",
        "session_fail_preview": "Izvinjavamo se! Nismo mogli obraditi Vašu izmjenu zbog gubitka podataka o prijavi.\n\nMožda ste odjavljeni. <strong>Provjerite jeste li prijavljeni i pokušajte ponovo</strong>.\nAko i dalje ne radi, pokušajte se [[Special:UserLogout|odjaviti]] i ponovo prijaviti i provjerite dozvoljava li Vaš preglednik kolačiće s ovog sajta.",
        "session_fail_preview_html": "'''Žao nam je! Nismo mogli da obradimo vašu izmjenu zbog gubitka podataka.'''\n\n''Zbog toga što {{SITENAME}} ima omogućen izvorni HTML, predpregled je sakriven kao predostrožnost protiv JavaScript napada.''\n\n'''Ako ste pokušali da napravite pravu izmjenu, molimo pokušajte ponovo. Ako i dalje ne radi, pokušajte da se [[Special:UserLogout|odjavite]] i ponovo prijavite.'''",
        "token_suffix_mismatch": "'''Vaša izmjena nije prihvaćena jer je Vaš web preglednik ubacio znakove interpunkcije u token uređivanja.\nIzmjena je odbačena da bi se spriječilo uništavanje teksta stranice.\nTo se događa ponekad kad korisite problematični anonimni proxy koji je baziran na web-u.'''",
        "editing": "Uređujete $1",
        "creating": "Pravljenje stranice $1",
        "editingsection": "Uređujete $1 (dio)",
-       "editingcomment": "Uređujete $1 (nova sekcija)",
+       "editingcomment": "Uređujete $1 (novi odlomak)",
        "editconflict": "Sukob izmjena: $1",
        "explainconflict": "Neko drugi je promijenio ovu stranicu otkad ste je Vi počeli mijenjati.\nGornje tekstualno polje sadrži tekst stranice koji trenutno postoji.\nVaše izmjene prikazane su u donjem tekstu.\nMorat ćete unijeti svoje promjene u postojeći tekst.\n'''Samo''' tekst u gornjem tekstualnom polju bit će sačuvan kad\nkliknete \"{{int:savearticle}}\".",
        "yourtext": "Vaš tekst",
        "nextrevision": "Novija izmjena →",
        "currentrevisionlink": "Trenutna verzija",
        "cur": "tren",
-       "next": "slijed",
+       "next": "sljed",
        "last": "preth",
        "page_first": "prva",
        "page_last": "posljednja",
        "historysize": "({{PLURAL:$1|1 bajt|$1 bajta|$1 bajtova}})",
        "historyempty": "(prazno)",
        "history-feed-title": "Historija izmjena",
-       "history-feed-description": "Historija promjena ove stranice na wikiju",
+       "history-feed-description": "Historija izmjena ove stranice na wikiju",
        "history-feed-item-nocomment": "$1 u $2",
        "history-feed-empty": "Tražena stranica ne postoji.\nMoguće da je obrisana s wikija ili je preimenovana.\nPokušajte [[Special:Search|pretražiti wiki]] za slične stranice.",
        "history-edit-tags": "Uredi oznake izabranih verzija",
        "prefs-watchlist-edits": "Najveći broj izmjena za prikaz u proširenom spisku praćenja:",
        "prefs-watchlist-edits-max": "Najveći broj: 1000",
        "prefs-watchlist-token": "Žeton praćenih članaka:",
-       "prefs-misc": "Ostala podešavanja",
+       "prefs-misc": "Razno",
        "prefs-resetpass": "Promijeni lozinku",
        "prefs-changeemail": "Promijeni ili ukloni adresu e-pošte",
        "prefs-setemail": "Postavite e-mail adresu",
        "gender-male": "On uređuje wiki stranice",
        "gender-female": "Ona uređuje wiki stranice",
        "prefs-help-gender": "Postavljanje ovih podešavanja nije obavezno.\nSoftver koristi ove vrijednosti za vaše naslovljanje i ispravke gramatičkog roda u porukama softvera. Ova će informacija biti javna.",
-       "email": "E-mail",
+       "email": "E-pošta",
        "prefs-help-realname": "Pravo ime nije obavezno.\nAko izaberete da date ime, biće korišteno za pripisivanje vašem radu.",
        "prefs-help-email": "Adresa e-pošte nije obavezna, ali je potrebna u slučaju ponovnog postavljanja šifre, ako je zaboravite.",
        "prefs-help-email-others": "Također možete dopustiti drugim korisnicima da vas kontaktiraju preko linka na lijevoj strani vaše stranice ili stranice za razgovor.\nVaša adresa e-pošte neće biti prikazana drugim korisnicima koji vas kontaktiraju.",
        "unknown-error": "Desila se nepoznata greška.",
        "tmp-create-error": "Nije moguće napraviti privremenu datoteku.",
        "tmp-write-error": "Greška pri pisanju privremene datoteke.",
-       "large-file": "Preporučeno je da datoteke nisu veće od $1;\nOva datoteka je velika $2.",
+       "large-file": "Preporučeno je da datoteke ne budu veće od $1;\nova datoteka je velika $2.",
        "largefileserver": "Ova datoteka je veća nego što je dozvoljeno u postavkama servera.",
        "emptyfile": "Datoteka koju ste poslali je prazna. Ovo je moguće zbog greške u imenu datoteke. Molimo Vas da provjerite da li stvarno želite da pošaljete ovu datoteku.",
        "windows-nonascii-filename": "Ova wiki ne podržava imena datoteka sa posebnim znacima.",
        "uploadwarning": "Upozorenje pri postavljanju",
        "uploadwarning-text": "Molimo izmijeniti opis datoteke ispod i pokušajte kasnije.",
        "savefile": "Sačuvaj datoteku",
-       "uploaddisabled": "Slanje fajlova je isključeno",
+       "uploaddisabled": "Postavljanje datoteka je onemogućeno.",
        "copyuploaddisabled": "Postavljanje putem URL nije omogućeno.",
        "uploaddisabledtext": "Postavljanje datoteka je onemogućeno.",
        "php-uploaddisabledtext": "Postavljanje datoteka preko PHP je onemogućeno. Molimo provjerite postavku file_uploads.",
        "withoutinterwiki-submit": "Prikaži",
        "fewestrevisions": "Stranice s najmanje izmjena",
        "nbytes": "$1 {{PLURAL:$1|bajt|bajta|bajtova}}",
-       "ncategories": "$1 {{PLURAL:$1|kategorija|kategorije}}",
+       "ncategories": "$1 {{PLURAL:$1|kategorija|kategorije|kategorija}}",
        "ninterwikis": "$1 {{PLURAL:$1|međujezična veza|međujezične veze}}",
-       "nlinks": "$1 {{PLURAL:$1|veza|veze}}",
-       "nmembers": "$1 {{PLURAL:$1|član|članova}}",
+       "nlinks": "$1 {{PLURAL:$1|linka|linka|linkova}}",
+       "nmembers": "$1 {{PLURAL:$1|član|člana|članova}}",
        "nmemberschanged": "$1 → $2 {{PLURAL:$2|član|člana|članova}}",
        "nrevisions": "$1 {{PLURAL:$1|verzija|verzije|verzija}}",
        "nimagelinks": "Koristi se na $1 {{PLURAL:$1|stranici|stranice|stranica}}",
        "wantedfiletext-nocat": "Sljedeće datoteke se koriste, ali ne postoje. Datoteke iz drugih baza mogu biti navedene iako postoje. Takve datoteke će biti <del>precrtane</del> sa spiska.",
        "wantedfiletext-nocat-noforeign": "Sljedeće datoteke se koriste, ali ne postoje.",
        "wantedtemplates": "Traženi šabloni",
-       "mostlinked": "Članci sa najviše linkova",
-       "mostlinkedcategories": "Kategorije sa najviše linkova",
+       "mostlinked": "Stranice s najviše linkova",
+       "mostlinkedcategories": "Kategorije s najviše linkova",
        "mostlinkedtemplates": "Najviše uključene stranice",
-       "mostcategories": "Članci sa najviše kategorija",
+       "mostcategories": "Stranice s najviše kategorija",
        "mostimages": "Datoteke s najviše veza",
        "mostinterwikis": "Stranice sa najviše međuwikija",
-       "mostrevisions": "Članci sa najviše izmjena",
+       "mostrevisions": "Stranice s najviše izmjena",
        "prefixindex": "Sve stranice s prefiksom",
        "prefixindex-namespace": "Sve stranice s predmetkom (imenski prostor $1)",
        "prefixindex-submit": "Prikaži",
        "shortpages": "Kratke stranice",
        "longpages": "Duge stranice",
        "deadendpages": "Stranice bez unutrašnjih linkova",
-       "deadendpagestext": "Slijedeće stranice nisu povezane s drugim stranicama na {{SITENAME}}.",
+       "deadendpagestext": "Sljedeće stranice nisu povezane s drugim stranicama na {{GRAMMAR:dativ|{{SITENAME}}}}.",
        "protectedpages": "Zaštićene stranice",
        "protectedpages-indef": "Samo neograničena zaštićenja",
        "protectedpages-summary": "Na ovoj stranici se nalazi spisak trenutno zaštićenih stranica. Za spisak zaštićenih naslova vidi [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "cachedspecial-refresh-now": "Pogledaj najnoviju.",
        "categories": "Kategorije",
        "categories-submit": "Prikaži",
-       "categoriespagetext": "{{PLURAL:$1|Slijedeća kategorija sadrži|Slijedeće kategorije sadrže}} stranice ili multimedijalne datoteke.\n[[Special:UnusedCategories|Nekorištene kategorije]] nisu prikazane ovdje.\nVidi također [[Special:WantedCategories|zatražene kategorije]].",
+       "categoriespagetext": "{{PLURAL:$1|Sljedeća kategorija sadrži|Sljedeće kategorije sadrže}} stranice ili multimedijalne datoteke.\n[[Special:UnusedCategories|Nekorištene kategorije]] nisu prikazane ovdje.\nTakođer pogledajte [[Special:WantedCategories|zatražene kategorije]].",
        "categoriesfrom": "Prikaži kategorije počev od:",
        "deletedcontributions": "Obrisani korisnički doprinosi",
        "deletedcontributions-title": "Obrisani doprinosi korisnika",
        "mywatchlist": "Spisak praćenja",
        "watchlistfor2": "Za $1 $2",
        "nowatchlist": "Nemate ništa na svom spisku praćenih članaka.",
-       "watchlistanontext": "Morate biti prijavljeni kako biste vidjeli ili uređivali svoj spisak praćenih članaka.",
+       "watchlistanontext": "Morate biti prijavljeni da biste vidjeli ili uređivali svoj spisak praćenih članaka.",
        "watchnologin": "Niste prijavljeni",
        "addwatch": "Dodaj na spisak praćenja",
        "addedwatchtext": "Stranica \"[[:$1]]\" i njena stranica za razgovor dodani su na Vaš [[Special:Watchlist|spisak praćenja]].",
        "removedwatchtext": "Stranica \"[[:$1]]\" i njena stranica za razgovor uklonjeni su s Vašeg [[Special:Watchlist|spiska praćenja]].",
        "removedwatchtext-talk": "\"[[:$1]]\" i njoj pridružena stranica uklonjene su s Vašeg [[Special:Watchlist|spiska praćenja]].",
        "removedwatchtext-short": "Stranica \"$1\" je uklonjena sa vašeg spiska praćenja.",
-       "watch": "Prati članak",
+       "watch": "Prati",
        "watchthispage": "Prati ovu stranicu",
        "unwatch": "Prestani pratiti",
        "unwatchthispage": "Prestani pratiti",
-       "notanarticle": "Nije članak",
+       "notanarticle": "Nije stranica sa sadržajem",
        "notvisiblerev": "Obrisana je posljednja izmjena drugog korisnika",
        "watchlist-details": "Imate {{PLURAL:$1|$1 stranica|$1 stranice|$1 stranica}} na Vašem spisku praćenja, ne računajući posebno stranice za razgovor.",
        "wlheader-enotif": "Uključeno je obavještenje e-poštom.",
        "wlheader-showupdated": "Stranice koje su izmijenjene otkad ste ih posljednji put posjetili prikazane su <strong>podebljanim slovima</strong>.",
-       "wlnote": "Ispod {{PLURAL:$1|je najskorija izmjena|su <strong>$1</strong> najskorije izmjene|<strong>$1</strong> najskorijih izmjena}} načinjenih {{PLURAL:$2|posljednjeg sata|u posljednjih <strong>$2</strong> sata|u posljednjih <strong>$2</strong> sati}}, od $3, $4.",
+       "wlnote": "Ispod {{PLURAL:$1|je posljednja izmjena|su <strong>$1</strong> posljednje izmjene|su <strong>$1</strong> posljednjih izmjena}} načinjenih {{PLURAL:$2|posljednjeg sata|u posljednjih <strong>$2</strong> sata|u posljednjih <strong>$2</strong> sati}}, od $3, $4.",
        "wlshowlast": "Prikaži posljednjih $1 sati $2 dana",
        "watchlist-hide": "Sakrij",
        "watchlist-submit": "Prikaži",
        "enotif_anon_editor": "anonimni korisnik $1",
        "enotif_body": "Poštovani $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nSažetak urednika: $PAGESUMMARY $PAGEMINOREDIT\n\nKontaktirajte urednika:\ne-pošta: $PAGEEDITOR_EMAIL\nwiki: $PAGEEDITOR_WIKI\n\nNeće biti drugih obavještenja u slučaju daljnjih izmjena osim ako prijavljeni ponovno posjetite stranicu. Također možete poništiti oznake obavijesti za sve praćene stranice koje imate na vašem spisku praćenja.\n\nVaš prijateljski {{SITENAME}} sistem obavještavanja\n\n--\nZa promjenu vaših postavki email obavijesti, posjetite\n{{canonicalurl:{{#special:Preferences}}}}\n\nZa promjenu postavki vašeg praćenja, posjetite\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nDa obrišete stranicu sa vašeg spiska praćenja, posjetite\n$UNWATCHURL\n\nPovratne informacije i daljnja pomoć:\n$HELPPAGE",
        "created": "napravljena",
-       "changed": "promijenjena",
+       "changed": "izmijenjena",
        "deletepage": "Obriši stranicu",
-       "confirm": "Potvrdite",
+       "confirm": "Potvrdi",
        "excontent": "sadržaj je bio: \"$1\"",
        "excontentauthor": "sadržaj je bio: \"$1\", a jedini urednik \"[[Special:Contributions/$2|$2]]\" ([[User talk:$2|razgovor]])",
        "exbeforeblank": "sadržaj prije brisanja je bio: \"$1\"",
        "undeletepagetext": "{{PLURAL:$1|Slijedeća $1 stranica je obrisana|Slijedeće $1 stranice su obrisane|Slijedećih $1 je obrisano}} ali su još uvijek u arhivi i mogu biti vraćene.\nArhiva moše biti periodično čišćena.",
        "undelete-fieldset-title": "Vraćanje izmjena",
        "undeleteextrahelp": "Da biste vratili cijelu historiju stranice, ostavite sve kućice neoznačene i kliknite na <strong><em>{{int:undeletebtn}}</em></strong>.\nDa biste vratili određene izmjene, označite ih i kliknite na <strong><em>{{int:undeletebtn}}</em></strong>.",
-       "undeleterevisions": "$1 {{PLURAL:$1|izmjena je obrisana|izmjena je obrisano}}",
+       "undeleterevisions": "$1 {{PLURAL:$1|izmjena je obrisana|izmjene su obrisane|izmjena je obrisano}}",
        "undeletehistory": "Ako vratite stranicu, sve će izmjene biti vraćene u njenu historiju.\nAko je u međuvremenu napravljena nova izmjena s istim nazivom, vraćene izmjene pojavit će se u njenoj ranijoj historiji.",
        "undeleterevdel": "Vraćanje neće biti izvršeno ako je rezultat toga djelomično brisanje posljednje izmjene.\nU takvim slučajevima morate isključiti ili otkriti najnoviju obrisanu izmjenu.",
        "undeletehistorynoadmin": "Ova stranica je obrisana.\nRazlog za brisanje se nalazi ispod, zajedno s detaljima o korisniku koji je mijenjao stranicu prije brisanja.\nTekst obrisanih verzija dostupan je samo administratorima.",
        "anoncontribs": "Doprinosi",
        "contribsub2": "Za {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Korisnički račun \"$1\" nije registriran.",
-       "nocontribs": "Nisu nađene promjene koje zadovoljavaju ove uslove.",
+       "nocontribs": "Nema izmjena koje odgovaraju navedenim kriterijima.",
        "uctop": "(trenutno)",
        "month": "Od mjeseca (i ranije):",
        "year": "Od godine (i ranije):",
        "whatlinkshere": "Šta vodi ovamo",
        "whatlinkshere-title": "Stranice koje vode na \"$1\"",
        "whatlinkshere-page": "Stranica:",
-       "linkshere": "Sljedeći članci vode na '''[[:$1]]''':",
+       "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.",
        "isredirect": "preusmjerenje",
-       "istemplate": "šablon",
+       "istemplate": "uključivanje",
        "isimage": "veza na datoteku",
        "whatlinkshere-prev": "{{PLURAL:$1|prethodni|prethodna|prethodnih}} $1",
        "whatlinkshere-next": "{{PLURAL:$1|sljedeći|sljedeća|sljedećih}} $1",
        "unblock-hideuser": "Ne možete deblokirati ovog korisnika jer je njegovo korisničko ime sakriveno.",
        "ipb_cant_unblock": "Greška: Blokirani ID $1 nije pronađen. Možda je korisnik već deblokiran.",
        "ipb_blocked_as_range": "Greška: IP adresa $1 nije direktno blokirana i ne može se deblokirati.\nMeđutim, možda je blokirana kao dio bloka $2, koji se ne može deblokirati.",
-       "ip_range_invalid": "Netačan raspon IP adresa.",
+       "ip_range_invalid": "Netačan opseg IP-adresa.",
        "ip_range_toolarge": "Nisu dopuštene blokade veće od /$1.",
        "proxyblocker": "Zaštita od proxya",
        "proxyblockreason": "Vaša IP adresa je blokirana jer je ona otvoreni proxy.\nMolimo vas da kontaktirate vašeg davatelja internetskih usluga ili tehničku podršku i obavijestite ih o ovom ozbiljnom sigurnosnom problemu.",
        "cant-see-hidden-user": "Korisnik kojeg pokušavate blokirati je već blokiran i sakriven. Pošto nemate prava hideuser (sakrivanje korisnika), ne možete vidjeti ni urediti korisnikovu blokadu.",
        "ipbblocked": "Ne možete blokirati ili deblokirati druge korisnike, jer ste i sami blokirani",
        "ipbnounblockself": "Nije Vam dopušteno da deblokirate samog sebe",
-       "lockdb": "Zaključajte bazu",
-       "unlockdb": "Otključaj bazu",
-       "lockdbtext": "Zaključavanje baze će svim korisnicima ukinuti mogućnost izmjene stranica,\npromjene korisničkih podešavanja, izmjene praćenih članaka, i svega ostalog\nšto zahtjeva promjene u bazi.\nMolimo Vas da potvrdite da je ovo zaista ono što namjeravate da uradite, i da ćete\notkučati bazu kad završite posao oko njenog održavanja.",
+       "lockdb": "Zaključavanje baze podataka",
+       "unlockdb": "Otključavanje baze podataka",
+       "lockdbtext": "Zaključavanje baze će svim korisnicima ukinuti mogućnost izmjene stranica,\nkorisničkih postavki, praćenih članaka i svega ostalog\nšto zahtijeva izmjenu u bazi.\nPotvrdite da je ovo zaista ono što namjeravate uraditi i da ćete\notkučati bazu kad završite posao oko njenog održavanja.",
        "unlockdbtext": "Otključavanje baze će svim korisnicima vratiti mogućnost\nizmjene stranica, promjene korisničkih stranica, izmjene spiska praćenih članaka,\ni svega ostalog što zahtjeva promjene u bazi.\nMolimo Vas da potvrdite da je ovo zaista ono što namijeravate da uradite.",
-       "lockconfirm": "Da, zaista želim da zaključam bazu.",
-       "unlockconfirm": "Da, zaista želim da otključam bazu.",
-       "lockbtn": "Zaključajte bazu",
+       "lockconfirm": "Da, zaista želim zaključati bazu.",
+       "unlockconfirm": "Da, zaista želim otključati bazu.",
+       "lockbtn": "Zaključaj bazu",
        "unlockbtn": "Otključaj bazu",
        "locknoconfirm": "Niste potvrdili svoju namjeru.",
        "lockdbsuccesssub": "Baza je zaključana",
        "unlockdbsuccesssub": "Baza je otključana",
-       "lockdbsuccesstext": "{{SITENAME}} baza podataka je zaključana. <br /> Sjetite se da je otključate kad završite sa održavanjem.",
+       "lockdbsuccesstext": "Baza podataka je zaključana.<br />\nNe zaboravite je [[Special:UnlockDB|otključati]] nakon što završite s održavanjem.",
        "unlockdbsuccesstext": "{{SITENAME}} baza podataka je otključana.",
        "lockfilenotwritable": "Datoteka zaključavanja baze je zaštićena za pisanje.\nAko želite otključati ili zaključati bazu, ova datoteka mora biti omogućena za pisanje od strane web servera.",
        "databasenotlocked": "Baza podataka nije zaključana.",
        "semiprotectedpagemovewarning": "'''Napomena:''' Ova stranica je zaključana tako da je mogu uređivati samo registrovani korisnici.\nPosljednja stavka zapisnika je prikazana ispod kao referenca:",
        "move-over-sharedrepo": "[[:$1]] postoji na dijeljenom skladištu. Premještanje datoteke na ovaj naslov zamijenit će dijeljenu datoteku.",
        "file-exists-sharedrepo": "Ime datoteke koje ste odabrali je već korišteno u dijeljenom repozitorijumu.\nMolimo odaberite drugo ime.",
-       "export": "Izvezite stranice",
+       "export": "Izvoz stranica",
        "exporttext": "Možete izvesti tekst i historiju jedne ili više stranica uklopljene u XML kod.\nOvo se može uvesti u drugi wiki koristeći MediaWiki preko [[Special:Import|stranice uvoza]].\n\nZa izvoz stranica unesite njihove naslove u polje ispod, jedan naslov po retku, i označite želite li trenutnu verziju zajedno sa svim ranijim, ili samo trenutnu verziju sa informacijom o zadnjoj promjeni.\n\nU drugom slučaju možete koristiti i vezu, npr. [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] za stranicu [[{{MediaWiki:Mainpage}}]].",
        "exportall": "Izvezi sve stranice",
-       "exportcuronly": "Uključite samo trenutnu reviziju, ne cijelu historiju",
+       "exportcuronly": "Uključi samo trenutnu verziju, ne cijelu historiju",
        "exportnohistory": "----\n'''Pažnja:''' Izvoz cjelokupne historije stranica preko ovog obrasca je onemogućeno iz tehničkih razloga.",
        "exportlistauthors": "Uključi cjelokupan spisak doprinosilaca za svaku stranicu",
        "export-submit": "Izvezi",
        "export-manual": "Ručno dodaj stranice:",
        "allmessages": "Sve sistemske poruke",
        "allmessagesname": "Naziv",
-       "allmessagesdefault": "Uobičajeni tekst",
+       "allmessagesdefault": "Predodređeni tekst",
        "allmessagescurrent": "Trenutni tekst",
-       "allmessagestext": "Ovo je spisak svih sistemskih poruka u dostupnih u MediaWiki imenskom prostoru.\nMolimo posjetite [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation MediaWiki lokalizaciju] i [https://translatewiki.net translatewiki.net] ako želite doprinijeti općoj lokalizaciji MediaWikija.",
+       "allmessagestext": "Ovo je spisak svih sistemskih poruka u dostupnih u imenskom prostoru MediaWiki.\nPosjetite [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation lokalizaciju MediaWikija] i [https://translatewiki.net translatewiki.net] ako želite doprinijeti općoj lokalizaciji MediaWikija.",
        "allmessagesnotsupportedDB": "Ova stranica ne može biti korištena jer je <i>wgUseDatabaseMessages</i> isključen.",
        "allmessages-filter-legend": "Filter",
        "allmessages-filter": "Filter po stanju podešavanja:",
        "thumbnail-dest-create": "Ne mogu da sačuvam smanjenu sliku (\"thumbnail\") na destinaciju",
        "thumbnail_invalid_params": "Pogrešne postavke smanjenog prikaza",
        "thumbnail_toobigimagearea": "Datoteka sa dimenzijama većim od $1",
-       "thumbnail_dest_directory": "Ne može se napraviti odredišni folder",
+       "thumbnail_dest_directory": "Ne mogu napraviti odredišni folder",
        "thumbnail_image-type": "Tip slike nije podržan",
        "thumbnail_gd-library": "Nekompletna konfiguracija GD biblioteke: nedostaje funkcija $1",
        "thumbnail_image-missing": "Datoteka ne dostaje: $1",
        "import-mapping-subpage": "Uvezi kao podstranice sljedeće stranice:",
        "import-upload-filename": "Naziv datoteke:",
        "import-comment": "Komentar:",
-       "importtext": "Molimo Vas da izvezete datoteku iz izvornog wikija koristeći [[Special:Export|alat za izvoz]].\nSačuvajte je na Vašem računaru i pošaljite ovdje.",
-       "importstart": "Uvoz stranica...",
+       "importtext": "Izvezite datoteku iz izvornog wikija koristeći [[Special:Export|alat za izvoz]].\nSačuvajte je na svoj računar i postavite je ovdje.",
+       "importstart": "Uvozim stranice...",
        "import-revision-count": "$1 {{PLURAL:$1|izmjena|izmjene|izmjena}}",
        "importnopages": "Nema stranica za uvoz.",
        "imported-log-entries": "{{PLURAL:$1|Uvezena $1 stavka zapisnika|Uvezene $1 stavke zapisnika|Uvezeno $1 stavki zapisnika}}.",
-       "importfailed": "Uvoz nije uspjeo: $1",
+       "importfailed": "Uvoz nije uspio: $1",
        "importunknownsource": "Nepoznat izvorni tip uvoza",
-       "importcantopen": "Ne može se otvoriti uvozna datoteka",
+       "importcantopen": "Ne mogu otvoriti datoteku za uvoz",
        "importbadinterwiki": "Loš interwiki link",
        "importsuccess": "Uspješno ste uvezli stranicu!",
-       "importnosources": "Nije definisan međuwiki izvor za uvoz i direktna postavljanja historije su isključena.",
+       "importnosources": "Nije definiran međuwiki izvor za uvoz i direktna postavljanja historije su isključena.",
        "importnofile": "Uvozna datoteka nije postavljena.",
        "importuploaderrorsize": "Postavljanje uvozne datoteke nije uspjelo.\nDatoteka je veća nego što je dopušteno.",
        "importuploaderrorpartial": "Postavljanje uvozne datoteke nije uspjelo.\nDatoteka je samo djelimično postavljena.",
        "xml-error-string": "$1 na liniji $2, kolona $3 (bajt $4): $5",
        "import-upload": "Postavljanje XML podataka",
        "import-token-mismatch": "Izgubljeni podaci sesije. Molimo pokušajte ponovno.",
-       "import-invalid-interwiki": "Ne može se uvesti iz navedenog wikija.",
+       "import-invalid-interwiki": "Ne mogu uvesti iz navedenog wikija.",
        "import-error-edit": "Stranica \"$1\" nije uvezena jer vam nije dopušteno da je uređujete.",
        "import-error-create": "Stranica \"$1\" nije uvezena jer vam nije dozvoljeno da je napravite.",
        "import-error-interwiki": "Stranica \"$1\" nije uvezena jer je njen naziv rezerviran za vanjsko povezivanje (interwiki).",
        "print.css": "/* CSS umetnut ovdje uticat će na izgled isprintane stranice */",
        "common.js": "/* Bilo koja JavaScript će biti učitana za sve korisnike pri svakom učitavanju stranice. */",
        "anonymous": "{{PLURAL:$1|Anonimni korisnik|$1 anonimna korisnika|$1 anonimnih korisnika}} projekta {{SITENAME}}",
-       "siteuser": "{{SITENAME}} korisnik $1",
+       "siteuser": "{{SITENAME}} {{GENDER:$2|korisnik|korisnica}} $1",
        "anonuser": "{{SITENAME}} anonimni korisnik $1",
        "lastmodifiedatby": "Ovu stranicu posljednji je put {{GENDER:$4|izmijenio|izmijenila}} $3 dana $1 u $2.",
        "othercontribs": "Bazirano na radu od strane korisnika $1.",
        "others": "ostali",
-       "siteusers": "{{SITENAME}} {{PLURAL:$2|korisnik|korisnika}} $1",
+       "siteusers": "{{SITENAME}} {{PLURAL:$2|{{GENDER:$1|korisnik|korisnica}}|korisnici}} $1",
        "anonusers": "{{SITENAME}} {{PLURAL:$2|anonimni korisnik|anonimni korisnici}} $1",
        "creditspage": "Autori stranice",
        "nocredits": "Autori ove stranice nisu navedeni.",
        "markedaspatrolledtext": "Izabrana izmjena stranice [[:$1]] označena je patroliranom.",
        "rcpatroldisabled": "Patroliranje nedavnih izmjena onemogućeno",
        "rcpatroldisabledtext": "Funkcija patroliranja nedavnih izmjena je trenutno isključena.",
-       "markedaspatrollederror": "Ne može se označiti kao patrolirano",
+       "markedaspatrollederror": "Ne mogu označiti kao patrolirano",
        "markedaspatrollederrortext": "Morate izabrati izmjenu koju želite označiti patroliranom.",
        "markedaspatrollederror-noautopatrol": "Nije Vam dopušteno da vlastite izmjene označavate patroliranim.",
-       "markedaspatrollednotify": "Ova izmjena na stranici „$1“ je označena kao pregledana.",
+       "markedaspatrollednotify": "Ova izmjena na stranici $1 označena je kao patrolirana.",
        "markedaspatrollederrornotify": "Označavanje stranice pregledanom nije uspjelo.",
        "patrol-log-page": "Zapisnik patroliranja",
        "patrol-log-header": "Ovo je zapisnik patroliranih izmjena.",
        "previousdiff": "← Starija izmjena",
        "nextdiff": "Novija izmjena →",
        "mediawarning": "'''Upozorenje''': Ova datoteka sadrži loš kod, njegovim izvršavanjem možete da ugrozite Vaš sistem.",
-       "imagemaxsize": "Ograničenje veličine slike:<br />''(za stranice opisa datoteke)''",
+       "imagemaxsize": "Ograničenje veličine slike:<br /><em>(za stranice opisa datoteke)</em>",
        "thumbsize": "Veličina umanjenog prikaza:",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|stranica|stranice|stranica}}",
        "file-info": "veličina datoteke: $1, MIME tip: $2",
        "file-no-thumb-animation": "'''Napomena: Zbog tehničkih ograničenja minijature ove datoteke neće biti animirane.'''",
        "file-no-thumb-animation-gif": "'''Napomena: Zbog tehničkih ograničenja, minijature GIF slika visoke rezolucije kao što je ova neće biti animirane.'''",
        "newimages": "Galerija novih slika",
-       "imagelisttext": "Ispod je spisak od '''$1''' {{PLURAL:$1|datoteke|datoteke|datoteka}} poredanih $2.",
+       "imagelisttext": "Ispod je spisak od <strong>$1</strong> {{PLURAL:$1|datoteke|datoteke|datoteka}} poredanih $2.",
        "newimages-summary": "Ova posebna stranica prikazuje nedavno postavljene datoteke.",
        "newimages-legend": "Filter",
        "newimages-label": "Ime datoteke (ili dio imena):",
        "bad_image_list": "Koristi se sljedeći format:\n\nRazmatraju se samo stavke u spisku (linije koje počinju sa *).\nPrvi link u liniji mora biti povezan sa lošom slikom.\nSvi drugi linkovi u istoj liniji se smatraju izuzecima, npr. kod stranica gdje se slike pojavljuju ''inline''.",
        "metadata": "Metapodaci",
        "metadata-help": "Ova datoteka sadržava dodatne podatke koje je vjerovatno dodala digitalna kamera ili skener u procesu snimanja, odnosno digitalizacije. Ako je datoteka mijenjana, podaci možda nisu u skladu sa stvarnim stanjem.",
-       "metadata-expand": "Pokaži sve detalje",
-       "metadata-collapse": "Sakrij dodatne podatke",
+       "metadata-expand": "Prikaži detalje",
+       "metadata-collapse": "Sakrij detalje",
        "metadata-fields": "Polja metapodataka slika su prikazani ispod slike će biti uključeni u prikaz stranice slike kada je sakrivena tabela metapodataka. U suprotnom će biti sakrivena po postavkama.\n\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "exif-imagewidth": "Širina",
        "exif-imagelength": "Visina",
        "exif-spectralsensitivity": "Spektralna osjetljivost",
        "exif-isospeedratings": "Rejting ISO brzine",
        "exif-shutterspeedvalue": "Brzina APEX okidača",
-       "exif-aperturevalue": "APEX otvor",
-       "exif-brightnessvalue": "APEX osvijetljenost",
+       "exif-aperturevalue": "Otvor blende",
+       "exif-brightnessvalue": "Osvijetljenost",
        "exif-exposurebiasvalue": "Kompozicija ekspozicije",
        "exif-maxaperturevalue": "Najveći broj otvora blende",
        "exif-subjectdistance": "Udaljenost objekta",
        "exif-gpslongituderef": "Istočna ili zapadna dužina",
        "exif-gpslongitude": "Dužina",
        "exif-gpsaltituderef": "Referenca visine",
-       "exif-gpsaltitude": "Nadmorska visina",
+       "exif-gpsaltitude": "Visina",
        "exif-gpstimestamp": "GPS vrijeme (atomski sat)",
        "exif-gpssatellites": "Sateliti korišteni pri mjerenju",
        "exif-gpsstatus": "Status prijemnika",
        "monthsall": "sve",
        "confirmemail": "Potvrdite adresu e-pošte",
        "confirmemail_noemail": "Niste unijeli tačnu e-mail adresu u Vaše [[Special:Preferences|korisničke postavke]].",
-       "confirmemail_text": "Ova viki zahtjeva da potvrdite adresu Vaše e-pošte prije nego što koristite mogućnosti e-pošte. Aktivirajte dugme ispod kako bi ste poslali poštu za potvrdu na Vašu adresu. Pošta uključuje link koji sadrži kod; učitajte link u Vaš preglednik da bi ste potvrdili da je adresa Vaše e-pošte validna.",
+       "confirmemail_text": "{{SITENAME}} zahtijeva da potvrdite adresu Vaše e-pošte prije nego što koristite mogućnosti e-pošte.\nAktivirajte dugme ispod kako biste poslali poštu za potvrdu na Vašu adresu.\nPošta uključuje link koji sadrži kod;\nučitajte link u Vaš preglednik da biste potvrdili da je adresa Vaše e-pošte validna.",
        "confirmemail_pending": "Potvrdni kod Vam je već poslan e-poštom;\nako ste nedavno otvorili račun, trebali biste pričekati nekoliko minuta da poslana pošta stigne, prije nego što ponovo zahtijevate novi kod.",
        "confirmemail_send": "Pošaljite kod za potvrdu",
        "confirmemail_sent": "E-pošta za potvrđivanje poslata.",
        "confirmemail_oncreate": "Kod za potvrđivanje Vam je poslat na Vašu e-mail adresu.\nTaj kod nije neophodan za prijavljivanje, ali Vam ne potreban kako bi ste omogućili funkcije wikija zasnovane na e-mailu.",
-       "confirmemail_sendfailed": "{{SITENAME}} Vam ne može poslati poštu za potvrđivanje. Provjerite adresu zbog nepravilnih karaktera.\n\nPovratna pošta: $1",
+       "confirmemail_sendfailed": "{{SITENAME}} Vam ne može poslati potvrdnu e-poruku.\nProvjerite sadrži li adresa nedopuštene znakove.\n\nGreška: $1",
        "confirmemail_invalid": "Netačan kod za potvrdu. Moguće je da je kod istekao.",
        "confirmemail_needlogin": "Morate biti $1 da biste potvrdili adresu vaše e-pošte.",
        "confirmemail_success": "Adresa vaše e-pošte je potvrđena. Možete sad da se prijavite i uživate u viki.",
        "confirmemail_loggedin": "Adresa Vaše e-pošte je potvrđena.",
-       "confirmemail_subject": "{{SITENAME}} – adresa e-pošte za potvrđivanje",
+       "confirmemail_subject": "Potvrda adrese e-pošte na {{GRAMMAR:dativ|{{SITENAME}}}}",
        "confirmemail_body": "Neko, vjerovatno Vi, je sa IP adrese $1 registrovao nalog \"$2\" sa ovom adresom e-pošte na {{SITENAME}}.\n\nDa potvrdite da ovaj nalog stvarno pripada vama i da aktivirate mogućnost e-pošte na {{SITENAME}}, otvorite ovaj link u vašem pregledniku:\n\n$3\n\nAko ovo niste vi, pratite ovaj link da prekinete prijavu:\n$5\n\nOvaj kod za potvrdu će isteći u $4.",
        "confirmemail_body_changed": "Neko, vjerovatno Vi, je sa IP adrese $1\nje promijenio adresu e-pošte računa \"$2\" na ovu adresu za {{SITENAME}}.\n\nDa potvrdite da ovaj nalog stvarno pripada Vama i da reaktivirate mogućnosti e-pošte na {{SITENAME}}, otvorite ovaj link u Vašem pregledniku:\n\n$3\n\nAko ovaj račun *ne* pripada Vama, pratite ovaj link da prekinete odobravanje adrese e-pošte:\n\n$5\n\nOvaj kod za potvrdu će isteći u $4.",
        "confirmemail_body_set": "Neko, vjerovatno Vi, je sa IP adrese $1\npostavio adresu e-pošte računa \"$2\" na ovu adresu za {{SITENAME}}.\n\nDa potvrdite da ovaj račun stvarno pripada Vama i da aktivirate mogućnosti e-pošte na {{SITENAME}}, otvorite ovaj link u Vašem pregledniku:\n\n$3\n\nAko ovaj račun *ne* pripada Vama, pratite ovaj link da prekinete odobravanje adrese e-pošte:\n\n$5\n\nOvaj kôd za potvrdu će isteći u $4.",
        "scarytranscludefailed": "[Neuspješno preusmjerenje šablona na $1]",
        "scarytranscludefailed-httpstatus": "[Preuzimanje šablona nije uspjelo za $1: HTTP $2]",
        "scarytranscludetoolong": "[URL je predugačak]",
-       "deletedwhileediting": "'''Upozorenje''': Ova stranica je obrisana prije nego što ste počeli uređivati!",
+       "deletedwhileediting": "<strong>Upozorenje:</strong> Ova stranica je obrisana prije nego što ste počeli uređivati!",
        "confirmrecreate": "{{GENDER:$1|Korisnik|Korisnica}} [[User:$1|$1]] ([[User talk:$1|razgovor]]) {{GENDER:$1|obrisao|obrisala}} je ovu stranicu nakon što ste je počeli uređivati iz sljedećeg razloga:\n: <em>$2</em>\n\nPotvrdite da stvarno želite ponovo napraviti ovu stranicu.",
        "confirmrecreate-noreason": "{{GENDER:$1|Korisnik|Korisnica}} [[User:$1|$1]] ([[User talk:$1|razgovor]]) {{GENDER:$1|obrisao|obrisala}} je ovu stranicu nakon što ste je počeli uređivati. Potvrdite da stvarno želite ponovo napraviti ovu stranicu.",
        "recreate": "Ponovno napravi",
        "tags-deactivate-not-allowed": "Nije moguće deaktivirati oznaku \"$1\".",
        "tags-deactivate-submit": "Deaktiviraj",
        "tags-apply-no-permission": "Nemate dopuštenja da dodate izmjenske oznake zajedno s vašim promjenama.",
-       "tags-apply-not-allowed-one": "Oznaka \"$1\" se ne može ručno dodati.",
+       "tags-apply-not-allowed-one": "Nije dozvoljeno da se oznaka \"$1\" ručno dodaje.",
        "tags-apply-not-allowed-multi": "{{PLURAL:$2|Sljedeća oznaka ne dozvoljava da se ručno doda|Sljedeće oznake ne dozvoljavaju da se ručno dodaju}}: $1",
        "tags-update-no-permission": "Nemate dopuštenje da dodate ili uklonite izmjenske oznake sa zasebnih verzija ili zapisničkih unosa.",
-       "tags-update-add-not-allowed-one": "Oznaka \"$1\" se ne može ručno dodati.",
+       "tags-update-add-not-allowed-one": "Nije dozvoljeno da se oznaka \"$1\" ručno dodaje.",
        "tags-update-add-not-allowed-multi": "{{PLURAL:$2|Sljedeća oznaka ne dozvoljava da se ručno doda|Sljedeće oznake ne dozvoljavaju da se ručno dodaju}}: $1",
        "tags-update-remove-not-allowed-one": "Oznaka \"$1\" se ne može ručno ukloniti.",
        "tags-update-remove-not-allowed-multi": "{{PLURAL:$2|Sljedeća oznaka ne dozvoljava da se ručno ukloni|Sljedeće oznake ne dozvoljavaju da se ručno uklone}}: $1",
        "revdelete-uname-unhid": "korisničko ime je otkriveno",
        "revdelete-restricted": "primijenjena ograničenja za administratore",
        "revdelete-unrestricted": "uklonjena ograničenja za administratore",
-       "logentry-block-block": "$1 {{GENDER:$2|blokirao|blokirala}} je {{GENDER:$4|$3}} sa vremenom isticanja blokade od $5 $6",
+       "logentry-block-block": "$1 {{GENDER:$2|blokirao|blokirala}} je {{GENDER:$4|$3}} u trajanju od $5 $6",
        "logentry-block-unblock": "$1 {{GENDER:$2|deblokirao|deblokirala}} je {{GENDER:$4|$3}}",
        "logentry-block-reblock": "$1 {{GENDER:$2|promijenio|promijenila}} je postavke za blokiranje {{GENDER:$4|korisnika|korisnice}} {{GENDER:$4|$3}} u trajanju od $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|blokirao|blokirala}} je {{GENDER:$4|$3}} sa vremenom isticanja blokade od $5 $6",
index 07b8838..140bbf4 100644 (file)
@@ -55,7 +55,8 @@
                        "KRLS",
                        "Jaumeortola",
                        "Kippelboy",
-                       "Syum90"
+                       "Syum90",
+                       "Xð"
                ]
        },
        "tog-underline": "Subratlla els enllaços:",
        "unprotectthispage": "Desprotegeix aquesta pàgina",
        "newpage": "Pàgina nova",
        "talkpage": "Discussió",
-       "talkpagelinktext": "Discussió",
+       "talkpagelinktext": "discussió",
        "specialpage": "Pàgina especial",
        "personaltools": "Eines de l'usuari",
        "articlepage": "Mostra la pàgina",
        "rcfilters-invalid-filter": "Filtre no vàlid",
        "rcfilters-empty-filter": "No hi ha cap filtre actiu. Es mostren totes les contribucions.",
        "rcfilters-filterlist-title": "Filtres",
+       "rcfilters-highlightbutton-title": "Ressalta els resultats",
        "rcfilters-highlightmenu-title": "Selecciona un color",
        "rcfilters-filterlist-noresults": "No s'ha trobat cap filtre",
        "rcfilters-filtergroup-registration": "Registre d'usuari",
        "svg-long-error": "El fitxer SVG no és vàlid: $1",
        "show-big-image": "Fitxer original",
        "show-big-image-preview": "Mida d'aquesta previsualització: $1.",
+       "show-big-image-preview-differ": "Mida d'aquesta previsualització $3 del fitxer $2: $1.",
        "show-big-image-other": "{{PLURAL:$2|Altra resolució|Altres resolucions}}: $1.",
        "show-big-image-size": "$1 × $2 píxels",
        "file-info-gif-looped": "en bucle",
        "tags-delete-not-found": "L'etiqueta «$1» no existeix.",
        "tags-delete-too-many-uses": "L'etiqueta «$1» s'aplica a més {{PLURAL:$2|d'$2 revisió|de $2 revisions}} i, per tant, no pot eliminar-se.",
        "tags-delete-warnings-after-delete": "L'etiqueta \"$1\" ha estat esborrada satisfactòriament, però {{PLURAL:$2|s'ha registrat l'advertència següent|s'han registrat les advertències següents}}:",
+       "tags-delete-no-permission": "No teniu permisos per a eliminar les etiquetes de canvis.",
        "tags-activate-title": "Activa l'etiqueta",
        "tags-activate-question": "Esteu a punt d'activar l'etiqueta «$1».",
        "tags-activate-reason": "Motiu:",
        "tags-deactivate-not-allowed": "No és possible desactivar l'etiqueta «$1».",
        "tags-deactivate-submit": "Desactiva",
        "tags-apply-no-permission": "No teniu permís per canviar etiquetes juntament amb altres canvis.",
+       "tags-apply-blocked": "No podeu aplicar etiquetes de canvis amb els vostres canvis mentre estigueu {{GENDER:$1|blocat|blocada}}.",
        "tags-apply-not-allowed-one": "No es permet aplicar l'etiqueta «$1» manualment.",
        "tags-apply-not-allowed-multi": "No es permet aplicar manualment {{PLURAL:$2|l'etiqueta següent|les etiquetes següents}}: $1",
        "tags-update-no-permission": "No teniu permisos per a afegir o suprimir etiquetes de canvi de revisions individuals o entrades de registre.",
+       "tags-update-blocked": "No podeu afegir o suprimir etiquetes de canvis mentre estigueu {{GENDER:$1|blocat|blocada}}.",
        "tags-update-add-not-allowed-one": "No es permet afegir manualment l'etiqueta «$1».",
        "tags-update-add-not-allowed-multi": "No es permet afegir manualment {{PLURAL:$2|l'etiqueta següent|les etiquetes següents}}: $1",
        "tags-update-remove-not-allowed-one": "No es permet treure l’etiqueta «$1».",
        "authprovider-resetpass-skip-label": "Omet",
        "authprovider-resetpass-skip-help": "Omet el restabliment de contrasenya.",
        "specialpage-securitylevel-not-allowed-title": "No permès",
+       "specialpage-securitylevel-not-allowed": "Ho sentim, no podeu utilitzar la pàgina perquè no es pot verificar la vostra identitat.",
        "authpage-cannot-login": "No s'ha pogut iniciar la sessió.",
        "authpage-cannot-login-continue": "No es pot continuar amb l'inicio de sessió. Probablement la vostra sessió ha expirat.",
        "authpage-cannot-create": "No s'ha pogut iniciar la creació del compte.",
        "authpage-cannot-create-continue": "No es pot prosseguir la creació del compte. Probablement la vostra sessió ha expirat.",
        "authpage-cannot-link": "No s'ha pogut iniciar l'enllaç del compte.",
+       "authpage-cannot-link-continue": "No es pot continuar amb l'enllaç del compte. Possiblement s'ha esgotat el temps de la vostra sessió.",
        "cannotauth-not-allowed-title": "S'ha denegat el permís",
        "cannotauth-not-allowed": "No teniu permisos per utilitzar la pàgina",
        "changecredentials": "Canvi de dades credencials",
index 1533127..ec38e90 100644 (file)
        "showhideselectedlogentries": "Гайта/къайлаяха хаьржина башхонаш",
        "checkbox-select": "Харжар: $1",
        "checkbox-all": "Массо",
-       "checkbox-none": "ХӀума а",
+       "checkbox-none": "ХӀума",
        "checkbox-invert": "Инверт ян",
        "allpages": "Массо агӀонаш",
        "nextpage": "ТӀаьхьа йогӀу агӀо ($1)",
index 2ae2a77..f224ed7 100644 (file)
        "tog-editondblclick": "دەستکاریی پەڕە بە دووکرتە",
        "tog-editsectiononrightclick": "دەستکاریی بەشەکان بە کرتەی ڕاست لەسەر سەردێڕی بەشەکان",
        "tog-watchcreations": "ئەو پەڕانەی من دروستم کردوون و ئەو پەڕگانە من بارم کردوون زیاد بکە بە لیستی چاودێڕییەکەم",
-       "tog-watchdefault": "ئەو پەڕانە  و ئەو پەڕگانە من دەستکاریان دەکەم زیاد بکە بە لیستی چاودێڕییەکەم",
+       "tog-watchdefault": "ئەو پەڕانە و ئەو پەڕگانە من دەستکاریان دەکەم زیاد بکە بە لیستی چاودێڕییەکەم",
        "tog-watchmoves": "ئەو پەڕانە و ئەو پەڕگانە کە من گواستومنەتەوە زیاد بکە بە لیستی چاودێڕییەکەم",
        "tog-watchdeletion": "ئەو پەڕانە و ئەو پەڕگانە من سڕیومنەتەوە زیاد بکە بە لیستی چاودێڕییەکەم",
+       "tog-watchuploads": "ئەو پەڕگە نوێیانەی باریان دەکەم زیاد بکە ناو پێڕستی چاودێرییەکەمەوە",
+       "tog-watchrollback": "ئەو پەڕانەی کە کرداری گەڕاندنەوەم لەسەر ئەنجام داون زیاد بکە ناو پێڕستی چاودێرییەکەمەوە",
        "tog-minordefault": "ھەموو دەستکارییەکان بە ورد نیشان بکە لە حاڵەتی دیفاڵت",
        "tog-previewontop": "پێشبینین بەرلە چوارچێوەی دەستکاری نیشان بدە‌",
        "tog-previewonfirst": "لە یەکەم دەستکاری دا پێشبینین نیشان بدە",
        "newwindow": "(لە پەڕەیەکی نوێدا دەکرێتەوە)",
        "cancel": "ھەڵوەشاندنەوە",
        "moredotdotdot": "زیاتر",
-       "morenotlisted": "ئەم لیستەیە تەواو نییە",
+       "morenotlisted": "ئەم لیستە لەوانەیە تەواو نەبێت",
        "mypage": "پەڕە",
        "mytalk": "لێدوان",
        "anontalk": "لێدوان",
        "searcharticle": "بڕۆ",
        "history": "مێژووی پەڕە",
        "history_short": "مێژووی پەڕە",
+       "history_small": "مێژوو",
        "updatedmarker": "لە دوایین سەردانمدا نوێ کراوەتەوە",
        "printableversion": "وەشانی ئامادەی چاپ",
        "permalink": "بەستەری ھەمیشەیی",
        "view": "بینین",
        "view-foreign": "لە $1دا بیبینە",
        "edit": "دەستکاری",
+       "edit-local": "دەستکاریکردنی زانیارییە ناوخۆییەکان",
        "create": "دروستکردن",
        "create-local": "وەسفی ناوچەیی زۆر بکە",
        "editthispage": "دەستکاری ئەم پەڕەیە بکە‌",
        "talk": "وتووێژ",
        "views": "بینینەکان",
        "toolbox": "ئامرازەکان",
+       "tool-link-userrights": "بینینی گرووپەکانی {{GENDER:$1|بەکارھێنەر}}",
+       "tool-link-userrights-readonly": "بینینی گرووپەکانی {{GENDER:$1|بەکارھێنەر}}",
+       "tool-link-emailuser": "ئیمەیلی ئەم {{GENDER:$1|بەکارھێنەر}}ە",
        "userpage": "بینینی پەڕەی بەکارھێنەر",
        "projectpage": "پەڕەی پرۆژە نیشان بدە",
        "imagepage": "پەڕەی پەڕگە نیشان بدە",
        "jumptonavigation": "ڕێدۆزی",
        "jumptosearch": "گەڕان",
        "view-pool-error": "ببورە، لەم کاتەدا ڕاژەکارەکان زیادەباریان لە سەرە.\nژمارەیەکی زۆر لە بەکارھێنەران ھاوکات ھەوڵی دیتنی ئەم پەڕەیان داوە.\nتکایە پێش ھەوڵی دووبارە بۆ دیتنی ئەم پەڕە، نەختێک بوەستە.\n\n$1",
+       "generic-pool-error": "ببورە، لەم کاتەدا ڕاژەکارەکان زیادەباریان لە سەرە.\nژمارەیەکی زۆر لە بەکارھێنەران ھاوکات ھەوڵی دیتنی ئەم پەڕەیان داوە.\nتکایە پێش ھەوڵی دووبارە بۆ دیتنی ئەم پەڕە، کەمێک بووەستە.",
        "pool-timeout": "لەکات دەرچوون ڕوویدا لەکاتی چاوەڕوانکردنی داخستندا",
        "pool-errorunknown": "هەڵەی نەزانراو",
        "aboutsite": "دەربارەی {{SITENAME}}",
        "viewsource": "بینینی سەرچاوە",
        "viewsource-title": "سەرچاوەی $1 ببینە",
        "actionthrottled": "چالاکی پێشی پێ گیرا",
-       "actionthrottledtext": "بÛ\95 Ù\85Û\95بÛ\95ستÛ\8c Ù¾Û\8eشگرÛ\8cÛ\8c Ù\84Û\95 Ø³Ù¾Û\95Ù\85Ø\8c Ú\95Û\8eÚ¯Û\95 Ù\86ادرÛ\8eت ØªÛ\86 Ù\84Û\95 Ù\85اÙ\88Û\95Û\8cÛ\95Ú©Û\8c Ú©Ù\88رت Ø¯Ø§ Ù\84Û\95 Ø³Û\95ر Û\8cÛ\95Ú© Ø¦Û\95Ù\85Û\95 Ø²Û\86ر Ø¬Ø§Ø± Ø¦Û\95Ù\86جاÙ\85 Ø¨Ø¯Û\95Û\8cØ\8c Ù\88Û\95 ئیستا تۆ لە ڕادە بەدەرت کردووە.\nتکایە پاش چەند خولەک دووبارە تاقی بکەوە.",
+       "actionthrottledtext": "بÛ\95 Ù\85Û\95بÛ\95ستÛ\8c Ù¾Û\8eشگرÛ\8cÛ\8c Ù\84Û\95 Ø®Ø±Ø§Ù¾Ú©Ø§Ø±Û\8cØ\8c Ú\95Û\8eÚ¯Û\95 Ù\86ادرÛ\8eت ØªÛ\86 Ù\84Û\95 Ù\85اÙ\88Û\95Û\8cÛ\95Ú©Û\8c Ú©Ù\88رت Ø¯Ø§ Ù\84Û\95 Ø³Û\95ر Û\8cÛ\95Ú© Ø¦Û\95Ù\85Û\95 Ø²Û\86ر Ø¬Ø§Ø± Ø¦Û\95Ù\86جاÙ\85 Ø¨Ø¯Û\95Û\8cØ\8c ئیستا تۆ لە ڕادە بەدەرت کردووە.\nتکایە پاش چەند خولەک دووبارە تاقی بکەوە.",
        "protectedpagetext": "بۆ بەرگری لە دەستکاریکردن یان چالاکییەکانی تر ئەم پەڕەیە پارێزراوە.",
        "viewsourcetext": "دەتوانی سەرچاوەی ئەم پەڕە ببینی و کۆپیی بکەی٫",
        "viewyourtext": "دەتوانی ژێدەری <strong>دەستکارییەکەت</strong> لەم پەڕەیەدا ببینی و کۆپی بکەی.",
        "virus-scanfailed": "سکەن ئەنجام نەدرا(کۆد $1)",
        "virus-unknownscanner": "دژەڤایرس نەناسراوە:",
        "logouttext": "'''ئێستا چوویتە دەرەوە.'''\n\nئاگادار بە ھەتا ئەو کاتەی کەشی وێبگەڕەکەت پاک دەکەیتەوە، لەوانەیە ھەندێک لە پەڕەکان وا پێشان بدرێن کە ھێشتا لە ژوورەوە بیت.",
+       "cannotlogoutnow-title": "ناتوانیت لە ئێستادا بچیتە دەرەوە",
+       "cannotlogoutnow-text": "توانای چوونە دەرەوەت نییە لەکاتی بەکارھێنانی $1",
        "welcomeuser": "بەخێربێیت، $1!",
        "welcomecreation-msg": "ھەژمارەکەت دروست کرا.\nلە بیرت نەچێت [[Special:Preferences|ھەڵبژاردەکانی {{SITENAME}}]]ت بگۆڕی.",
        "yourname": "ناوی بەکارھێنەری:",
        "createacct-yourpasswordagain-ph": "تێپەروشە دیسان بنووسەوە",
        "userlogin-remembermypassword": "چوونەژوورەوەکەم ڕابگرە",
        "userlogin-signwithsecure": "پەیوەندیی دڵنیا بەکاربھێنە",
+       "cannotlogin-title": "ناتوانیت بچیتە ژوورەوە",
+       "cannotlogin-text": "توانای چوونەژوورەوەت نییە",
+       "cannotloginnow-title": "ناتوانیت لە ئێستادا بچیتە ناوەوە",
+       "cannotloginnow-text": "توانای چوونەژوورەوەت نییە لەکاتی بەکارھێنانی $1",
+       "cannotcreateaccount-title": "ناتوانرێت ھەژمار دروست بکرێت",
        "yourdomainname": "دۆمەینەکەت:",
        "password-change-forbidden": "ناتوانیت تێپەڕوشەکانت لەم ویکییەدا بگۆڕیت.",
        "externaldberror": "یان هەڵەی ڕێگەپێدانی بنکەدراو هەیە یان ڕێگات پێ نادرێت بۆ نوێ کردنی هەژماری دەرەکیت.",
        "login": "بچۆ ژوورەوە",
+       "login-security": "شوناست دڵنیا بکەرەوە",
        "nav-login-createaccount": "بچۆ ژوورەوە / ھەژمار دروست بکە",
        "userlogin": "بچۆ ژوورەوە / ھەژمار دروست بکە",
        "userloginnocreate": "بچۆ ژوورەوە",
        "userlogin-resetpassword-link": "تێپەڕوشەکەت بیر کردووە؟",
        "userlogin-helplink2": "یارمەتی بۆ چوونەژوورەوە",
        "userlogin-loggedin": "تۆ ھەر ئێستا بە ناوی {{GENDER:$1|$1}} چوویتە ژوورەوە.\nفۆرمی ژێرەوە بەکاربھێنە بۆ چوونەژوورەوە وەک بەکارھێنەرێکی تر.",
+       "userlogin-reauth": "دەبێت دووبارە بچیتە ژوورەوە بۆ دڵنیا بوونەوە لە {{GENDER:$1|$1}}بوونت.",
        "userlogin-createanother": "ھەژمارێکی تر دروست بکە",
        "createacct-emailrequired": "ناونیشانی ئیمەیل",
        "createacct-emailoptional": "ناونیشانی ئیمەیل (دڵخوازانە)",
        "createacct-email-ph": "ناونیشانی ئیمەیلەکەت بنووسە",
        "createacct-another-email-ph": "ناونیشانی ئیمەیڵەکەت بنووسە",
        "createaccountmail": "تێپەڕوشەیەکی ھەڕەمەکیی کاتی بەکاربھێنە و بینێرە بۆ ناونیشانی ئیمەیلی دیاریکراو",
+       "createaccountmail-help": "دەتوانرێت بەکار بھێندرێت بۆ دروستکردنی ھەژمار بۆ کەسێکی تر بەبێ زانینی تێپەڕ وشەکەی.",
        "createacct-realname": "ناوی ڕاستی (دڵخوازانە)",
        "createaccountreason": "هۆکار:",
        "createacct-reason": "ھۆکار",
        "createacct-reason-ph": "بۆ ھەژمارێکی تر دروست دەکەی",
        "createacct-submit": "ھەژمارەکەت دروست بکە",
        "createacct-another-submit": "ھەژمار دروست بکە",
+       "createacct-continue-submit": "بەردەوامبوون لە دروستکردنی ھەژمار",
+       "createacct-another-continue-submit": "بەردەوامبوون لە دروستکردنی ھەژمار",
        "createacct-benefit-heading": "{{SITENAME}} لە لایەن کەسانێک وەکوو خۆت دروست کراوە.",
        "createacct-benefit-body1": "{{PLURAL:$1|دەستکاری}}",
        "createacct-benefit-body2": "{{PLURAL:$1|پەڕە}}",
        "createacct-benefit-body3": "دوایین {{PLURAL:$1|بەشداربوو|بەشداربووان}}",
        "badretype": "تێپەڕوشەکان لەیەک ناچن.",
+       "usernameinprogress": "دروستکردنی ھەژمارێک بۆ ئەم ناوی بەکارھێنەرە لە پڕۆسەی بەرھەمھێناندایە. تکایە چاوەڕوان بە.",
        "userexists": "ئەو ناوەی تۆ داوتە پێشتر بەکارھێنراوە.\nناوێکی دیکە ھەڵبژێرە.",
        "loginerror": "ھەڵەی چوونەژوورەوە",
        "createacct-error": "ھەڵە لە دروستکردنی ھەژمار",
        "nocookiesnew": "ھەژماری بەکارھێنەری دروست کرا، بەڵام نەچوویتەوە ژوورەوە.\n{{SITENAME}} بۆ چوونەوە ژوورەوەی بەکارھێنەر کوکی بەکاردەھێنێت.\nتۆ کوکییەکەکەت لەکارخستووە.\nتکایە کوکییەکە کارا بکە، پاشان بە ناوی بەکارھێنەری و تێپەڕوشەکەت بچۆ ژوورەوە.",
        "nocookieslogin": "{{SITENAME}} بۆ چوونەژوورەوە لە کووکی‌یەکان کەڵک وەرئەگرێت.\nڕێگەت نەداوە بە کووکی‌یەکان.\nڕێگەیان پێ بدەو و دیسان تێبکۆشە.",
        "nocookiesfornew": "ھەژماری بەکارھێنەری دروست نەکرا، چون ناتوانین سەرچاوەکەی پشتڕاست بکەینەوە.\nدڵنیا بە کوکییەکانت چالاک کردووە، پەڕەکە بار بکەوە و دیسان ھەوڵ بدە.",
+       "createacct-loginerror": "ھەژمارەکە بە سەرکەوتوانە دروست کرا، بەڵام ناتوانرێت بە شێوەیەکی ئۆتۆماتیکی بکرێیتە ژوورەوە. تکایە سەردانی [[Special:UserLogin|ڕێنماییەکانی چوونەژوورەوە]] بکە.",
        "noname": "ناوی بەکارهێنەرییەکی گۆنجاوت دیاری نەکردووه.",
        "loginsuccesstitle": "چوویە ناوەوە",
        "loginsuccess": "'''ئێستا بە ناوی «$1»ەوە لە {{SITENAME}} چوویتەتەژوورەوە.'''",
-       "nosuchuser": "بەکارھێنەرێک بە ناوی «$1» نیە.\nناوی بەکارھێنەر بە گەورە و بچووک بوونی پیتەکان ھەستیارە.\nڕێنووسەکەت چاولێکەرەوە، یان [[Special:CreateAccount|ھەژمارێکی نوێ دروست بکە]].",
+       "nosuchuser": "بÛ\95کارھÛ\8eÙ\86Û\95رÛ\8eÚ© Ø¨Û\95 Ù\86اÙ\88Û\8c Â«$1» Ù\86Û\8cÛ\8cÛ\95.\nÙ\86اÙ\88Û\8c Ø¨Û\95کارھÛ\8eÙ\86Û\95ر Ø¨Û\95 Ú¯Û\95Ù\88رÛ\95 Ù\88 Ø¨Ú\86Ù\88Ù\88Ú© Ø¨Ù\88Ù\88Ù\86Û\8c Ù¾Û\8cتÛ\95کاÙ\86 Ú¾Û\95ستÛ\8cارÛ\95.\nÚ\95Û\8eÙ\86Ù\88Ù\88سÛ\95Ú©Û\95ت Ú\86اÙ\88Ù\84Û\8eÚ©Û\95رÛ\95Ù\88Û\95Ø\8c Û\8cاÙ\86 [[Special:CreateAccount|Ú¾Û\95Ú\98Ù\85ارÛ\8eÚ©Û\8c Ù\86Ù\88Û\8e Ø¯Ø±Ù\88ست Ø¨Ú©Û\95]].",
        "nosuchusershort": "بەکارھێنەرێک بە ناوی «$1»ەوە نیە.\nبە نووسراوەکەتدا بچۆرەوە.",
        "nouserspecified": "دەبێت ناوێکی بەکارھێنەری دەستنیشان بکەیت.",
        "login-userblocked": "ئەم بەکارهێنەرە بڵۆک کراوە. چوونەژوورەوە ڕێگەپێنەدراوە.",
        "wrongpassword": "تێپەڕوشەی ھەڵە.\nتکایە دووبارە تێبکۆشە.",
        "wrongpasswordempty": "تێپەڕەوشەی لێدراو بەتاڵبوو.\nتکایە هەوڵ بدەوە.",
        "passwordtooshort": "تێپەڕوشەکەت لانی کەم دەبێ {{PLURAL:$1|١ پیت|$1 پیت}} بێت.",
+       "passwordtoolong": "تێپەڕ وشەکان ناتوانرێت لە {{PLURAL:$1|١ کارەکتەر|$1 کارەکتەر}} درێژتر بێت.",
+       "passwordtoopopular": "تێپەڕ وشە باوەکان ناتواندرێت دابنرێن. تکایە تێپەڕ وشەیەکی دەگمەنتر ھەڵبژێرە.",
        "password-name-match": "تێپەڕوشەکەت ئەبێ جیاواز بێت لە ناوی بەکارهێنەریت.",
        "password-login-forbidden": "بەکارهێنانی ئەم ناوی بەکارهێنەر و تێپەڕەووشەیە قەدەغەکراوە.",
        "mailmypassword": "تێپەڕوشەکە ڕێک بخەوە",
        "noemail": "ھیچ ئەدرەسێکی ئیمەیل تۆمار نەکراوە بۆ بەکارھێنەر « $1 ».",
        "noemailcreate": "دەبێ ناونیشانێکی دروستی ئیمەیل بنووسی",
        "passwordsent": "تێپەڕوشەیەکی نوێ نێررا بۆ ئەدرەسی ئیمێلی تۆمارکراوی «$1».\nتکایە دوای وەرگرتنی، دیسان بچۆ ژوورەوە.",
-       "blocked-mailpassword": "ئادرەسی ئای‌پی تۆ بۆ دەستکاری کردن بەستراوه بۆیە بۆ بەرگری لە بەکارهێنانی نابەجێ ئەنجامی گەڕانەوەی تێپەڕوشە ڕیگە نەدراوە.",
+       "blocked-mailpassword": "ناونیشانی ئای پی تۆ بۆ دەستکاری کردن بەستراوه. بۆ بەرگری لە بەکارهێنانی نابەجێ، ئەنجامی گەڕانەوەی تێپەڕوشە ڕیگە نەدراوە لەسەر ئەم ناونیشانە ئای پییە.",
        "eauthentsent": "ئیمێلێکی پشتڕاستکردنەوە بۆ ناونیشانی ئیمێلی دیاریکراو نێررا.\nپێش ئەوەی ئیمەیلی تر بۆ ئەم ھەژمارە بنێررێت، دەبێت پەیڕەوی ڕێکارەکانی ناو ئیمێلەکە بکەیت بۆ پشتڕاستکردنەوەی ئەوەی کە ئەم هەژمارە بە ڕاستی ھی تۆیە.",
        "throttled-mailpassword": "ئیمەیلێکی ڕیکخستنەوەی تێپەڕوشە لە ماوەی {{PLURAL:$1|ساعەت}}ی ڕابردوودا نێردراوە.\nبۆ ڕێگری لە بەکارھێنانی خراپ، ھەر {{PLURAL:$1|ساعەت}} تاکە یەک ئیمەیلی ڕیکخستنەوەی تێپەڕوشە دەنێردرێت.",
        "mailerror": "هەڵە ڕوویدا لە ناردنی ئیمەیل: $1",
        "createaccount-title": "درووست کردنی ھەژمار بۆ {{SITENAME}}",
        "createaccount-text": "کەسێک ھەژمارێکی بۆ ناونیشانی ئیمێلی تۆ لە {{SITENAME}}دا ($4) بە ناوی «$2»ـەوە و بە تێپەڕوشەی  «$3»ـەوە دروست کردووە.\nدەبێت ھەر ئێستا بچیتە چوورەوە و تێپەڕوشەیەکەت بگۆڕیت.\n\nئەگەر ئەم ھەژمارە بە ھەڵە دروست کراوە، دەکرێت گوێ بەم پەیامە نەدەیت.",
        "login-throttled": "زۆر زۆر ھەوڵت داوە بۆ چوونە ژوورەوە.\nتکایە $1 بوەستە پێش ھەوڵی دووبارە.",
+       "login-abort-generic": "چوونەژوورەوەکەت شکستی ھێنا - بەجێ ھێڵدرا",
+       "login-migrated-generic": "ھەژمارەکەت گوازراوەتەوە و ناوی بەکارھێنەرەکەت چی تر لەسەر ئەم ویکیپیدیایە بوونی نییە.",
        "loginlanguagelabel": "زمان: $1",
+       "suspicious-userlogout": "داواکارییەکەت بۆ چوونە دەرەوە ڕەت کرایەوە لەبەر ئەوەی وا دیارە داواکارییەکە لەلایەن براوسەرێکی شکاوەوە نێردراوە.",
+       "createacct-another-realname-tip": "ناوی ڕاستیت پێویست نییە.\nئەگەر ھەڵت بژارد کە دایبنێیت، ئەوا بەکار دەھێندرێت بۆ ئاماژە کردن بە بەکارھێنەر بۆ بەشدارییەکانیان.",
        "pt-login": "بچۆ ژوورەوە",
        "pt-login-button": "بچۆ ژوورەوە",
+       "pt-login-continue-button": "بەردەوامبوونی چوونەژوورەوە",
        "pt-createaccount": "ھەژمار دروست بکە",
        "pt-userlogout": "بچۆ دەرەوە",
+       "user-mail-no-addy": "ھەوڵی ناردنی ئیمەڵ درا بەبێ ھەبوونی ناونیشانێکی ئیمەیڵ.",
        "changepassword": "تێپەڕوشە بگۆڕە",
        "resetpass_announce": "بۆ کۆتایی چوونە ژوورەوە، دەبێت تێپەڕوشەیەکی نوێ دابنێیت.",
        "resetpass_text": "<!-- تێپه‌ڕه‌وشه‌ی هه‌ژماره‌كه‌ سفر بكه‌ره‌وه‌ -->",
        "retypenew": "تێپەڕوشەی نوێ دوبارە بنووسەوە:",
        "resetpass_submit": "تێپەڕوشە رێکخە و بچۆ ژوورەوە",
        "changepassword-success": "تێپەڕەوشەکەت  گۆڕدرا!",
+       "changepassword-throttled": "تۆ ھەوڵی زۆری چوونەژوورەوەت داوە. \nتکایە $1 چاوەڕوان بە پێش دووبارە ھەوڵدانەوە.",
+       "botpasswords": "تێپەڕ وشەی بۆت",
+       "botpasswords-disabled": "تێپەڕ وشەی بۆتەکان کوژێنرانەوە.",
+       "botpasswords-label-appid": "ناوی بۆت",
        "botpasswords-label-create": "دروستکردن",
        "botpasswords-label-update": "نوێکردنەوە",
        "botpasswords-label-cancel": "ھەڵوەشاندنەوە",
        "botpasswords-label-delete": "سڕینەوە",
        "botpasswords-label-resetpassword": "ڕێکخستنەوەی تێپەڕوشە",
+       "botpasswords-bad-appid": "ناوی بۆت «$1» دروست نییە.",
+       "botpasswords-created-title": "تێپەڕ وشەی بۆت دروست کرا",
+       "botpasswords-updated-title": "تێپەڕ وشەی بۆتەکە نوێ کرایەوە",
+       "botpasswords-deleted-title": "تێپەڕ وشەی بۆت سڕدرایەوە",
        "resetpass_forbidden": "تێپەڕوشەکە ناگۆڕدرێت",
        "resetpass-no-info": "بۆ گەیشتنی راستەوخۆ بەم پەڕە ئەشێ بچیتە ژوورەوە.",
        "resetpass-submit-loggedin": "تێپەڕوشە بگۆڕە",
        "resetpass-submit-cancel": "ھەڵوەشاندنەوە",
        "resetpass-wrong-oldpass": "تێپەڕوشەی ھەنووکەیی یان تێپەڕوشەی کاتی ھەڵەیە.\nوا دیارە تێپەڕوشەکەت بە سەرکەوتوویی گۆڕدراوە یان داوای تێپەڕوشەیەکی نوێت کردووە.",
+       "resetpass-recycled": "تکایە تێپەڕوشەکەت بگۆڕە بە دانەیەکی جیاواز لەوەی ئێستا.",
+       "resetpass-temp-emailed": "تۆ بە تێپەڕوشەیەکی کاتیی ھاتوویتە ژوورەوە. بۆ تەواوکردنی چوونە ژوورەوە تێپەڕوشەیەکی نوێ لێرە دابنێ.",
        "resetpass-temp-password": "تێپەڕوشەی کاتی:",
+       "resetpass-expired": "تێپەڕ وشەکەت بەسەر چووە، تکایە تێپەڕ وشەیەکی نوێ دابنێ بۆ چوونە ژوورەوە",
+       "resetpass-validity-soft": "تێپەڕ وشەکەت دروست نییە: $1",
        "passwordreset": "ڕێکخستنەوەی تێپەڕوشە",
+       "passwordreset-text-one": "ئەم فۆرمە تەواو بکە بۆ بەدەستھێنانی تێپەڕ وشەیەکی کاتیی بە ئیمەیڵ",
+       "passwordreset-text-many": "{{PLURAL:$1|یەکێک لەم بۆشاییانە بڕ بکەرەوە بۆ بەدەستھێنانی تێپەڕ وشەیەکی کاتیی بە ئیمەیڵ}}",
        "passwordreset-username": "ناوی بەکارھێنەری:",
        "passwordreset-domain": "پاوان:",
        "passwordreset-email": "ناونیشانی ئیمەیل:",
        "passwordreset-emailtext-ip": "‫کەسێک (لەوانەیە خۆت، بە ناونیشانی ئایپیی $1) داوای ڕیسێتکردنەوەی تێپەڕوشەکەت لە {{SITENAME}}دا ($4) کردووە. {{PLURAL:$3|ھەژماری بەکارھێنەریی ژێرەوە پەیوەندیی ھەیە|ھەژمارە بەکارھێنەرییەکانی ژێرەوە پەیوەندییان ھەیە}} بەم ناونیشانەی ئیمەیلەوە:\n\n$2\n\n{{PLURAL:$3|ئەم تێپەڕوشە کاتییە|ئەم تێپەڕوشە کاتییانە}} لە {{PLURAL:$5|ڕۆژێک|$5 ڕۆژ}}دا بەسەردەچێت.\nدەبێ بچیتە ژوورەوە و ھەر ئێستا تێپەڕوشەیەکی نوێ ھەڵبژێریت. ئەگەر کەسێکی تر ئەم داواکارییەی کردووە،\nیان ئەگەر تێپەڕوشە سەرەتاییەکەت ھاتووەتەوە بیرت و ئیتر ناتەوێ بیگۆڕی، دەتوانی گوێ بەم پەیامە نەدەیت و ھەر لە تێپەڕوشە کۆنەکەت کەڵک وەربگریت.",
        "passwordreset-emailtext-user": "‫بەکارھێنەر $1 لە {{SITENAME}} ڕیسێتکردنەوەی تێپەڕوشەکەت لە {{SITENAME}}دا ($4) کردووە. {{PLURAL:$3|ھەژماری بەکارھێنەریی ژێرەوە پەیوەندیی ھەیە|ھەژمارە بەکارھێنەرییەکانی ژێرەوە پەیوەندییان ھەیە}} بەم ناونیشانەی ئیمەیلەوە:\n\n$2\n\n{{PLURAL:$3|ئەم تێپەڕوشە کاتییە|ئەم تێپەڕوشە کاتییانە}} لە {{PLURAL:$5|ڕۆژێک|$5 ڕۆژ}}دا بەسەردەچێت.\nدەبێ بچیتە ژوورەوە و ھەر ئێستا تێپەڕوشەیەکی نوێ ھەڵبژێریت. ئەگەر کەسێکی تر ئەم داواکارییەی کردووە، یان ئەگەر تێپەڕوشە سەرەتاییەکەت ھاتووەتەوە بیرت و ئیتر ناتەوێ بیگۆڕی، \nدەتوانی گوێ بەم پەیامە نەدەیت و ھەر لە تێپەڕوشە کۆنەکەت کەڵک وەربگریت.",
        "passwordreset-emailelement": "ناوی بەکارھێنەری: \n$1\n\nتێپەڕوشەی کاتی: \n$2",
-       "passwordreset-emailsentemail": "ئیمەیلێکی ڕیسێتکردنەوەی تێپەڕوشە نێردرا.",
-       "changeemail": "گۆڕینی ناونیشانی ئیمەیل",
-       "changeemail-header": "ناونیشانی ئیمەیلی ھەژمار بگۆڕە",
+       "passwordreset-emailsentemail": "ئەگەر ناونیشانی ئەم ئیمەیڵە بەستراوەتەوە بە ھەژمارەکەتەوە، ئەوا ڕێکخستنەوەی تێپەڕ وشەت بە ئیمەیڵ پێ دەگات.",
+       "passwordreset-emailsentusername": "ئەگەر ناونیشانی ئەم ئیمەیڵە بەستراوەتەوە بە ناوی بەکارھێنەرتەوە، ئەوا ڕێکخستنەوەی تێپەڕ وشەت بە ئیمەیڵ پێ دەگات.",
+       "passwordreset-invalidemail": "ناونیشانی ئیمەیڵی نەگونجاو",
+       "passwordreset-nodata": "نە ئیمەیڵێک یان ناوی بەکارھێنەرێک ھەڵبژێردرا",
+       "changeemail": "گۆڕین یان لابردنی ناونیشانی ئیمەیل",
+       "changeemail-header": "ئەم فۆرمە تەواو بکە بۆ گۆڕینی ناونیشانی ئیمەیڵەکەت. ئەگەر ئارەزووی ئەوە دەکەیت کە ھەر ئیمەیڵێک لە ھەژمارەکەت بکەیتەوە، بۆشایی ئیمەیڵی نوێ بە بەتاڵی بەجێ بھێڵە لەکاتی پاشەکەوتکردنی فۆرمەکە.",
        "changeemail-no-info": "بۆ گەیشتنی راستەوخۆ بەم پەڕە دەبێت بچیتە ژوورەوە.",
        "changeemail-oldemail": "ئەدرەسی ئیمەیڵی ئێستا:",
        "changeemail-newemail": "ناونیشانی ئیمەیلی نوێ:",
+       "changeemail-newemail-help": "ئەم بۆشاییە دەبێت خاڵی بێت ئەگەر دەتەوێت ناونیشانی ئیمەیڵەکەت لابەریت. تۆ ناتوانیت ئیمەیڵی ڕێکخستنەوەی تێپەڕە وشە یاخود ھەر ئیمەیڵێکی تری ئەم ویکییەت پێ بگات ئەگەر ناونیشانی پۆستە ئەلیکترۆنییەکە لاببرێت.",
        "changeemail-none": "(ھیچ)",
        "changeemail-password": "تێپەڕوشەکەت لە {{SITENAME}}:",
        "changeemail-submit": "ئەمەیل بگۆڕە",
+       "changeemail-nochange": "تکایە ناونیشانی ئیمەیڵێکی جیاواز بەکار بھێنە.",
        "bold_sample": "دەقی ئەستوور",
        "bold_tip": "دەقی ئەستوور",
        "italic_sample": "دەقی لار",
        "sig_tip": "واژووەکەت بە مۆری ڕێکەوتەوە",
        "hr_tip": "هێڵی ئاسۆیی (دەگمەن بەکاری بێنە)",
        "summary": "کورتەی دەستکاری:",
-       "subject": "بابەت/سەردێڕ:",
+       "subject": "بابەت:",
        "minoredit": "ئەمە دەستکارییەکی بچووکە",
        "watchthis": "ئەم پەڕەیە بخە ژێر چاودێری",
        "savearticle": "پەڕەکە پاشەکەوت بکە",
        "savechanges": "پاشەکەوتکردنی گۆڕانکارییەکان",
+       "publishpage": "بڵاوکردنەوەی پەڕە",
+       "publishchanges": "پاشەکەوتکردنی گۆڕانکارییەکان",
        "preview": "پێشبینین",
        "showpreview": "پێشبینین نیشان بدە",
        "showdiff": "گۆڕانکارییەکان نیشان بدە",
+       "blankarticle": "<strong>ئاگاداری:</strong> ئەو پەڕەیەی کە ھەوڵی دروستکردنی دەدەیت واڵایە. ئەگەر کرتە لەسەر «{{int:savearticle}}» بکەیت دووبارە، پەڕەکە بەبێ ھیچ ناوەڕۆکێک دروست دەبێت.",
        "anoneditwarning": "<strong>ھۆشیار بە:</strong> نەڕۆیشتووتەتە ژوورەوە. ھەر دەستکارییەک بکەیت ناونیشانی IPیەکەت بۆ ھەموو کەسێک دیار دەبێت. بەڵام ئەگەر <strong>[$1 بچیتە ژوورەوە]</strong> یان <strong>[$2 ھەژمارێک دروست بکەیت]</strong>، دەستکارییەکانت بە ناوی بەکارھێنەرییەکەتەوە بڵاو دەبێتەوە و لە چەند قازانجی تریشی ھەیە.",
        "anonpreviewwarning": "«نەڕۆشتوویتە ژوورەوە. پاشەکەوتکردن، ئەدرەسی IPەکەت لە مێژووی دەستکاریی ئەم پەڕە تۆمار دەکات.»",
        "missingsummary": "'''وە بیر خستنەوە:''' پوختەیەکت نەنووسیوە بۆ چۆنیەتی گۆڕانکارییەکەت.\nئەگەر جارێکی تر پاشکەوت کردن لێبدەی، بێ پوختە تۆمار دەکرێ.",
+       "selfredirect": "<strong>ئاگاداری:</strong> تۆ خەریکی گواستنەوەی ئەم پەڕەیەیت بۆ سەر خۆی. لەوانەیە خەریکی گواستنەوەی پەڕەیەکی ھەڵە بیت یان ھەوڵی گواستنەوە دەدەیت بۆ ئامانجێکی ھەڵە. \nئەگەر دەەبارە کرتە لەسەر «{{int:savearticle}}» بکەیتەوە، ڕەوانەکەرەکە دروست دەکرێت بەھەرحاڵ.",
        "missingcommenttext": "تکایە لە خوارەوە شرۆڤەیەک بنووسە.",
        "missingcommentheader": "'''بیرهێنانەوە:''' بۆ ئەم بۆچوونەت سەردێڕ\\بابەت ڕاچاو نەکردووە.\nئەگەر دیسان «{{int:savearticle}}» لێبدەی، دەستکاریەکەت بێ سەردێڕ یان بابەت پاشەکەوت دەبێ.",
        "summary-preview": "پێشبینینی کورتە:",
-       "subject-preview": "پێشبینینی بابەت/سەردێڕ:",
+       "subject-preview": "پێشبینینی بابەت:",
+       "previewerrortext": "ھەڵەیەک دروست بوو لەکاتی ھەوڵدان بۆ بینینی دەستکارییەکانت.",
        "blockedtitle": "بەکارھێنەر بەربەست کراوە",
        "blockedtext": "'''ناوی بەکارهێنەری یان ئای‌پی ئەدرەسی تۆ بەربەست‌ کراوە.'''\n\nبەربەست لە لایەن $1 کراوە.\nهۆکاری بەربەست کردن ''$2''ە.\n\n* دەستپێکی بەربەست‌کران: $8\n* کۆتایی هاتنی بەربەست‌کران: $6\n* بابەتی بەربەست: $7\n\nبۆ وتووێژ سەبارەت بە بەربەست‌کرانەکە دەبێ پەیوەندی بکەی بە $1 یان یەکێ دی لە [[{{MediaWiki:Grouppage-sysop}}|بەڕێوبەران]].\nلە بیرت بێ تاکوو ئیمەیل ئەدرەسێکی بڕوا پێ‌کراو لە [[Special:Preferences|ھەڵبژاردەکانی بەکارھێنەر]] ڕاچاو نەکەی، نابێت لە هەلی «ئیمەیل ناردن بۆ ئەم بەکارهێنەرە» کەڵک وەر بگری؛ کەڵک وەرگرتن لەوە بەربەست نەکراوە بۆت.\n\nئای‌پی ئەدرەسی ئێستای تۆ $3 و پێناسەی بەربەست‌کراو #$5.\nتکایە لە هەر پرس و داواکاریەکت‌دا هەموو وردەکاریەکانی سەرەوە بگونجێنە.",
        "autoblockedtext": "ناونیشانی IPی تۆ بە شێوەی خۆکارانە بەرگیری لێ کراوە چوونکە بەکارھێنەرێکی دیکە بە خراپی بە کاری ھێناوە و بە دەستی $1 بەرگیری لێ کراوە.\nبەم ھۆکارەوە:\n\n:<em>$2</em>\n\n* دەست پێ کردنی بەرگیری: $8\n* بە سەر چوونی بەرگیری: $6\n* Intended blockee: $7\n\nدەتوانیت پەیوەندی بکەیت بە $1 یان یەکێکی دیکە لە [[{{MediaWiki:Grouppage-sysop}}|بەڕێوەبەران]] بۆ وتووێژ لە سەر بەرگیرییەکە.\n\nتێ بگە کە ناتوانیت ئامرازی «ئیمێل بنێرە بۆ ئەم بەکارھێنەرە» بە کار بھێنیت مەگەر ئەوەی کە پێشتر لە [[Special:Preferences|ھەڵبژاردەکانی بەکارھێنەر]]تدا ناونیشانێکی گونجاوی ئیمێلت تۆمار کردبێت و بەرگیریت لێ نەکرابێت لە بەکارھێنانی ئەو ئامرازەش.\n\nناونیشانی IPی ئێستای تۆ $3ـە و پێناسەی یەرگیرییەکە #$5ـە.\nتکایە ھەموو وردەکارییەکانی سەرەوە ھەبێت لە ھەر پرس و داوایک کە دەیکەیت.",
        "accmailtext": "تێپەڕوشەیەک کە بە هەڕەمەکی بۆ [[User talk:$1|$1]] دروست کرا، نێررا بۆ $2. دەتوانیت لە پەڕەی <em>[[Special:ChangePassword|گۆڕینی تێپەڕوشەدا]]</em> لە کاتی چوونەژوورەوەدا بیگۆڕی.",
        "newarticle": "(نوێ)",
        "newarticletext": "بە دوای بەستەری پەڕەیەک کەوتووی کە ھێشتا دروست نەکراوە.\nبۆ دروست کردنی پەڕەکە، لە چوارچێوەکەی خوارەوە دەست بکە بە تایپ کردن. (بۆ زانیاری زورتر\n[$1 یارمەتی] ببینە).\nئەگەر بە ھەڵەوە ھاتویتە ئێرە، لە سەر دوگمەی '''back'''ی وێبگەڕەکەت کلیک بکە.",
-       "anontalkpagetext": "----''ئەمە لاپەڕەی وتووێژە بۆ بەکارهێنەرێکی نەناسراوە کە هێشتا هەژمارەی درووست‌نەکردووه یان کەڵکی‌ لێ وەرناگرێ .\nلەبەر ئەوە مەجبوورین ئای‌پی ئەدرەسەکی ژمارەیی بۆ ناساندنی بەکار بێنین.\nئای‌پی ئەدرەسی وا لەوانەیه لە لایەن چەندین بەکارهێنەروە بەکاربێت.\nئەگەر تۆ بەکارهێنەرێکی نەناسراوی و هەست ئەکەی ئەم لێدوانە پەیوەندی بە تۆوە نیە تکایە [[Special:CreateAccount|ھەژمارێکی نوێ دروست بکە]] یان [[Special:UserLogin|بچۆ ژوورەوە]] لەبەر ئەوەی لەداهاتوودا دەگەڵ بەکارهێنەرانی‌ نەناسراوی دی تێکەڵ نەکرێیت. ''",
+       "anontalkpagetext": "----\n<em>ئەمە لاپەڕەی وتووێژە بۆ بەکارهێنەرێکی نەناسراوە کە هێشتا هەژمارەی درووست نەکردووه یان کەڵکی‌ لێ وەرناگرێ.</em>\nلەبەر ئەوە ناچارین ناونیشانی ئای پی ژمارەیی بۆ ناساندنی بەکار بێنین.\nناونیشانی ئای پی وا لەوانەیه لە لایەن چەندین بەکارهێنەری ترەوە بەکاربێت.\nئەگەر تۆ بەکارهێنەرێکی نەناسراویت و هەست دەکەیت ئەم لێدوانە پەیوەندی بە تۆوە نییە، تکایە [[Special:CreateAccount|ھەژمارێکی نوێ دروست بکە]] یان [[Special:UserLogin|بچۆ ژوورەوە]] بۆ تێکەڵ نەبوونت لەگەڵ بەکارھێنەرانی نەناسراوی تردا لە داھاتوودا.",
        "noarticletext": "ھەنووکە ھیچ دەقێک لەم پەڕەیەدا نییە.\nدەتوانیت لە پەڕەکانی تردا [[Special:Search/{{PAGENAME}}|بۆ ئەم سەرناوە بگەڕێیت]]،\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} لە لۆگە پەیوەندیدارەکاندا بگەڕێیت]،\nیان [{{fullurl:{{FULLPAGENAME}}|action=edit}} ئەم پەڕەیە دروست بکەیت]</span>.",
        "noarticletext-nopermission": "ھەنووکە ھیچ دەقێک لەم پەڕەیەدا نییە.\nدەتوانی لە پەڕەکانی تردا [[Special:Search/{{PAGENAME}}|بۆ ئەم ناوە بگەڕێی]]، یان <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} لە لۆگە پەیوەندیدارەکاندا بگەڕێی]</span>، بەڵام ناتوانی ئەم پەڕەیە دروست بکەی.",
+       "missing-revision": "بەسەرداچوونەوەی #$1 پەڕەی «{{FULLPAGENAME}}» بوونی نییە.\n\nئەمە ھەندێک جار ھۆکاری ئەوەیە کە مێژووەکەی بەسەرچووە یاخود پەڕەکە سڕدراوەتە.\nوردەکارییەکان دەتوانرێن ببینرێن لە [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} لۆگی سڕینەوەدا].",
        "userpage-userdoesnotexist": "ھەژماری بەکارھێنەریی «$1» تۆمار نەکراوە.\nتکایە دڵنیا ببەرەوە ئەگەر دەتھەوێت ئەم پەڕەیە دروست یان دەستکاری بکەیت.",
        "userpage-userdoesnotexist-view": "ھەژماری بەکارھێنەریی «$1» تۆمار نەکراوە.",
        "blocked-notice-logextract": "ھەنووکە ئەم بەکارھێنەرە بەربەست کراوە.\nدوایین بابەتی لۆگی بەربەستن لە ژێرەوە ھاتووە:",
-       "clearyourcache": "تێبینی:''' لە دوای پاشەکەوت کردن، لەوانەیە  بۆ بینینی گۆڕانکارییەکان پێویست بێ cacheی وێبگەڕەکەت پاکبکەیتەوە.\n* '''Firefox / Safari:''' دوگمەی ''Shift'' بگرە کاتێک لەسەر ''Reload''دا کرتە دەکەی، یان ھەرکام لە ''Ctrl-F5'' یان ''Ctrl-R'' لێبدە (''⌘-R'' لەسەر Mac دا)\n* '''Google Chrome:''' دوگمەکانی ''Ctrl-Shift-R'' لێبدە  (''⌘-Shift-R'' لەسەر Mac دا)\n* '''Internet Explorer:''' دوگمەی ''Ctrl'' بگرە کاتێک لەسەر  ''Refresh''دا کرتە دەکەی، یان ''Ctrl-F5'' لێبدە\n* '''Opera:''' لە ڕێگەی ''Tools → Preferences'' ەوە cacheەکە بسڕەوە.",
+       "clearyourcache": "<strong>تێبینی:</strong> لە دوای پاشەکەوت کردن، لەوانەیە  بۆ بینینی گۆڕانکارییەکان پێویست بێ کاشی وێبگەڕەکەت پاکبکەیتەوە.\n* '''Firefox / Safari:''' دوگمەی ''Shift'' بگرە کاتێک لەسەر ''Reload''دا کرتە دەکەی، یان ھەرکام لە ''Ctrl-F5'' یان ''Ctrl-R'' لێبدە (''⌘-R'' لەسەر Mac دا)\n* '''Google Chrome:''' دوگمەکانی ''Ctrl-Shift-R'' لێبدە  (''⌘-Shift-R'' لەسەر Mac دا)\n* '''Internet Explorer:''' دوگمەی ''Ctrl'' بگرە کاتێک لەسەر  ''Refresh''دا کرتە دەکەی، یان ''Ctrl-F5'' لێبدە\n* '''Opera:''' لە ڕێگەی ''Tools → Preferences'' ەوە cacheەکە بسڕەوە.",
        "usercssyoucanpreview": "'''سەرچەشن:''' «{{int:showpreview}}» بەکاربێنە بۆ تاقی‌کردنەوەی CSS نوێ‌کەت، پێش پاشەکەوت‌کردن.",
        "userjsyoucanpreview": "'''سەرچەشن:''' «{{int:showpreview}}» بەکاربێنە بۆ تاقی‌کردنەوەی جاڤاسکریپتە نوێ‌کەت، پێش پاشەکەوت‌کردن.",
        "usercsspreview": "<strong>لە بیرت ببێت کە تەنھا خەریکی پێشبینینی CSSـەکەت دەبینیت.\nھێشتا پاشەکەوەت نەکراوە!</strong>",
        "previewnote": "'''لە بیرت نەچێت ئەمە تەنیا پێشبینینە.'''\nگۆڕانکارییەکانت ھێشتا پاشەکەوت نەکراون!",
        "continue-editing": "چوونە سەر بەشی دەستکاریکردن",
        "previewconflict": "ئەم پێشبینینە بە تۆ نیشان ئەدات ئەو دەقەی لە شوێنی دەستکاری سەرەوە داتناوە چۆن بەرچاو ئەکەوێت ئەگەر پاشەکەوتی بکەیت.",
-       "session_fail_preview": "'''ببوورە! ناتوانین دەستکارییەکەت پێواژۆ بکەین بە ھۆی لەدەستدانی session data.'''\nتکایە دیسان ھەوڵبدەوە.\nئەگەر ھێشتا کار ناکات، [[Special:UserLogout|چوونەدەرەوە]] و گەڕانەوەژوورەوە تاقی بکەوە.",
+       "session_fail_preview": "ببوورە! ناتوانین دەستکارییەکەت پێواژۆ بکەین بە ھۆی لەدەستدانی زانیاری و داتاکانی ئەم کۆرسە.\nلەوانەیە ھەژمارەکەت کرابێتە دەرەوە. <strong>تکایە دڵنیا بکەرەوە کە ھێشتا لە ژوورەوەیت و دووبارە ھەوڵ بدەرەوە.</strong>\nئەگەر ھێشتا کار ناکات، [[Special:UserLogout|چوونەدەرەوە]] و گەڕانەوەژوورەوە تاقی بکەوە، دواتریش ئەگەر ھێشتا ڕێگەت نەداوە، ڕێگە بە براوسەرەکەت بدە کە ''کوکی'' لەم سایەتەوە وەربگرێت.",
        "session_fail_preview_html": "'''ببوورە! ناتوانین دەستکارییەکەت پێواژۆ بکەین بە ھۆی لەدەستدانی session data.'''\n\n''لەبەر ئەوەی {{SITENAME}} ڕێگەی داوە بە raw HTML، بۆ بەرگری بەرامبەر بە هێرشەکانی جاڤاسکریپت، پێشبینین شاردراوەتەوە.''\n\n'''ئەگەر ئەمە ھەوڵێکی دەستکاریکردنی ڕەوایە، تکایە دیسان ھەوڵبدەوە.'''\nئەگەر ھێشتا کار ناکات، [[Special:UserLogout|چوونە دەرەوە]] گەڕانەوەژوورەوە تاقی بکەوە.",
        "token_suffix_mismatch": "'''دەستکاریەکەت پەسەند نەکرا لەبەر ئەوەی ڕاژەخواز یان وێبگەڕەکەت نووسەکانی خاڵبەندی لەیەک پچڕاندوە.'''<br />\nدەستکاریەکەت بۆ بەرگری لە تێکەڵ‌بوونی دەقی لاپەڕەکە وەر نەگیرا.<br />\nئەمە بڕێ‌جار کاتێ ڕوو ئەدات کە لە خزمەتی پرۆکسی سەر وێب کەڵک وەر بگریت.",
+       "edit_form_incomplete": "<strong>ھەندێک بەشی دەستکارییەکانت بە سێرڤەرەکەمان نەگەیشت. دووبارە سەیری دەستکارییەکانت بکە بۆ دڵنیا بوون لە تەواوییان و دووبارە ھەوڵ بدەرەوە.</strong>",
        "editing": "دەستکاریکردنی $1",
        "creating": "دروستکردنی $1",
        "editingsection": "دەستکاریکردنی $1 (بەش)",
        "copyrightwarning": "تکایە ئاگادار بە کە هەموو بەشدارییەکان لە {{SITENAME}} وا فەرز دەکرێت کە لە ژێر  $2دا بڵاودەبنەوە (سەیری $1 بکە بۆ وردەکاریەکان).\nئەگەر ناتەوێ نووسراوەکانت بە بێبەزەیی دەستکاری بکرێن و بە دڵخواز دابەشبکرێنەوە، مەینێرە بۆ ئێرە.<br />\nھەروەھا تۆ بەڵێنمان پێدەدەی کە خۆت ئەمەت نووسیوە یان لە پاوانێکی گشتی (public domain) یان سەرچاوە ئازادەکانی وەک ئەو وەرتگرتووە.\n'''ئەو کارانە کە مافی لەبەرگرتنەوەیان پارێزراوەکان بە بێ وەرگرتنی ئیجازە مەنێرە!'''",
        "copyrightwarning2": "ئاگادار بە کە هەموو بەشدارییەکان لە {{SITENAME}} لەوانەیە بەدەستی بەشداربووانی دیکەوە دەستکاری بکرێن، بگۆڕدرێن یا بسڕێنەوە.\nئەگەر ناتەوێ نووسراوەکانت بێبەزەیی دەستکاری بکرێن، ھەر مەینێرە بۆ ئێرە.<br />\nھەروەھا تۆ بەڵێنمان پێدەدەی کە خۆت ئەمەت نووسیوە یان لە پاوانێکی گشتی (public domain) یان سەرچاوە ئازادەکانی وەک ئەو وەرتگرتووە (سەیری $1 بکە بۆ وردەکاریەکان).\n'''ئەو کارانە کە مافی لەبەرگرتنەوەیان پارێزراوەکان بە بێ وەرگرتنی ئیجازە مەنێرە!'''",
        "longpageerror": "'''ھەڵە: ئەو دەقە تۆ ناردووتە {{PLURAL:$1|یەک کیلۆبایت|$1 کیلۆبایت}} درێژە، کە درێژترە لە زۆرینەی {{PLURAL:$2|یەک کیلۆبایت|$2 کیلۆبایت}}.'''\nئەمە پاشەکەوت ناکرێت.",
-       "readonlywarning": "<strong>ئاگادارÛ\8c: Ø¯Ø§ØªØ§Ø¨Û\95Û\8cس Ø¨Û\86 Ú\86اکسازÛ\8c Ø¯Ø§Ø®Ø±Ø§Ù\88Û\95Ø\8c Ø¨Û\86Û\8cÛ\95 Ø¦Û\8eستا Ù\86اتÙ\88اÙ\86Û\8c Ø¯Û\95ستکارÛ\8cÛ\95کاÙ\86ت Ù¾Ø§Ø´Û\95Ú©Û\95Ù\88ت Ø¨Ú©Û\95Û\8cت.</strong>\nدÛ\95تÙ\88اÙ\86Û\8cت Ø¯Û\95Ù\82Û\95Ú©Û\95ت Ú©Û\86Ù¾Û\8c Ø¨Ú©Û\95Û\8cت Ø¨Û\86 Ù\81اÛ\8cÙ\84Û\8eک و ھەڵی بگریت بۆ دوایی.\nئەو بەڕێوەبەرەی کە دای خستووە، ئەم هۆکارەی دەستنیشان کردووە: $1",
+       "readonlywarning": "<strong>ئاگادارÛ\8c: Ø¨Ù\86Ú©Û\95Û\8c Ø²Ø§Ù\86Û\8cارÛ\8c Ø¨Û\86 Ú\86اکسازÛ\8c Ø¯Ø§Ø®Ø±Ø§Ù\88Û\95Ø\8c Ø¨Û\86Û\8cÛ\95 Ø¦Û\8eستا Ù\86اتÙ\88اÙ\86Û\8c Ø¯Û\95ستکارÛ\8cÛ\95کاÙ\86ت Ù¾Ø§Ø´Û\95Ú©Û\95Ù\88ت Ø¨Ú©Û\95Û\8cت.</strong>\nدÛ\95تÙ\88اÙ\86Û\8cت Ø¯Û\95Ù\82Û\95Ú©Û\95ت Ù\84Û\95بÛ\95ر Ø¨Ú¯Ø±Û\8cتÛ\95Ù\88Û\95 Ø¨Û\86 Ù¾Û\95Ú\95Ú¯Û\95Û\8cÛ\95ک و ھەڵی بگریت بۆ دوایی.\nئەو بەڕێوەبەرەی کە دای خستووە، ئەم هۆکارەی دەستنیشان کردووە: $1",
        "protectedpagewarning": "'''وشیار بە: ئەم پەڕە پارێزراوە بۆ ئەوی تەنیا ئەو بەکارھێنەرانە کە مافەکانی بەڕێوەبەرایەتییان ھەیە بتوانن دەستکاریی بکەن.'''\nدوایین لۆگ بۆ ژێدەر لە خوارەوەدا ھاتووە:",
        "semiprotectedpagewarning": "'''ئاگاداری:''' ئەم پەڕە داخراوە بۆ ئەوی تەنھا بەکارھێنەرە تۆمارکراوەکان بتوانن دەستکاریی بکەن.\nدوایین لۆگ بۆ ژێدەر لە خوارەوەدا ھاتووە:",
-       "cascadeprotectedwarning": "'''ئاگاداری:''' ئەم لاپەڕە داخراوە بۆیە تەنها ئەو کەسانەی مافی بەڕێوبەرایەتی‌یان هەیە ئەتوانن دەستکاری بکەن، چۆنکا ئەمە {{PLURAL:$1|لاپه‌ڕه‌|لاپه‌ڕانه‌}} لە زنجیرەی پارێزراوەکانی لە خۆ گرتووە‌:",
+       "cascadeprotectedwarning": "'''ئاگاداری:''' ئەم لاپەڕە داخراوە بۆ ئەوەی تەنھا ئەو کەسانەی کە مافی بەڕێوبەرایەتییان هەیە بتوانن دەستکاری بکەن، چوونکە ئەم {{PLURAL:$1|لاپه‌ڕه‌|لاپه‌ڕانه‌}} لە زنجیرەی پارێزراوەکانی لە خۆ گرتووە‌:",
        "titleprotectedwarning": "'''ئاگاداری: ئەم پەڕە داخراوە، بۆئەوەی بۆ درووست‌کردنی [[Special:ListGroupRights|مافە تایبەتەکانت]] پێویستن.'''\nبۆ چاوانە دوایین لۆگ لە خوارەوەدا ھاتووە:",
        "templatesused": "ئەو {{PLURAL:$1|داڕێژەیە کە لەم پەڕەیەدا بە کارھێنراوە|داڕێژانە کە لەم پەڕەیەدا بە کارھێنراون}}:",
        "templatesusedpreview": "ئەو {{PLURAL:$1|داڕێژەیە کە لەم پێشبینینەدا بە کارھێنراوە|داڕێژانە کە لەم پێشبینینەدا بە کارھێنراون}}:",
        "nocreate-loggedin": "ئیجازەی دروست کردنی پەڕەی نوێت نیە.",
        "sectioneditnotsupported-title": "بەش دەستکاریکردنی پشتیوانی ناکرێ",
        "sectioneditnotsupported-text": "دەستکاریکردنی بەش لە پەڕەدا پشتیوانی ناکرێ.",
-       "permissionserrors": "ھەڵەی ئیجازەکان",
+       "permissionserrors": "ھەڵە لە بە دەست ھێنان",
        "permissionserrorstext": "مافی ئەنجامی ئەوەت نیە لەبەر ئەم {{PLURAL:$1|هۆکار|هۆکارانە}} :",
        "permissionserrorstext-withaction": "دەسەڵاتت نییە بۆ $2، لەبەر ئەم {{PLURAL:$1|ھۆکارە|ھۆکارانە}}ی خوارەوە:",
        "recreate-moveddeleted-warn": "'''ھۆشیار بە: خەریکی پەڕەیەک دروست‌ دەکەیتەوە کە لە پێشدا سڕاوەتەوە.'''\n\nئەمە لەبەر چاو بگرە کە دەستکاریکردنی ئەم پەڕەیە بەقازانجە یان نا.\nلۆگی سڕینەوە و گواستنەوەی ئەم پەڕەیە بۆ سانایی لێرەدا ھاتووە:",
        "moveddeleted-notice": "ئەم پەڕەیە سڕاوەتەوە.\nلۆگی سڕینەوە و گواستنەوە بۆ پەڕەکە لە ژێرەوە دابین کراوە.",
+       "moveddeleted-notice-recent": "ببورە، ئەم پەڕەیە بەم زووانە سڕدراوەتەوە (لە ماوەی ٢٤ کاتژمێری پێشوودا). \nلۆگی سڕینەوە و ڕەوانەکردنی پەڕەکە بەردەستن لە خوارەوە لە پەڕاوێزەکاندا.",
        "log-fulllog": "لۆگی تەواو ببینە",
        "edit-hook-aborted": "دەستکاری لە لایەن قولاپەوە ھەڵوەشێنرایەوە.\nھۆکارەکەی لەبەر دەست نییە.",
        "edit-gone-missing": "توانای نوێ‌کردنەوەی لاپەڕەکە نیە.<br />\nلەوە دەچی سڕدرابێتەوه.‌",
        "edit-conflict": "کێشەی دەستکاری.",
        "edit-no-change": "دەستکاریەکەت بەرچاو نەخرا، لەبەر ئەوەی هیچ گۆڕانکارییەکت لەسەر دەقەکە نەکردووە.",
+       "postedit-confirmation-created": "پەڕەکە دروست کرا.",
+       "postedit-confirmation-restored": "پەڕەکە ھێنرایەوە.",
        "postedit-confirmation-saved": "دەستکارییەکەت پاشەکەوت کرا.",
        "edit-already-exists": "تواناییی دروستکردنی پەڕەی نوێ نییە.\nئەمە پەڕەیە پێشتر هەبووە.",
        "defaultmessagetext": "دەقی پەیامی هەمیشەیی",
        "invalid-content-data": "دراوەی ناوەرۆکی نادروست",
-       "editwarning-warning": "بەجێ‌هێشتنی ئەم لاپەڕەیە دەبێتە هۆی لە‌دەست چوونی هەموو ئەو گۆڕانکاریانەی کردووتە.",
+       "content-not-allowed-here": "«$1» ڕێگە پێنەدراوە لەسەر پەڕەی [[$2]]",
+       "editwarning-warning": "بەجێھێشتنی ئەم لاپەڕەیە دەبێتە هۆی لە‌دەستدانی هەموو ئەو گۆڕانکاریانەی کە ئەنجامت داون. ئەگەر لە ژوورەوەیت، دەتوانیت ئەم ئاگادارییە لابەریت لە ھەڵبژاردەی بەکارھێنەرت.",
        "content-model-wikitext": "ویکیدەق",
        "content-model-text": "دەقی ساکار",
        "content-model-javascript": "جاڤاسکریپت",
        "content-model-css": "سی ئێس ئێس",
+       "deprecated-self-close-category": "ئەو پەڕانەی کە تاگی ئێچ تی ئێم ئێڵی خۆ-داخراوی ھەڵە بەکاردەھێنن",
+       "duplicate-args-warning": "<strong>ئاگاداری:</strong> ن [[:$1]] بانگی [[:$2]] دەکات بە بەکارھێنانی زیاتر لە یەک بەھا بۆ پارامەتری «$3.» تەنھا کۆتا بەھای کە پێشکەش کراوە بەکار دەھێندرێت.",
        "expensive-parserfunction-warning": "'''ئاگاداری:''' ئەم لاپەڕە ژمارەیەکی زۆر بانگ‌کەری فەنکشێنی لێک‌کەرەوەی لەخۆ گرتوو.<br /><br />\nئەوە دەبێ کەمتر بێت لە $2 {{PLURAL:$2|بانگ‌کەردن|بانگ‌کەردن}} کە ئێستا {{PLURAL:$1|بانگ‌کردنی|بانگ‌کردنی}} تێدایە.",
        "expensive-parserfunction-category": "ئەو لاپەڕانەی  ژمارەیەکی زۆر بانگ‌کەری فەنکشێنی لێک‌کەرەوەیان لەخۆ گرتووە.",
        "post-expand-template-inclusion-warning": "'''ئاگاداری:''' قەبارەی داڕێژەکە زۆر گەورەیە.\nلەوانەیە ھەندێک لە داڕێژەکان لەخۆنەگرێتەوە.",
        "undo-success": "دەکرێ دەستکاریەکە پووچەڵبکرێتەوە.\nتکایە چاو لەو هەڵسەنگاندنەی خوارەوە بکە تا دڵنیا بیت ئەمە ئەوەیە کە‌ دەتویست بیکەی و دواتر گۆڕانکارییەکانی خوارەوە پاشەکەوت بکە بۆ تەواوکردنی پووچەڵکردنەوەکە.",
        "undo-failure": "لەبەر کێشەی دەست‌تێ‌وەردان، ناتوانی دەستکاریەکە ئەنجام‌نەدراو بکەیت.",
        "undo-norev": "ناتوانی دەستکاریەکە ئەنجام‌نەدراو بکەی لەبەر ئەوەی بوونی نیە یا سڕدراوەتەوە.",
+       "undo-nochange": "وا دیارە دەستکارییەکە پووچەڵ کراوەتەوە.",
        "undo-summary": "گەڕاندنەوەی پێداچوونەوەی $1 لە لایەن [[Special:Contributions/$2|$2]] ([[User talk:$2|لێدوان]])",
+       "undo-summary-username-hidden": "پوچەڵکردنەوەی دەستکاری $1 لەلایەن بەکارھێنەرێکی شاردراوەوە.",
        "cantcreateaccount-text": "درووست‌کردنی هەژمارە بۆ ناونیشانی ئای‌پی ('''$1''') لە لایەن [[User:$3|$3]] داخراوە.<br /><br />\n$3 هۆکاری \"$2\" خستوەتەڕوو",
        "viewpagelogs": "لۆگەکانی ئەم پەڕەیە ببینە",
        "nohistory": "هیچ مێژوویەکی دەستکاری نییە بۆ ئەم پەڕەیە.",
        "editusergroup": "گرووپەکانی بەکارھێنەر دەستکاری بکە",
        "editinguser": "گۆڕینی مافە بەکارھێنەرییەکانی {{GENDER:$1|بەکارھێنەر}} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "گرووپە بەکارھێنەرییەکان دەستکاری بکە",
+       "userrights-viewusergroup": "بینینی گرووپەکانی {{GENDER:$1|بەکارھێنەر}}",
        "saveusergroups": "گرووپەکانی بەکارھێنەر پاشەکەوت بکە",
        "userrights-groupsmember": "ئەندامە لە:",
        "userrights-groupsmember-auto": "ئەندامی ناڕاشکاوە لە:",
        "right-override-export-depth": "هەناردنی لاپەڕەکان کە لاپەڕەکانی بەستەر پێ‌دراو تا قووڵایی 5 لەخۆ بگرێت",
        "right-sendemail": "ناردنی ئیمەیل بۆ بەکارھێنەرانی تر",
        "right-managechangetags": "دروستکردن و سڕینەوەی [[Special:Tags|تاگەکان]] لە بنکەدراوە",
+       "grant-group-email": "ناردنی ئیمەیل",
+       "grant-sendemail": "ناردنی ئیمەیل بۆ بەکارھێنەرانی تر",
        "newuserlogpage": "لۆگی دروستکردنی بەکارھێنەر",
        "newuserlogpagetext": "ئەمە لۆگێکی دروستکردنی بەکارھێنەرە.",
        "rightslog": "لۆگی مافەکانی بەکارھێنەر",
        "action-viewmywatchlist": "دیتنی پێرستی چاودێریت",
        "action-viewmyprivateinfo": "زانیارییە تایبەتییەکانت ببینە",
        "action-editmyprivateinfo": "دەستکاری زانیارییە تایبەتییەکانت بکە",
+       "action-purge": "پاکسازی ئەم پەڕەیە بکە",
        "nchanges": "$1 {{PLURAL:$1|گۆڕانکاری}}",
        "enhancedrc-history": "مێژوو",
        "recentchanges": "دوایین گۆڕانکارییەکان",
        "emailpagetext": "دەتوانی لەم فۆرمەی ژێرەوە بۆ ناردنی ئیمەیلێک بۆ ئەم {{GENDER:$1|بەکارھێنەر}}ە کەڵک وەربگریت.\nئەو ناونیشانە ئیمەیلە لە [[Special:Preferences|ھەڵبژاردەکانی بەکارھێنەر‌یتدا]] نووسیوتە، لە ناونیشانی «لەلایەن»ی (From) ئیمەیلەکەدا نیشان دەدرێت، کە وایە بەکارھێنەری وەرگر دەتوانێ ڕاستەوخۆ وەڵامت بداتەوە.",
        "defemailsubject": "ئیمەیلی {{SITENAME}} لە بەکارھێنەر «$1»ەوە",
        "usermaildisabled": "ئیمەیڵی بەکارهێنەر لەکاردانیە",
+       "usermaildisabledtext": "ناتوانیت ئیمەیڵ بۆ بەکارھێنەرانی تر بنێریت لەسەر ئەم ویکیپیدیایە",
        "noemailtitle": "هیچ ناونیشانێکی ئی‌مەیل نییە",
        "noemailtext": "ئەم بەکارھێنەرە ناونێشانێکی گونجاوی ئیمێلی دەستنیشان نەکردووە.",
        "nowikiemailtext": "ئەم بەکارهێنەرە تایبەتمەندیی وەرنەگرتنی ئی‌مەیل لە بەکارهێنەرانی دیکەی هەلبژاردووە.",
        "enotif_lastvisited": "بۆ بینینی ھەموو گۆرانکارییەکانی پاش دوایین سەردانت $1 ببینە.",
        "enotif_lastdiff": "بۆ بینینی ئەم گۆڕانکارییە $1 ببینە.",
        "enotif_anon_editor": "بەکارھێنەری نەناسراو $1",
-       "enotif_body": "â\80«$WATCHINGUSERNAMEÛ\8c Ø¨Û\95Ú\95Û\8eزØ\8c\n\n$PAGEINTRO $NEWPAG\n\nÚ©Ù\88رتÛ\95Û\8c Ø¯Û\95ستکارÛ\8cÛ\8cÛ\95Ú©Û\95Û\8c: $PAGESUMMARY $PAGEMINOREDIT\n\nÙ¾Û\95Û\8cÙ\88Û\95Ù\86دÛ\8c Ù\84Û\95Ú¯Û\95Úµ Ø¯Û\95ستکارÛ\8cÚ©Û\95ر:\nÙ\86اÙ\85Û\95: $PAGEEDITOR_EMAIL\nÙ\88Û\8cÚ©Û\8c: $PAGEEDITOR_WIKI\n\nتا Ø³Û\95رداÙ\86Û\8c Ø¦Û\95Ù\85 Ù¾Û\95Ú\95Û\95Û\8cÛ\95 Ù\86Û\95Ú©Û\95Û\8cتØ\8c Ú¯Û\86Ú\95اÙ\86کارÛ\8cÛ\8cÛ\95کاÙ\86Û\8c Ø¯Ø§Ú¾Ø§ØªÙ\88Ù\88Û\8c Ù¾Û\95Ú\95Û\95Ú©Û\95ت Ù¾Û\8e Ú\95اÙ\86اگÛ\95Û\8cÛ\8eÙ\86درÛ\8eت. Ù\87Û\95رÙ\88Û\95ھا Ø¯Û\95تÙ\88اÙ\86Û\8c Ø¦Ø§ÚµØ§Ú©Ø§Ù\86Û\8c Ú\95اگÛ\95Û\8cاÙ\86دÙ\86 Ù\84Û\95 Ù¾Û\95Ú\95Û\95Û\8c Ú\86اÙ\88دÛ\8eرÛ\8cÛ\8cÛ\95Ú©Û\95تدا Ù\84Û\95 Ø³Û\95رÛ\95تاÙ\88Û\95 Ú\95Û\8eÚ© Ø¨Ø®Û\95Û\8cتÛ\95Ù\88Û\95.\n\nبÛ\95 Ø³Ù¾Ø§Ø³Û\95Ù\88Û\95Ø\8c Ø³Û\8cستÛ\95می ڕاگەیاندنی {{SITENAME}}\n\n--\nبۆ گۆڕینی رێکخستنەکانی ڕاگەیاندن بە ئیمەیل، بڕوانە\n{{canonicalurl:{{#special:Preferences}}}}\n\nبۆ گۆڕینی ڕێکخستنەکانی پێرستی چاودێرییەکەت، بڕوانە\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nبۆ سڕینەوەی پەڕەکە لە پێرستی چاودێرییەکەت، بڕوانە\n$UNWATCHURL\n\nکاردانەوە و یارمەتیی زۆرتر:\n$HELPPAGE",
+       "enotif_body": "â\80«$WATCHINGUSERNAMEÛ\8c Ø¨Û\95Ú\95Û\8eزØ\8c\n\n$PAGEINTRO $NEWPAG\n\nÚ©Ù\88رتÛ\95Û\8c Ø¯Û\95ستکارÛ\8cÛ\8cÛ\95Ú©Û\95Û\8c: $PAGESUMMARY $PAGEMINOREDIT\n\nÙ¾Û\95Û\8cÙ\88Û\95Ù\86دÛ\8c Ù\84Û\95Ú¯Û\95Úµ Ø¯Û\95ستکارÛ\8cÚ©Û\95ر:\nÙ\86اÙ\85Û\95: $PAGEEDITOR_EMAIL\nÙ\88Û\8cÚ©Û\8c: $PAGEEDITOR_WIKI\n\nتا Ø³Û\95رداÙ\86Û\8c Ø¦Û\95Ù\85 Ù¾Û\95Ú\95Û\95Û\8cÛ\95 Ù\86Û\95Ú©Û\95Û\8cتØ\8c Ú¯Û\86Ú\95اÙ\86کارÛ\8cÛ\8cÛ\95کاÙ\86Û\8c Ø¯Ø§Ú¾Ø§ØªÙ\88Ù\88Û\8c Ù¾Û\95Ú\95Û\95Ú©Û\95ت Ù¾Û\8e Ú\95اÙ\86اگÛ\95Û\8cÛ\8eÙ\86درÛ\8eت. Ù\87Û\95رÙ\88Û\95ھا Ø¯Û\95تÙ\88اÙ\86Û\8c Ø¦Ø§ÚµØ§Ú©Ø§Ù\86Û\8c Ú\95اگÛ\95Û\8cاÙ\86دÙ\86 Ù\84Û\95 Ù¾Û\95Ú\95Û\95Û\8c Ú\86اÙ\88دÛ\8eرÛ\8cÛ\8cÛ\95Ú©Û\95تدا Ù\84Û\95 Ø³Û\95رÛ\95تاÙ\88Û\95 Ú\95Û\8eÚ© Ø¨Ø®Û\95Û\8cتÛ\95Ù\88Û\95.\n\nبÛ\95 Ø³Ù\88پاسÛ\95Ù\88Û\95Ø\8c Ø³Û\8cستمی ڕاگەیاندنی {{SITENAME}}\n\n--\nبۆ گۆڕینی رێکخستنەکانی ڕاگەیاندن بە ئیمەیل، بڕوانە\n{{canonicalurl:{{#special:Preferences}}}}\n\nبۆ گۆڕینی ڕێکخستنەکانی پێرستی چاودێرییەکەت، بڕوانە\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nبۆ سڕینەوەی پەڕەکە لە پێرستی چاودێرییەکەت، بڕوانە\n$UNWATCHURL\n\nکاردانەوە و یارمەتیی زۆرتر:\n$HELPPAGE",
        "created": "دروستکرا",
        "changed": "گۆڕدرا",
        "deletepage": "پەڕە بسڕەوە",
        "alreadyrolled": "دوایین گۆڕانکارییەکان لەسەر [[:$1]] لە لایەن [[User:$2|$2]] ناگەڕێندرێنەوە ([[User talk:$2|لێدوان]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]])؛ کەسێکی تر لە پێشدا دەستکاریی کردووە یان گەڕاندوویەتەوە.\n\nدوایین دەستکاری ئەم پەڕە [[User:$3|$3]] کردوویە ([[User talk:$3|لێدوان]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "پوختەی دەستکاری <em>$1</em> بوو.",
        "revertpage": "گەڕاندنەوەی دەستکارییەکانی [[Special:Contributions/$2|$2]] ([[User talk:$2|لێدوان]]) بۆ دوایین پێداچوونەوەی [[User:$1|$1]]",
-       "revertpage-nouser": "دەستکارییەکانی بەکارھێنەرێکی شاڕدراوە بۆ دوایین پێداچوونەوەی {{GENDER:$1|[[User:$1|$1]]}} گەڕێنرایەوە.",
+       "revertpage-nouser": "دەستکارییەکانی بەکارھێنەرێکی شاردراوە بۆ دوایین پێداچوونەوەی {{GENDER:$1|[[User:$1|$1]]}} گەڕێنرایەوە.",
        "rollback-success": "دەستکارییەکانی $1 وەرگێرایەوە؛<br />\nگۆڕدرا بۆ دوایین پێداچوونەوەی $2.",
        "sessionfailure": "لەوەدەچی کێشەیەک لە دانیشتنی چوونەژوورەوەت (login session)دا ببێت.\nئەم کردەوە هەڵوەشێندرایەوە بۆ بەرگری لە دزینی دراوەکانی دانیشتن.\nتکایە بگەڕێوە بۆ پەڕەی پێشوو و نوێی بکەوە، ئینجا دیسان تاقیی بکەوە.",
        "changecontentmodel-title-label": "سەرناوی پەڕە",
        "modifiedarticleprotection": "ئاستی پاراستنی «[[$1]]»ی گۆڕی",
        "unprotectedarticle": "پاراستنی لەسەر «[[$1]]» لابرد",
        "movedarticleprotection": "ڕێککارییەکانی پاراستن لە  «[[$2]]» گوازرایەوە بۆ «[[$1]]»",
+       "unprotectedarticle-comment": "{{GENDER:$2|پاراستنی}} لەسەر ''[[$1]]'' لابرد",
        "protect-title": "گۆڕینی ئاستی پاراستنی \"$1\"",
        "protect-title-notallowed": "دیتنی ئاستی پاراستنی «$1»",
        "prot_1movedto2": "[[$1]] گوازرایەوە بۆ [[$2]]",
        "exif-imagelength": "بەرزی",
        "exif-orientation": "ئاڕاستە",
        "exif-ycbcrpositioning": "شوێنی Y و C",
+       "exif-xresolution": "شێوازی ئاسۆیی",
+       "exif-yresolution": "شێوازی ستوونی",
        "exif-datetime": "ڕێکەوتی و کاتی گۆڕانی پەڕگە",
        "exif-imagedescription": "ناونیشانی وێنە",
        "exif-make": "بەرھەمھێنەری کامێرا",
        "confirmemail_body_set": "کەسێک، لەوانەیە خۆت، لە ناونیشانی IPی $1 ـەوە،\nلە {{SITENAME}}دا، ناونیشانیی ئیمێلی ھەژماری «$2»ی کردووە بەم ناونیشانە.\n\nبۆ پشتڕاستکردنەوەی ئەوەی کە ئەم ھەژمارە بە ڕاستی ھی تۆیە و بۆ چالاککردنەوەی ئامرازە ئیمێلییەکانی {{SITENAME}}، ئەم لینکە لە وێبگەڕەکەتدا بکەرەوە:\n\n$3\n\nئەگەر ھەژمارەکە ھی تۆ *نییە*، بۆ هەڵوەشاندنەوەی پشتڕاستکردنەوەی ناونیشانی ئیمێل، شوێنی ئەم لینکە بکەوە:\n\n$5\n\nماوەی ئەم کۆدی پشتڕاستکردنەوەیە لە $4دا بە سەر دەچێت.",
        "confirmemail_invalidated": "بڕواپی‌کردنی ناونیشانی ئی‌مەیل هەڵوەشێندراوە",
        "invalidateemail": "هەڵوەشاندنەوەی بڕواپێ‌کردنی ئی‌مەیل",
+       "notificationemail_body_changed": "کەسێک، کە لەوانەیە خۆت بووبێت، لە ناونیشانی IPی $1، ناونیشانی پۆستی ئەلیکترۆنی لە $2ەوە گۆڕی بە $3 لە {{SITENAME}}.\n\nئەگەر ئەمە تۆ نەبوویت، ھەر ئێستا پەیوەندی بە بەڕێوەبەرێکی سایتەکەوە بکە.",
        "scarytranscludetoolong": "[URL زۆر درێژە]",
        "deletedwhileediting": "'''ھۆشیار بە''': ئەم پەڕە دوای ئەوە تۆ دەستکاریکردنیت دەستپێکرد سڕاوەتەوە!",
        "confirmrecreate-noreason": "بەکارھێنەر [[User:$1|$1]] ([[User talk:$1|talk]]) پەڕەکەی سڕییەوە پاش ئەوەی تۆ دەستکاریکردنی پەڕەکەت دەستپێکرد. تکایە پشتڕاستی بکەوە کە بە ڕاستی دەتەوێ دیسان ئەم پەڕە دروست بکەیتەوە.",
        "special-characters-group-thai": "تایلەندی",
        "special-characters-group-khmer": "خمێری",
        "log-action-filter-all": "ھەموو",
-       "log-action-filter-upload-upload": "بارکردنی نوێ"
+       "log-action-filter-upload-upload": "بارکردنی نوێ",
+       "authmanager-email-label": "ئیمەیڵ"
 }
index 70fbb4b..9d39994 100644 (file)
@@ -7,7 +7,8 @@
                        "Wolliger Mensch",
                        "ОйЛ",
                        "아라",
-                       "Илья Драконов"
+                       "Илья Драконов",
+                       "Vvs-dm"
                ]
        },
        "tog-oldsig": "нꙑнѣшьн҄ь аѵтографъ :",
        "prefs-resetpass": "таина словєсє иꙁмѣнѥниѥ",
        "saveprefs": "съхранѥниѥ",
        "prefs-editing": "исправлѥниѥ",
-       "rows": "рѧдꙑ :",
        "searchresultshead": "исканиѥ",
        "savedprefs": "твои строи иꙁмѣнєнъ ѥстъ",
        "localtime": "мѣстьно врѣмѧ :",
        "sourcefilename": "источьна дѣла имꙗ :",
        "watchthisupload": "си дѣла блюдєниѥ",
        "upload-dialog-button-cancel": "отъмѣтаниѥ",
+       "upload-form-label-infoform-categories": "Катигории",
        "license": "прощєниѥ :",
        "license-header": "прощєниѥ",
        "imgfile": "дѣло",
index 351ac32..e3291ce 100644 (file)
        "tog-newpageshidepatrolled": "Skjul patruljerede sider på listen over nye sider",
        "tog-hidecategorization": "Skjul kategorisering af sider",
        "tog-extendwatchlist": "Udvid overvågningslisten til at vise alle ændringer og ikke kun den nyeste",
-       "tog-usenewrc": "Gruppér ændringer per side i listen over seneste ændringer og i overvågningslisten",
+       "tog-usenewrc": "Gruppér ændringer efter side i listen over seneste ændringer og i overvågningslisten",
        "tog-numberheadings": "Automatisk nummerering af overskrifter",
        "tog-showtoolbar": "Vis værktøjslinje til redigering",
        "tog-editondblclick": "Redigér sider med dobbeltklik",
        "tog-editsectiononrightclick": "Redigér afsnit ved at højreklikke på deres titler",
-       "tog-watchcreations": "Tilføj sider, jeg opretter, og filer, jeg lægger op, til min overvågningsliste",
-       "tog-watchdefault": "Tilføj sider og filer, jeg redigerer, til min overvågningsliste",
-       "tog-watchmoves": "Tilføj sider og filer, jeg flytter, til min overvågningsliste",
-       "tog-watchdeletion": "Tilføj sider og filer, jeg sletter, til min overvågningsliste",
-       "tog-watchuploads": "Tilføj nye filer jeg uploader til min overvågningsliste",
-       "tog-watchrollback": "Tilføj sider, hvor jeg har udført en tilbagerulning til min overvågningsliste",
+       "tog-watchcreations": "Føj sider, jeg opretter, og filer, jeg lægger op, til min overvågningsliste",
+       "tog-watchdefault": "Føj sider og filer, jeg redigerer, til min overvågningsliste",
+       "tog-watchmoves": "Føj sider og filer, jeg flytter, til min overvågningsliste",
+       "tog-watchdeletion": "Føj sider og filer, jeg sletter, til min overvågningsliste",
+       "tog-watchuploads": "Føj nye filer, jeg uploader, til min overvågningsliste",
+       "tog-watchrollback": "Føj sider, hvor jeg har udført en tilbagerulning, til min overvågningsliste",
        "tog-minordefault": "Markér som standard alle redigeringer som mindre",
        "tog-previewontop": "Vis forhåndsvisning over redigeringsboksen",
        "tog-previewonfirst": "Vis forhåndsvisning ved første redigering",
        "tog-ccmeonemails": "Send mig kopier af e-mails som jeg sender til andre brugere",
        "tog-diffonly": "Vis ikke sideindhold neden under versionssammenligninger",
        "tog-showhiddencats": "Vis skjulte kategorier",
-       "tog-norollbackdiff": "Vis ikke forskel efter tilbagerulning",
+       "tog-norollbackdiff": "Vis ikke forskel efter udførelse af en tilbagerulning",
        "tog-useeditwarning": "Advar mig, hvis jeg forlader en redigeringsside med ændringer, der ikke er gemt.",
-       "tog-prefershttps": "Brug altid en sikker forbindelse, når du er logget ind",
+       "tog-prefershttps": "Brug altid en sikker forbindelse, når jeg er logget ind",
        "underline-always": "Altid",
        "underline-never": "Aldrig",
        "underline-default": "Brug browserens indstilling eller standarden for det valgte udseende",
        "pagecategories": "{{PLURAL:$1|Kategori|Kategorier}}",
        "category_header": "Sider i kategorien \"$1\"",
        "subcategories": "Underkategorier",
-       "category-media-header": "Medier i kategorien „$1“",
-       "category-empty": "''Denne kategori indeholder for øjeblikket hverken sider eller medie-filer.''",
+       "category-media-header": "Medier i kategorien \"$1\"",
+       "category-empty": "<em>Denne kategori indeholder for øjeblikket hverken sider eller medie-filer.</em>",
        "hidden-categories": "{{PLURAL:$1|Skjult kategori|Skjulte kategorier}}",
        "hidden-category-category": "Skjulte kategorier",
-       "category-subcat-count": "{{PLURAL:$2|Denne kategori har en underkategori.|Denne kategori indeholder nedenstående {{PLURAL:$1|underkategori|$1 underkategorier}}, af i alt $2.}}",
-       "category-subcat-count-limited": "Denne kategori indeholder {{PLURAL:$1|underkategori|$1 underkategorier}}.",
-       "category-article-count": "Denne kategori indeholder {{PLURAL:$2|kun den nedenstående side|{{PLURAL:$1|den nedenstående side|de nedenstående $1 sider}} af i alt $2.}}",
-       "category-article-count-limited": "Kategorien indeholder {{PLURAL:$1|den nedenstående side|de nedenstående $1 sider}}.",
-       "category-file-count": "Denne kategori indeholder {{PLURAL:$2|kun den nedenstående fil.|{{PLURAL:$1|den nedenstående fil|de nedenstående $1 filer}} af i alt $2.}}",
-       "category-file-count-limited": "Kategorien indeholder {{PLURAL:$1|den nedenstående fil|de nedenstående $1 filer}}.",
+       "category-subcat-count": "{{PLURAL:$2|Denne kategori har kun den nedenstående underkategori.|Denne kategori har nedenstående {{PLURAL:$1|underkategori|$1 underkategorier}}, af i alt $2.}}",
+       "category-subcat-count-limited": "Denne kategori har nedenstående {{PLURAL:$1|underkategori|$1 underkategorier}}.",
+       "category-article-count": "{{PLURAL:$2|Denne kategori indeholder kun den nedenstående side.|{{PLURAL:$1|Den nedenstående side|De nedenstående $1 sider}} er i denne kategori, ud af i alt $2.}}",
+       "category-article-count-limited": "{{PLURAL:$1|Den nedenstående side|De nedenstående $1 sider}} er i denne kategori.",
+       "category-file-count": "{{PLURAL:$2|Denne kategori indeholder kun den nedenstående fil.|{{PLURAL:$1|Den nedenstående fil|De nedenstående $1 filer}} er i denne kategori, ud af i alt $2.}}",
+       "category-file-count-limited": "{{PLURAL:$1|Den nedenstående fil|De nedenstående $1 filer}} er i denne kategori.",
        "listingcontinuesabbrev": "forts.",
        "index-category": "Indekserede sider",
        "noindex-category": "Ikke-indekserede sider",
        "qbfind": "Søg",
        "qbbrowse": "Gennemse",
        "qbedit": "Redigér",
-       "qbpageoptions": "Indstillinger for side",
-       "qbmyoptions": "Mine indstillinger",
+       "qbpageoptions": "Denne side",
+       "qbmyoptions": "Mine sider",
        "faq": "OSS",
        "faqpage": "Project:OSS",
        "actions": "Handlinger",
        "tagline": "Fra {{SITENAME}}",
        "help": "Hjælp",
        "search": "Søg",
-       "search-ignored-headings": " #<!-- lad denne linje være præcis som den er --> <pre>\n# Overskrifter, der vil blive ignoreret af søgning.\n# Ændringer til dette træder i kraft så snart siden med overskriften er indekseret.\n# Du kan tvinge siden til genindeksering ved at lave en nul redigering.\n# syntaksen er som følger:\n#   * Alt fra en tegnet \"#\" til slutningen af linjen er en kommentar\n#   * Hver ikke-tomme linje er den nøjagtige titel der skal ignoreres, der skelnes også mellem store og små bogstaver\nReferencer\nEksterne henvisninger\nSe også\nKilder og henvisninger\nEksterne kilder/henvisninger\nKilder\n #</pre> <!-- lad denne linje være præcis som den er -->",
+       "search-ignored-headings": " #<!-- leave this line exactly as it is --> <pre>\n# Overskrifter, der vil blive ignoreret af søgning.\n# Ændringer til dette træder i kraft så snart siden med overskriften er indekseret.\n# Du gennemtvinge genindeksering af siden ved at lave en tom redigering.\n# Syntaksen er som følger:\n#   * Alt fra et \"#\"-tegn til slutningen af linjen er en kommentar.\n#   * Hver ikke-tom linje er den nøjagtige titel der skal ignoreres; der skelnes mellem store og små bogstaver.\nReferencer\nEksterne henvisninger\nSe også\nKilder og henvisninger\nEksterne kilder/henvisninger\nKilder\n #<!-- leave this line exactly as it is --> <pre>",
        "searchbutton": "Søg",
        "go": "Gå til",
        "searcharticle": "Gå til",
        "delete": "Slet",
        "deletethispage": "Slet side",
        "undeletethispage": "Gendan denne side",
-       "undelete_short": "Fortryd sletning af {{PLURAL:$1|én version|$1 versioner}}",
-       "viewdeleted_short": "Vis {{PLURAL:$1|en slettet redigering|$1 slettede redigeringer}}",
+       "undelete_short": "Gendan {{PLURAL:$1|én redigering|$1 redigeringer}}",
+       "viewdeleted_short": "Vis {{PLURAL:$1|én slettet redigering|$1 slettede redigeringer}}",
        "protect": "Beskyt",
        "protect_change": "ændr",
        "protectthispage": "Beskyt side",
        "unprotect": "Ændr beskyttelse",
-       "unprotectthispage": "Ændre beskyttelsen af denne side",
+       "unprotectthispage": "Ændr beskyttelsen af denne side",
        "newpage": "Ny side",
        "talkpage": "Diskussion",
        "talkpagelinktext": "diskussion",
        "tool-link-userrights": "Ændre {{GENDER:$1|bruger}}grupper",
        "tool-link-userrights-readonly": "Se {{GENDER:$1|bruger}}grupper",
        "tool-link-emailuser": "Send e-mail til denne {{GENDER:$1|bruger}}",
-       "userpage": "Se brugersiden",
-       "projectpage": "Se projektsiden",
-       "imagepage": "Se filside",
-       "mediawikipage": "Vise indholdsside",
-       "templatepage": "Vise skabelonside",
-       "viewhelppage": "Vise hjælpeside",
-       "categorypage": "Vise kategoriside",
-       "viewtalkpage": "Se diskussion",
-       "otherlanguages": "Andre sprog",
+       "userpage": "Vis brugerside",
+       "projectpage": "Vis projektside",
+       "imagepage": "Vis filside",
+       "mediawikipage": "Vis indholdsside",
+       "templatepage": "Vis skabelonside",
+       "viewhelppage": "Vis hjælpeside",
+       "categorypage": "Vis kategoriside",
+       "viewtalkpage": "Vis diskussion",
+       "otherlanguages": "På andre sprog",
        "redirectedfrom": "(Omdirigeret fra $1)",
        "redirectpagesub": "Omdirigeringsside",
        "redirectto": "Omdiriger til:",
        "lastmodifiedat": "Denne side blev senest ændret $1 kl. $2.",
-       "viewcount": "Siden er vist {{PLURAL:$1|en gang|$1 gange}}.",
+       "viewcount": "Siden er vist {{PLURAL:$1|én gang|$1 gange}}.",
        "protectedpage": "Beskyttet side",
        "jumpto": "Skift til:",
        "jumptonavigation": "navigering",
        "jumptosearch": "søgning",
-       "view-pool-error": "Beklager, men serverne er i øjeblikket overbelastede.\nFor mange brugere prøver at se denne side.\nVent et øjeblik, før du prøver at besøge denne side igen.\n\n$1",
-       "generic-pool-error": "Beklager, men serverne er i øjeblikket overbelastede.\nFor mange brugere prøver at se denne side.\nVent et øjeblik før du prøver at besøge denne side igen.",
-       "pool-timeout": "Timeout mens man venter på låsningen",
-       "pool-queuefull": "Pool køen er fuld",
+       "view-pool-error": "Beklager, men serverne er i øjeblikket overbelastede.\nFor mange brugere prøver at se denne side.\nVent venligst lidt, før du igen prøver at besøge denne side.\n\n$1",
+       "generic-pool-error": "Beklager, men serverne er i øjeblikket overbelastede.\nFor mange brugere prøver at se denne side.\nVent venligst lidt, før du igen prøver at besøge denne side.",
+       "pool-timeout": "Timeout mens der blev ventet på låsen",
+       "pool-queuefull": "Puljekøen er fuld",
        "pool-errorunknown": "Ukendt fejl",
-       "pool-servererror": "Pool-counter servicen er ikke til rådighed ($1).",
+       "pool-servererror": "Puljetæller-tjenesten er ikke til rådighed ($1).",
        "poolcounter-usage-error": "Brugsfejl: $1",
        "aboutsite": "Om {{SITENAME}}",
        "aboutpage": "Project:Om",
        "privacy": "Behandling af personlige oplysninger",
        "privacypage": "Project:Behandling af personlige oplysninger",
        "badaccess": "Manglende rettigheder",
-       "badaccess-group0": "Du har ikke de nødvendige rettigheder til denne handling.",
-       "badaccess-groups": "Denne handling kan kun udføres af brugere som tilhører {{PLURAL:$2|gruppen|en af grupperne:}} $1.",
+       "badaccess-group0": "Du har ikke de nødvendige rettigheder til at udføre den handling, du har anmodet om.",
+       "badaccess-groups": "Denne handling kan kun udføres af brugere i {{PLURAL:$2|gruppen|disse grupper:}} $1.",
        "versionrequired": "Kræver version $1 af MediaWiki",
-       "versionrequiredtext": "Version $1 af MediaWiki er påkrævet, for at bruge denne side. Se [[Special:Version|Versionssiden]]",
+       "versionrequiredtext": "Version $1 af MediaWiki er nødvendig for at bruge denne side. Se [[Special:Version|Versionssiden]]",
        "ok": "OK",
        "retrievedfrom": "Hentet fra \"$1\"",
        "youhavenewmessages": "Du har $1 ($2).",
-       "youhavenewmessagesfromusers": "Du har $1 fra {{PLURAL:$3|en anden bruger| $3 brugere}} ($2).",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|Du har}} $1 fra {{PLURAL:$3|en anden bruger|$3 brugere}} ($2).",
        "youhavenewmessagesmanyusers": "Du har $1 fra mange brugere ($2).",
        "newmessageslinkplural": "{{PLURAL:$1|en ny besked|999=nye beskeder}}",
        "newmessagesdifflinkplural": "seneste {{PLURAL:$1|ændring|999=ændringer}}",
        "confirmable-confirm": "Er {{GENDER:$1|du}} sikker?",
        "confirmable-yes": "Ja",
        "confirmable-no": "Nej",
-       "thisisdeleted": "Se eller gendan $1?",
+       "thisisdeleted": "Vis eller gendan $1?",
        "viewdeleted": "Vis $1?",
-       "restorelink": "{{PLURAL:$1|en slettet ændring|$1 slettede ændringer}}",
+       "restorelink": "{{PLURAL:$1|én slettet redigering|$1 slettede redigeringer}}",
        "feedlinks": "Feed:",
        "feed-invalid": "Ugyldig abonnementstype.",
        "feed-unavailable": "Der er ingen syndikeringsfeeds tilgængelige",
        "site-atom-feed": "$1 Atom-feed",
        "page-rss-feed": "\"$1\" RSS-feed",
        "page-atom-feed": "\"$1\" Atom-feed",
-       "red-link-title": "$1 (siden er ikke skrevet endnu)",
+       "red-link-title": "$1 (siden findes ikke)",
        "sort-descending": "Sorter faldende",
        "sort-ascending": "Sorter stigende",
        "nstab-main": "Side",
        "nstab-category": "Kategori",
        "mainpage-nstab": "Forside",
        "nosuchaction": "Funktionen findes ikke",
-       "nosuchactiontext": "Handlingen som er angivet i URL'en er ugyldig.\nDu kan have skrevet URL'en forkert, eller fulgt en ukorrekt henvisning.\nDet kan også skyldes en fejl i programmellet som bruges af {{SITENAME}}.",
+       "nosuchactiontext": "Handlingen som er angivet i URL'en er ugyldig.\nDu har måske skrevet URL'en forkert eller fulgt en ukorrekt henvisning.\nDet kan også skyldes en fejl i programmellet som bruges af {{SITENAME}}.",
        "nosuchspecialpage": "En sådan specialside findes ikke",
-       "nospecialpagetext": "<strong>Du har bedt om en specialside, der ikke kan genkendes af MediaWiki-softwaren.</strong>\nEn liste over gyldige specialsider findes på [[Special:SpecialPages|{{int:specialpages}}]].",
+       "nospecialpagetext": "<strong>Du har bedt om en specialside, som ikke findes.</strong>\n\nEn liste over gyldige specialsider kan findes på [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "Fejl",
        "databaseerror": "Databasefejl",
-       "databaseerror-text": "Der opstod fejl i en forespørgsel til databasen.\nDette kan indikere en fejl i softwaren.",
-       "databaseerror-textcl": "Der opstod fejl i en forespørgsel til databasen.",
+       "databaseerror-text": "Der opstod en fejl i en forespørgsel til databasen.\nDette kan skyldes en programmeringsfejl i softwaren.",
+       "databaseerror-textcl": "Der opstod en fejl i en forespørgsel til databasen.",
        "databaseerror-query": "Forespørgsel: $1",
        "databaseerror-function": "Funktion: $1",
        "databaseerror-error": "Fejl: $1",
-       "transaction-duration-limit-exceeded": "For at undgå høje replikationsforsinkelser blev denne transaktion afbrudt fordi tiden det tog at lagre ($1) oversteg maksimumsgrænsen på $2 {{PLURAL:$2|sekund|sekunder}}.\nHvis du er ved at ændre mange emner på en gang, så prøv at udføre flere mindre operationer i stedet.",
-       "laggedslavemode": "'''Bemærk:''' Den viste side indeholder muligvis ikke de nyeste ændringer.",
-       "readonly": "Databasen er skrivebeskyttet",
-       "enterlockreason": "Skriv en begrundelse for skrivebeskyttelsen, med samt en vurdering af, hvornår skrivebeskyttelsen ophæves igen",
-       "readonlytext": "Databasen er i øjeblikket låst for nye poster og andre ændringer, formentlig pga. rutinemæssig databasevedligeholdelse, hvorefter den vil være tilbage til normalen.\n\nSystemadministratoren som låste den, gav denne forklaring: $1",
-       "missing-article": "Databasen burde indeholde siden \"$1\" $2, men det gør den ikke.\n\nDen sandsynlige årsag er at du har fulgt et forældet link til en forskel eller en gammel version af en side der er blevet slettet.\n\nHvis det ikke er tilfældet, har du muligvis fundet en software-fejl.\nGør venligst en [[Special:ListUsers/sysop|administrator]] opmærksom på det, og husk at fortælle hvilken URL du har fulgt.",
+       "transaction-duration-limit-exceeded": "For at undgå høj replikationsforsinkelse blev denne transaktion afbrudt, fordi tiden det tog at lagre ($1) oversteg grænsen på $2 {{PLURAL:$2|sekund|sekunder}}.\nHvis du er ved at ændre mange emner på en gang, så prøv at udføre flere mindre operationer i stedet.",
+       "laggedslavemode": "<strong>Advarsel:</strong> Siden indeholder muligvis ikke de nyeste ændringer.",
+       "readonly": "Databasen er låst",
+       "enterlockreason": "Skriv en begrundelse for låsningen, inklusive en vurdering af hvornår den vil blive ophævet igen",
+       "readonlytext": "Databasen er i øjeblikket låst for nye poster og andre ændringer, formentlig pga. rutinemæssig databasevedligeholdelse, hvorefter den vil være tilbage til normalen.\n\nDen systemadministrator, som låste den, gav denne forklaring: $1",
+       "missing-article": "Databasen burde indeholde siden \"$1\" $2, men det gør den ikke.\n\nDette skyldes normalt at du har fulgt et forældet link til en forskel eller til en gammel version af en side der er blevet slettet.\n\nHvis det ikke er tilfældet, har du muligvis fundet en programmeringsfejl i softwaren.\nGør venligst en [[Special:ListUsers/sysop|administrator]] opmærksom på det, og sørg for at fortælle vedkommende hvilken URL, du har fulgt.",
        "missingarticle-rev": "(versionsnummer: $1)",
-       "missingarticle-diff": "(Forskel: $1, $2)",
-       "readonly_lag": "Databasen er automatisk blevet låst mens slave database serverne synkronisere med master databasen",
-       "nonwrite-api-promise-error": "HTTP-headeren 'Promise-Non-Write-API-Action' blev sendt, men forespørgslen var til et API skrivemodul.",
+       "missingarticle-diff": "(forskel: $1, $2)",
+       "readonly_lag": "Databasen er automatisk blevet låst mens slavedatabaseserverne synkroniserer med masterdatabasen",
+       "nonwrite-api-promise-error": "HTTP-headeren 'Promise-Non-Write-API-Action' blev sendt, men forespørgslen var til et API-skrivemodul.",
        "internalerror": "Intern fejl",
        "internalerror_info": "Intern fejl: $1",
-       "internalerror-fatal-exception": "Alvorlig undtagelse af typen \"$1\"",
+       "internalerror-fatal-exception": "Fatal undtagelse af typen \"$1\"",
        "filecopyerror": "Kunne ikke kopiere filen \"$1\" til \"$2\".",
        "filerenameerror": "Kunne ikke omdøbe filen \"$1\" til \"$2\".",
        "filedeleteerror": "Kunne ikke slette filen \"$1\".",
        "directorycreateerror": "Kunne ikke oprette mappen \"$1\".",
-       "directoryreadonlyerror": "Folderen \"$1\" er skrivebeskyttet.",
-       "directorynotreadableerror": "Folderen \"$1\" er ikke læsbar.",
+       "directoryreadonlyerror": "Mappen \"$1\" er skrivebeskyttet.",
+       "directorynotreadableerror": "Mappen \"$1\" er ikke læsbar.",
        "filenotfound": "Kunne ikke finde filen \"$1\".",
        "unexpected": "Uventet værdi: \"$1\"=\"$2\".",
-       "formerror": "Fejl: Kunne ikke afsende formular",
+       "formerror": "Fejl: Kunne ikke afsende formular.",
        "badarticleerror": "Denne funktion kan ikke udføres på denne side.",
        "cannotdelete": "Kunne ikke slette siden eller filen \"$1\".\nDen kan være blevet slettet af en anden.",
        "cannotdelete-title": "Kan ikke slette siden \"$1\"",
-       "delete-hook-aborted": "Sletningen blev afbrudt af en programfunktion.\nDer var ikke nogen forklaring.",
+       "delete-hook-aborted": "Sletningen blev afbrudt af en programfunktion.\nDer blev ikke givet nogen forklaring.",
        "no-null-revision": "Kunne ikke oprette nye tom revision for side \"$1\"",
        "badtitle": "Ugyldig titel",
        "badtitletext": "Den ønskede sides titel var ikke tilladt, tom eller siden er forkert henvist fra {{SITENAME}} på et andet sprog.\nDen kan indeholde et eller flere tegn, som ikke må anvendes i titler.",
        "noname": "Du har ikke angivet et gyldigt brugernavn.",
        "loginsuccesstitle": "Logget ind",
        "loginsuccess": "'''Du er nu logget på {{SITENAME}} som \"$1\".'''",
-       "nosuchuser": "Der er ingen bruger med navnet \"$1\".\nDer skelnes mellem store og bogstaver i brugernavne.\nKontrollér stavemåden, eller [[Special:CreateAccount|opret en ny konto]].",
+       "nosuchuser": "Der er ingen bruger med navnet \"$1\".\nDer skelnes mellem store og små bogstaver i brugernavne.\nKontrollér stavningen, eller [[Special:CreateAccount|opret en ny konto]].",
        "nosuchusershort": "Der er ingen bruger ved navn \"$1\". Tjek din stavning.",
        "nouserspecified": "Angiv venligst et brugernavn.",
        "login-userblocked": "Denne bruger er blokeret. Det er ikke tilladt at logge på.",
        "noemail": "Der er ikke oplyst en e-mailadresse for bruger \"$1\".",
        "noemailcreate": "Du skal angive en gyldig e-mailadresse",
        "passwordsent": "En ny adgangskode er sendt til e-mailadressen, som er registreret for \"$1\".\nDu bør logge på og ændre din adgangskode straks efter du har modtaget e-mailen.",
-       "blocked-mailpassword": "Din IP-adresse er blokeret fra at redigere sider. For at forhindre misbrug, er det heller ikke muligt, at bestille en ny adgangskode.",
+       "blocked-mailpassword": "Din IP-adresse er blokeret fra at redigere sider. For at forhindre misbrug er det heller ikke muligt at bestille en ny adgangskode fra denne IP-adresse.",
        "eauthentsent": "En e-mailbekræftelse er sendt til den angivne e-mailadresse.\n\nFør flere e-mails bliver sendt til kontoen, skal du følge instruktionerne i e-mailen, for at bekræfte at kontoen rent faktisk er din.",
        "throttled-mailpassword": "Indenfor {{PLURAL:$1|den sidste time|de sidste $1 timer}} er der allerede sendt en ny adgangskode. For at forhindre misbrug af funktionen, kan der kun bestilles en ny adgangskode én gang for hver {{PLURAL:$1|time|$1 timer}}.",
        "mailerror": "Fejl ved afsendelse af e-mail: $1",
-       "acct_creation_throttle_hit": "Besøgende med samme IP-adresse som dig har oprettet {{PLURAL:$1|en konto|$1 kontoer}} det sidste døgn, og det er ikke tilladt at oprette flere.\nDerfor kan besøgende ikke oprette flere kontoer fra denne IP-adresse i øjeblikket.",
+       "acct_creation_throttle_hit": "Besøgende med samme IP-adresse som dig har oprettet {{PLURAL:$1|1 konto|$1 kontoer}} inden for den/det/de seneste $2, hvilket er det maksimalt tilladte inden for denne tidsperiode.\nDerfor kan besøgende, som bruger denne IP-adresse, ikke oprette flere kontoer fra denne IP-adresse for øjeblikket.",
        "emailauthenticated": "Din e-mailadresse blev bekræftet den $2 kl. $3.",
        "emailnotauthenticated": "Din e-mailadresse er endnu ikke bekræftet.\nIngen e-mail vil blive sendt for de følgende funktioner.",
        "noemailprefs": "Angiv en e-mailadresse, så følgende funktioner er til rådighed.",
        "createaccount-title": "Opret brugerkonto på {{SITENAME}}",
        "createaccount-text": "Nogen har oprettet en konto for din e-mailadresse på {{SITENAME}} ($4) med navnet \"$2\". Adgangskoden er \"$3\".\nDu opfordres til at logge på og ændre adgangskoden med det samme.\n\nDu kan ignorere denne besked hvis kontoen blev oprettet ved en fejl.",
        "login-throttled": "Du har forsøgt at logge på for mange gange.\nVent venligst $1, før du prøver igen.",
-       "login-abort-generic": "Det lykkedes dig ikke at logge på - afbrudt",
+       "login-abort-generic": "Det lykkedes ikke at logge dig på - Afbrudt",
        "login-migrated-generic": "Din konto er blevet globaliseret, og dit brugernavn eksisterer ikke længere på denne wiki.",
        "loginlanguagelabel": "Sprog: $1",
        "suspicious-userlogout": "Din anmodning om at logge af blev nægtet, fordi det ser ud som den blev sendt af en ødelagt browser eller caching proxy.",
        "newpassword": "Ny adgangskode:",
        "retypenew": "Gentag ny adgangskode:",
        "resetpass_submit": "Gem adgangskode og log på",
-       "changepassword-success": "Din adgangskode er nu ændret!",
+       "changepassword-success": "Din adgangskode er blevet ændret!",
        "changepassword-throttled": "Du har forsøgt at logge på for mange gange for nylig.\nVent venligst $1, før du prøver igen.",
        "botpasswords": "Bot adgangskoder",
        "botpasswords-summary": "<em>Bot adgangskoder</em> giver adgang til en brugerkonto via API'en, uden at bruge kontoens normale login-legitimationsoplysninger. Brugerrettighederne kan være begrænset, når du er logget på med et bot password,.\n\nHvis du ikke ved, hvorfor du måske ønsker at gøre dette, bør du nok ikke gøre det. Ingen bør nogensinde bede dig om at generere et af disse, og give det til dem.",
        "resetpass-no-info": "Du skal være logget på for at komme direkte til denne side.",
        "resetpass-submit-loggedin": "Skift adgangskode",
        "resetpass-submit-cancel": "Annuller",
-       "resetpass-wrong-oldpass": "Ugyldig midlertidig eller gældende adgangskode.\nDu har muligvis allerede skiftet din adgangskode eller anmodet om en ny midlertidig kode.",
+       "resetpass-wrong-oldpass": "Ugyldig midlertidig eller gældende adgangskode.\nDu har muligvis allerede ændret din adgangskode eller bedt om en ny midlertidig kode.",
        "resetpass-recycled": "Vær venlig at ændre din adgangskode til noget andet end din nuværende adgangskode.",
        "resetpass-temp-emailed": "Du loggede på med en midlertidig kode tilsendt på e-mail.\nFor at afslutte indlogning skal du angive en ny adgangskode her:",
        "resetpass-temp-password": "Midlertidig adgangskode",
        "selfredirect": "<strong>Advarsel:</strong> Du er ved at omdirigere denne side til sig selv.\nDu kan have angivet det forkerte mål for omdirigeringen, eller du kan være ved at redigere den forkerte side.\nHvis du klikker på \"{{int:savearticle}}\" igen, vil omdirigeringen blive oprettet uanset dette.",
        "missingcommenttext": "Skriv venligst en kommentar nedenfor.",
        "missingcommentheader": "<strong>Bemærk:</strong> Du har ikke angivet en overskrift/emne for denne kommentar. Hvis du trykker \"{{int:savearticle}}\" én gang til, gemmes dine ændringer uden overskrift/emne.",
-       "summary-preview": "Forhåndsvisning af beskrivelsen:",
+       "summary-preview": "Forhåndsvisning af sammenfatning:",
        "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",
        "revdelete-unsuppress": "Ophæv begrænsninger for gendannede versioner",
        "revdelete-log": "Begrundelse:",
        "revdelete-submit": "Udfør på {{PLURAL:$1|den udvalgte version|de udvalgte versioner}}",
-       "revdelete-success": "'''Versionsvisningen er ændret.'''",
+       "revdelete-success": "Versionssynligheden blev opdateret.",
        "revdelete-failure": "'''Kunne ikke ændre versionssynligheden:'''\n$1",
-       "logdelete-success": "'''Synlighed ændret med success.'''",
+       "logdelete-success": "Log-synligheden blev ændret.",
        "logdelete-failure": "'''Kunne ikke ændre logsynligheden.'''\n$1",
        "revdel-restore": "ændre synlighed",
        "pagehist": "Sidehistorik",
        "modifiedarticleprotection": "ændrede beskyttelsen af \"[[$1]]\"",
        "unprotectedarticle": "fjernede beskyttelse af \"[[$1]]\"",
        "movedarticleprotection": "flyttede beskyttelsesindstillinger fra \"[[$2]]\" til \"[[$1]]\"",
+       "protectedarticle-comment": "{{GENDER:$2|beskyttede}} \"[[$1]]\"",
        "protect-title": "Ændre beskyttelse af \"$1\"",
        "protect-title-notallowed": "Få vist beskyttelsesniveauet af \"$1\"",
        "prot_1movedto2": "$1 flyttet til $2",
index 22aa69e..c7131ae 100644 (file)
        "rcfilters-invalid-filter": "Ungültiger Filter",
        "rcfilters-empty-filter": "Keine aktiven Filter. Es werden alle Beiträge angezeigt.",
        "rcfilters-filterlist-title": "Filter",
+       "rcfilters-filterlist-feedbacklink": "Rückmeldung zu den neuen (Beta-)Filtern hinterlassen",
        "rcfilters-highlightbutton-title": "Ergebnisse hervorheben",
        "rcfilters-highlightmenu-title": "Eine Farbe auswählen",
        "rcfilters-filterlist-noresults": "Keine Filter gefunden",
        "rollback-missingparam": "In der Anfrage fehlen erforderliche Parameter.",
        "rollback-missingrevision": "Die Versionsdaten konnten nicht geladen werden.",
        "cantrollback": "Die Änderung kann nicht zurückgesetzt werden, da es keine früheren Autoren gibt.",
-       "alreadyrolled": "Das Zurücksetzen der Änderungen von [[User:$2|$2]] ([[User talk:$2|Diskussion]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) an [[:$1]] ist gescheitert, da in der Zwischenzeit ein anderer Benutzer die Seite geändert hat.\n\nDie letzte Änderung stammt von [[User:$3|$3]] ([[User talk:$3|Diskussion]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
+       "alreadyrolled": "Das Zurücksetzen der Änderungen von [[User:$2|$2]] ([[User talk:$2|Diskussion]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) an [[:$1]] ist gescheitert, da bereits ein anderer Benutzer die Seite geändert hat.\n\nDie letzte Änderung stammt von [[User:$3|$3]] ([[User talk:$3|Diskussion]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Die Änderungszusammenfassung lautet: <em>$1</em>.",
        "revertpage": "Änderungen von [[Special:Contributions/$2|$2]] ([[User talk:$2|Diskussion]]) wurden auf die letzte Version von [[User:$1|$1]] zurückgesetzt",
        "revertpage-nouser": "Änderungen von einem versteckten Benutzer rückgängig gemacht und letzte Version von {{GENDER:$1|[[User:$1|$1]]}} wiederhergestellt",
index c791ecf..d8918e4 100644 (file)
        "viewdeleted_short": "{{PLURAL:$1|Jew vurnayış esternayi|$1 Vurnayışanê esternayan}} bımotne",
        "protect": "Bıstarnê",
        "protect_change": "bıvurne",
-       "protectthispage": "Ena perer bıpawe",
+       "protectthispage": "Ena perre şeveknê",
        "unprotect": "Starnayışi bıvurne",
-       "unprotectthispage": "Starnayışê ena perer bıvurne",
+       "unprotectthispage": "Şeveknayışê ena perre bıvırne",
        "newpage": "Perra newi",
        "talkpage": "Na per dı vatan kew",
        "talkpagelinktext": "Mesac",
        "edit-no-change": "Vırnayışê şıma qebul nêbı, çunke nuşte de yew vırnayış nêvıraziyo.",
        "postedit-confirmation-created": "Pele vıraziye.",
        "postedit-confirmation-restored": "Pele anciya vıraziye.",
-       "postedit-confirmation-saved": "Vırnayışê to qeyd bi.",
+       "postedit-confirmation-saved": "Vırnayışê şıma qeyd bi.",
        "edit-already-exists": "Pelo newe nêvıraziyeno.\nPel ca ra esto.",
        "defaultmessagetext": "Metnê mesacê hesabiyayey",
        "content-failed-to-parse": "Qandê madela $3 zereyê $1, $2 sero nêagozyayo",
        "rev-suppressed-text-permission": "Çımraviyarnayışê ena pele '''degusneyayo'''.\nŞıma be idarekerina xo ra şenê ey bıvênê; beno ke [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} degusnayış] de teferruat esto.",
        "rev-deleted-text-unhide": "Çım ra viyarnayışê enê riperri <strong>esteriya</strong>.\nTeferruati [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} qeydê esterıtışi] yenê diyene.\nŞıma hewna şenê [$1 nê vırnayışi bıvênê], eke wazenê dewam kerê.",
        "rev-suppressed-text-unhide": "Çımra viyarnayışê ena pele '''Degusneyayo'''.\nBeno ke [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} degustış] de teferruat esto.\nŞıma be idarekerina xo ra şenê hewna [$1 nê çımraviyarnayışi bıvênê], eke wazenê dewam kerê.",
-       "rev-deleted-text-view": "Çımra viyarnayışê ena pele '''besternêno'''.\nŞıma be idarekerina xo ra şenê ey bıvênê; beno ke [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} besternayış] de teferruat esto.",
+       "rev-deleted-text-view": "Çım ra viyarnayışê enê riperri '''vındarnao'''.\nŞıma şenê bıvênê; teferruat nao naca [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} besternayış].",
        "rev-suppressed-text-view": "Çımraviyarnayışê ena pele '''degusneyayo'''.\nŞıma be idarekerina xo ra şenê ey bıvênê; beno ke [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} degusnayış] de teferruat esto.",
        "rev-deleted-no-diff": "Şıma nêşenê nê ferqi bıvênê, çıke çımraviyarnayışan ra  yew '''esteriyo'''.\nBeno ke [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log] de teferruat esto.",
        "rev-suppressed-no-diff": "Revizyon '''esteriyayo\"' aye ra ti nieşkeno ena diff bivine.",
        "search-error": "Cıgeyrayış de yew xeta emê meydan: $1",
        "preferences": "Tercihi",
        "mypreferences": "Tercihi",
-       "prefs-edits": "Amarê vurnayışan:",
+       "prefs-edits": "Amarê vırnayışan:",
        "prefsnologintext2": "Kerem ke, seba vurnayışê tercihanê xo cı kewe.",
        "prefs-skin": "Çerme",
        "skin-preview": "Verqayt",
        "action-deletelogentry": "roceka dekerdan bestern",
        "action-deletedhistory": "verora esteriya perrer bıvin",
        "action-browsearchive": "pelanê esterıteyan bıgeyre",
-       "action-undelete": "ena perer mestern",
+       "action-undelete": "Ena perre mesterê",
        "action-suppressrevision": "revizyonê nımnayi bıvin u timar kı.",
        "action-suppressionlog": "enê qeydê xısusi bıvêne",
        "action-block": "enê karberi vurnayışi ra bıreyne",
        "action-patrol": "vurnayîşê karberanê binî nişan bike patrol biye",
        "action-autopatrol": "vurnayîşê xoye nişan bike ke belli biyo patrol biye",
        "action-unwatchedpages": "listeyê pelanê seyirnibiya bivîne",
-       "action-mergehistory": "tarixê ena pele yew ke",
+       "action-mergehistory": "tarixê ena perre yew ke",
        "action-userrights": "heqqa karberanê hemî bivurne",
        "action-userrights-interwiki": "heqqa karberanê ke wikiyê binî de hemî bivurne",
        "action-siteadmin": "database kilit bike ya zi a bike",
        "action-sendemail": "e-posta bırşe",
        "action-editmyoptions": "Tercihanê xo bıvurne",
-       "action-editmywatchlist": "Listeyseyran de xo bıvırne",
+       "action-editmywatchlist": "Lista xoya ewniyayışi bıvırnê",
        "action-viewmywatchlist": "Listeyseyran de xo bıvin",
        "action-viewmyprivateinfo": "Xısusi tercihane xo bıvin",
        "action-editmyprivateinfo": "Xısusi malumate xo bıvurne",
        "randomredirect-nopages": "Cayê nameyê \"$1\" de serşıkıtışi çıniyê.",
        "statistics": "İstatistiki",
        "statistics-header-pages": "İstatistikê perer",
-       "statistics-header-edits": "İstatistikê vurnayışan",
+       "statistics-header-edits": "İstatistikê vırnayışan",
        "statistics-header-users": "İstatistikê karberi",
        "statistics-header-hooks": "Yewbina istatistiki",
        "statistics-articles": "Perê zerreki",
        "checkbox-select": "Weçinaye: $1",
        "checkbox-all": "Pêro",
        "checkbox-none": "Temam",
-       "checkbox-invert": "Dimlaşt ke (verdindayış)",
+       "checkbox-invert": "Verdindayış",
        "allpages": "Pêro peli",
        "nextpage": "Pela badê cû ($1)",
        "prevpage": "Pela verêne ($1)",
        "tooltip-pt-anonuserpage": "pelê karberê IPyi",
        "tooltip-pt-mytalk": "Pela {{GENDER:|toya}} werênayışi",
        "tooltip-pt-anontalk": "vurnayiş ê ke no Ipadresi ra biyo muneqeşa bıker",
-       "tooltip-pt-preferences": "Tercihê {{GENDER:|to}}",
+       "tooltip-pt-preferences": "Tercihê {{GENDER:|şıma}}",
        "tooltip-pt-watchlist": "Listey peranê ke to gırotê seyr kerdış",
        "tooltip-pt-mycontris": "Yew lista iştırakanê {{GENDER:|şıma}}",
        "tooltip-pt-login": "Mayê şıma ronıştış akerdışi rê dawet keme; labelê ronıştış mecburi niyo",
        "tooltip-ca-delete": "Ena pele bestere",
        "tooltip-ca-undelete": "Perer fına zey verê esternayışi kerê",
        "tooltip-ca-move": "Ena pele bıkırışe",
-       "tooltip-ca-watch": "Ena pele lista xoya seyrkerdışi ke",
+       "tooltip-ca-watch": "Ena perre lista xoya seyrkerdışi ke",
        "tooltip-ca-unwatch": "Ena pele lista xoya seyrkerdışi ra vece",
        "tooltip-search": "{{SITENAME}} de cı geyre",
        "tooltip-search-go": "Ebe nê namey tami şo yew pela ke esta",
        "expand_templates_generate_xml": "Dara XML arêdayoği bımocne",
        "expand_templates_generate_rawhtml": "Xam HTML'i bıvin",
        "expand_templates_preview": "Verqayt",
-       "pagelanguage": "Zıwanê perer bıvırnê",
+       "pagelanguage": "Zıwanê perre bıvırnê",
        "pagelang-name": "Pele",
        "pagelang-language": "Zıwan",
        "pagelang-use-default": "Zıwanê hesabiyayeyi bıgurene",
index 93c33eb..70705e5 100644 (file)
        "views": "Προβολές",
        "toolbox": "Εργαλεία",
        "tool-link-userrights": "Αλλαγή ομάδων {{GENDER:$1|χρήστη}}",
+       "tool-link-userrights-readonly": "Εμφάνιση {{GENDER:$1|ομάδων}}  χρηστών",
        "tool-link-emailuser": "Αποστολή e-mail {{GENDER:$1|στο|στη}} χρήστη",
        "userpage": "Προβολή σελίδας χρήστη",
        "projectpage": "Προβολή σελίδας εγχειρήματος",
        "botpasswords-label-delete": "Διαγραφή",
        "botpasswords-label-resetpassword": "Επαναφορά του συνθηματικού",
        "botpasswords-label-grants": "Ισχύουσες άδειες:",
-       "botpasswords-help-grants": "Î\9aάθε Ï\80αÏ\81αÏ\87Ï\8eÏ\81ηÏ\83η Î´Î¯Î½ÎµÎ¹ Ï\80Ï\81Ï\8cÏ\83βαÏ\83η Ï\83Ï\84α Î¿Ï\81ιÏ\83μένα Î´Î¹ÎºÎ±Î¹Ï\8eμαÏ\84α Ï\87Ï\81ήÏ\83Ï\84η Ï\80οÏ\85 Ï\80οÏ\85 Î®Î´Î· Î­Ï\87ει Î­Î½Î±Ï\82 Î»Î¿Î³Î±Ï\81ιαÏ\83μÏ\8cÏ\82 Ï\87Ï\81ήÏ\83Ï\84η. Î\94είÏ\84ε Ï\84η [[Special:ListGrants|Ï\80ίνακαÏ\82 παραχωρήσεων]] για περισσότερες πληροφορίες.",
+       "botpasswords-help-grants": "ΠαÏ\81αÏ\87Ï\89Ï\81εί Ï\84ην Ï\80Ï\81Ï\8cÏ\83βαÏ\83η Ï\83ε Î´Î¹ÎºÎ±Î¹Ï\8eμαÏ\84α Ï\80οÏ\85 Î®Î´Î· ÎºÎ±Ï\84έÏ\87ονÏ\84αι Î±Ï\80Ï\8c Ï\84ο Î»Î¿Î³Î±Ï\81ιαÏ\83μÏ\8c Ï\87Ï\81ήÏ\83Ï\84η Ï\83αÏ\82. Î\95νεÏ\81γοÏ\80οίηÏ\83η Î¼Î¹Î±Ï\82 Ï\80αÏ\81αÏ\87Ï\8eÏ\81ηÏ\83ηÏ\82 ÎµÎ´Ï\8e Î´ÎµÎ½ Ï\80αÏ\81έÏ\87ει Ï\80Ï\81Ï\8cÏ\83βαÏ\83η Ï\83ε Î´Î¹ÎºÎ±Î¹Ï\8eμαÏ\84α Ï\80οÏ\85 Î¿ Î»Î¿Î³Î±Ï\81ιαÏ\83μÏ\8cÏ\82 Ï\87Ï\81ήÏ\83Ï\84ηÏ\82 Ï\83αÏ\82 Î´Î¹Î±Ï\86οÏ\81εÏ\84ικά Î´ÎµÎ½ Î¸Î± ÎµÎ¯Ï\87ε. Î\94είÏ\84ε Ï\84ον [[Special:ListGrants|Ï\80ίνακα παραχωρήσεων]] για περισσότερες πληροφορίες.",
        "botpasswords-label-grants-column": "Χορηγήθηκε",
        "botpasswords-bad-appid": "Το όνομα του ρομπότ «$1» δεν είναι έγκυρο.",
        "botpasswords-insert-failed": "Αποτυχία να προστεθεί το όνομα bot \"$1\". Έχει ήδη προστεθεί;",
        "passwordreset-emailsentemail": "Αν αυτή η διεύθυνση ηλεκτρονικού ταχυδρομείου συνδέεται με το  λογαριασμό σας, τότε  θα σας αποσταλεί μήνυμα ηλεκτρονικού ταχυδρομείου για την επαναφορά του κωδικού πρόσβασης.",
        "passwordreset-emailsentusername": "Αν υπάρχει μια διεύθυνση ηλεκτρονικού ταχυδρομείου που συνδέεται με αυτό το όνομα χρήστη, τότε θα σας αποσταλεί ένα μήνυμα ηλεκτρονικού ταχυδρομείου για την επαναφορά του κωδικού πρόσβασης.",
        "passwordreset-invalidemail": "Μη έγκυρη διεύθυνση ηλεκτρονικού ταχυδρομείου",
+       "passwordreset-nodata": "Δεν δόθηκε όνομα χρήστη ή διεύθυνση email.",
        "changeemail": "Αλλαγή ή αφαίρεση της διεύθυνσης ηλεκτρονικού ταχυδρομείου",
        "changeemail-header": "Συμπληρώστε αυτήν τη φόρμα για να αλλάξετε τη διεύθυνσή σας ηλεκτρονικού ταχυδρομείου. Αν θέλετε να καταργήσετε τη σύνδεση οποιασδήποτε διεύθυνσης ηλεκτρονικού ταχυδρομείου με το λογαριασμό σας, αφήστε τη νέα διεύθυνση ηλεκτρονικού ταχυδρομείου κενή κατά την υποβολή της φόρμας.",
        "changeemail-no-info": "Πρέπει να έχετε συνδεθεί για άμεση πρόσβαση σε αυτήν τη σελίδα.",
        "selfredirect": "<strong>Προσοχή:</strong> Ανακατευθύνετε αυτή τη σελίδα στον εαυτό της. Μπορεί να δώσατε λάθος στόχο για την ανακατεύθυνση, ή μπορεί να επεξεργάζεστε λάθος σελίδα.\nΑν κάνε κλίκ στο \"{{int:savearticle}}\" ξανά, η ανακατεύθυνση θα δημιουργηθεί ούτως ή άλλως.",
        "missingcommenttext": "Παρακαλούμε εισαγάγετε σχόλιο παρακάτω.",
        "missingcommentheader": "<strong>Υπενθύμιση:</strong> δεν έχετε δώσει ένα θέμα γι' αυτό το σχόλιο.\nΕάν κάνετε κλικ στο κουμπί \"{{int:savearticle}}\" ξανά, η επεξεργασία σας θα αποθηκευτεί χωρίς αυτό.",
-       "summary-preview": "Προεπισκόπηση σύνοψης:",
+       "summary-preview": "Προεπισκόπηση σύνοψης επεξεργασίας:",
        "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Παρακαλούμε περιλαμβάνετε οποιοδήποτε ή και τα δύο από αυτά σε οποιαδήποτε ερωτήματα σας.",
        "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": "δεν δόθηκε λόγος",
        "whitelistedittext": "Πρέπει να $1 για να επεξεργαστείτε σελίδες.",
        "confirmedittext": "Πρέπει να επιβεβαιώσετε την διεύθυνση ηλεκτρονικού σας ταχυδρομείου πριν μπορέσετε να επεξεργαστείτε σελίδες. Παρακαλούμε καθορίστε και επικυρώστε την διεύθυνση ηλεκτρονικού σας ταχυδρομείου μέσω των [[Special:Preferences|προτιμήσεων χρήστη]] σας.",
        "userpage-userdoesnotexist": "Ο λογαριασμός χρήστη «$1» δεν είναι εγγεγραμμένος. Παρακαλούμε ελέγξτε αν θα θέλατε να δημιουργήσετε/επεξεργαστείτε αυτήν τη σελίδα.",
        "userpage-userdoesnotexist-view": "Ο λογαριασμός χρήστη «$1» δεν είναι εγγεγραμμένος.",
        "blocked-notice-logextract": "Επί του παρόντος, αυτός ο χρήστης έχει υποστεί φραγή. Παρακάτω παρέχεται για αναφορά η πιο πρόσφατη καταχώρηση του αρχείου φραγών.",
-       "clearyourcache": "''' Σημείωση:''' μετά την αποθήκευση, ίσως χρειαστεί να παρακάμψετε την προσωρινή μνήμη του προγράμματος περιήγησής σας για να δείτε τις αλλαγές.\n * '''Firefox / Safari:''' Κρατήστε πατημένο το ''Shift'' κάνοντας ταυτόχρονα κλικ στο κουμπί ''Ανανέωση'' ή πιέστε ''Ctrl-F5'' ή ''Ctrl-R'' ('' ⌘-R'' σε Mac)\n * '''Google Chrome:''' Πιέστε ''Ctrl-Shift-R'' (''⌘-Shift-R'' σε Mac)\n * '''Internet Explorer:''' Κρατήστε πατημένο το ''Ctrl'' κάνοντας ταυτόχρονα κλικ στο κουμπί ''Ανανέωση'', ή πιέστε ''Ctrl-F5'' \n * '''Opera:''' Εκκαθαρίστε την προσωρινή μνήμη από το μενού ''Εργαλεία → Προτιμήσεις''",
+       "clearyourcache": "<strong>Σημείωση:</strong> μετά την αποθήκευση, ίσως χρειαστεί να παρακάμψετε την προσωρινή μνήμη του προγράμματος περιήγησής σας για να δείτε τις αλλαγές.\n* <strong>Firefox / Safari:</strong> Κρατήστε πατημένο το <em>Shift</em> κάνοντας ταυτόχρονα κλικ στο κουμπί <em>Ανανέωση</em> ή πιέστε <em>Ctrl-F5</em> ή <em>Ctrl-R</em> (<em>⌘-R</em> σε Mac)\n* <strong>Google Chrome:</strong> Πιέστε <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> σε Mac)\n* <strong>Internet Explorer:</strong> Κρατήστε πατημένο το <em>Ctrl</em> κάνοντας ταυτόχρονα κλικ στο κουμπί <em>Ανανέωση</em>, ή πιέστε <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Εκκαθαρίστε την προσωρινή μνήμη από το μενού <em>Εργαλεία → Προτιμήσεις</em>",
        "usercssyoucanpreview": "'''Χρήσιμη συμβουλή:''' Χρησιμοποιήστε το κουμπί \"{{int:showpreview}}\" για να ελέγξτε τα νέα σας CSS πριν τα αποθηκεύσετε.",
        "userjsyoucanpreview": "'''Χρήσιμη συμβουλή:''' Χρησιμοποιήστε το κουμπί \"{{int:showpreview}}\" για να ελέγξτε τη νέα σας JS πριν την αποθηκεύσετε.",
        "usercsspreview": "'''Σας υπενθυμίζουμε ότι κάνετε απλώς έλεγχο/προεπισκόπηση του CSS του χρήστη -δεν το έχετε ακόμα αποθηκεύσει! '''",
        "watchlistanontext": "Παρακαλούμε συνδεθείτε για να δείτε ή να επεξεργαστείτε αντικείμενα στη λίστα παρακολούθησής σας.",
        "watchnologin": "Δεν έχετε συνδεθεί.",
        "addwatch": "Προσθήκη στη λίστα παρακολούθησης",
-       "addedwatchtext": "Το Î»Î®Î¼Î¼Î± Â«[[:$1]]» ÎºÎ±Î¹ Î· Ï\83ελίδα Ï\83Ï\85ζήÏ\84ηÏ\83ήÏ\82 Ï\84οÏ\85 Î­Ï\87οÏ\85ν Ï\80Ï\81οÏ\83Ï\84εθεί Ï\83Ï\84η [[Special:Watchlist|λίÏ\83Ï\84α Ï\80αÏ\81ακολοÏ\8dθηÏ\83ήÏ\82]] Ï\83αÏ\82.",
+       "addedwatchtext": "Î\97 Ï\83ελίδα Â«[[:$1]]» ÎºÎ±Î¹ Î· Ï\83ελίδα Ï\83Ï\85ζήÏ\84ηÏ\83ήÏ\82 Ï\84ηÏ\82 Ï\80Ï\81οÏ\83Ï\84έθηκαν Ï\83Ï\84η [[Special:Watchlist|λίÏ\83Ï\84α Ï\80αÏ\81ακολοÏ\8dθηÏ\83ήÏ\82 Ï\83αÏ\82]].",
        "addedwatchtext-short": "Η σελίδα «$1» έχει προστεθεί στην λίστα παρακολούθησής σας.",
        "removewatch": "Αφαίρεση από τη λίστα παρακολούθησης",
        "removedwatchtext": "Το λήμμα «[[:$1]]» και η σελίδα συζήτησής του έχουν αφαιρεθεί από τη [[Special:Watchlist|λίστα παρακολούθησής]] σας.",
index 8957b4c..bf06e49 100644 (file)
@@ -27,7 +27,9 @@
                        "SamanthaNguyen",
                        "Usandaru555",
                        "Aefgh39622",
-                       "Anomie"
+                       "Anomie",
+                       "Dr. Shikha Jaggi",
+                       "Xð"
                ]
        },
        "tog-underline": "Link underlining:",
        "and": "&#32;and",
        "qbfind": "Find",
        "qbbrowse": "Browse",
-       "qbedit": "Edit",
-       "qbpageoptions": "This page",
-       "qbmyoptions": "My pages",
+       "qbedit": "संपादित करें",
+       "qbpageoptions": "यह पन्ना",
+       "qbmyoptions": "मेरे पृष्ठों",
        "faq": "FAQ",
        "faqpage": "Project:FAQ",
        "actions": "Actions",
        "unprotectthispage": "Change protection of this page",
        "newpage": "New page",
        "talkpage": "Discuss this page",
-       "talkpagelinktext": "Talk",
+       "talkpagelinktext": "talk",
        "specialpage": "Special page",
        "personaltools": "Personal tools",
        "articlepage": "View content page",
index abee4a9..b7078dd 100644 (file)
        "rcfilters-invalid-filter": "Invalid filter",
        "rcfilters-empty-filter": "No active filters. All contributions are shown.",
        "rcfilters-filterlist-title": "Filters",
+       "rcfilters-filterlist-feedbacklink": "Provide feedback on the new (beta) filters",
        "rcfilters-highlightbutton-title": "Highlight results",
        "rcfilters-highlightmenu-title": "Select a color",
+       "rcfilters-highlightmenu-help": "Select a color to highlight this property",
        "rcfilters-filterlist-noresults": "No filters found",
        "rcfilters-filtergroup-registration": "User registration",
        "rcfilters-filter-registered-label": "Registered",
index 19a9c27..9a31dbd 100644 (file)
        "databaseerror-query": "Consulta: $1",
        "databaseerror-function": "Función: $1",
        "databaseerror-error": "Error: $1",
-       "transaction-duration-limit-exceeded": "Para evitar la creación de lentitud alta de respuesta, la transacción fue abortada porque la duración de escritura ($1) excedió el límite de $2 {{PLURAL:$2|segundo|segundos}}.\nSi estás cambiando muchos elementos a la vez, trata de hacer operaciones similares más pequeñas.",
+       "transaction-duration-limit-exceeded": "Con el fin de evitar un aumento excesivo del retardo de replicación, se anuló esta transacción porque la duración de escritura ($1) excedió el límite de $2 {{PLURAL:$2|segundo|segundos}}.\nSi estás cambiando muchos elementos a la vez, trata de hacer operaciones similares más pequeñas.",
        "laggedslavemode": "<strong>Advertencia:</strong> puede que falten las actualizaciones más recientes en esta página.",
        "readonly": "Base de datos bloqueada",
        "enterlockreason": "Explica el motivo del bloqueo, incluyendo una estimación de cuándo se producirá el desbloqueo",
        "sp-contributions-blocked-notice-anon": "Esta dirección IP se encuentra actualmente bloqueada.\nA continuación se muestra la última entrada del registro de bloqueos para mayor referencia.",
        "sp-contributions-search": "Buscar contribuciones",
        "sp-contributions-username": "Dirección IP o nombre de usuario:",
-       "sp-contributions-toponly": "Solo mostrar últimas ediciones de página",
+       "sp-contributions-toponly": "Mostrar solo últimas ediciones de página",
        "sp-contributions-newonly": "Mostrar solo ediciones que son creaciones de páginas",
        "sp-contributions-hideminor": "Ocultar ediciones menores",
        "sp-contributions-submit": "Buscar",
        "reblock-logentry": "cambió el bloqueo para  [[$1]] con una caducidad de $2 $3",
        "blocklogtext": "Esto es un registro de acciones de bloqueo y desbloqueo de usuarios.\nLas direcciones IP bloqueadas automáticamente no aparecen aquí.\nConsulta la [[Special:BlockList|lista de bloqueos]] para ver la lista de bloqueos y prohibiciones de operar en vigor.",
        "unblocklogentry": "desbloqueó a $1",
-       "block-log-flags-anononly": "sólo anónimos",
+       "block-log-flags-anononly": "solo anónimos",
        "block-log-flags-nocreate": "desactivada la creación de cuentas",
        "block-log-flags-noautoblock": "bloqueo automático desactivado",
        "block-log-flags-noemail": "correo electrónico desactivado",
index f9eb200..b0b5e1f 100644 (file)
        "logentry-patrol-patrol": "$1(e)k $3 orrialdearen $4 berrikuspena patruilatutzat {{GENDER:$2|markatu}} du",
        "logentry-newusers-newusers": "$1 erabiltzaile kontua {{GENDER:$2|sortu da}}",
        "logentry-newusers-create": "$1 erabiltzaile kontua {{GENDER:$2|sortu da}}",
-       "logentry-newusers-create2": "$1 wikilariak $3 erabiltzaile kontua sortu du",
+       "logentry-newusers-create2": "$1 wikilariak $3 erabiltzaile kontua {{GENDER:$2|sortu}} du",
        "logentry-newusers-byemail": "$1(e)k $3 erabiltzaile kontua {{GENDER:$2|sortu du}} eta pasahitza emailez bidali da",
        "logentry-newusers-autocreate": "$1 erabiltzaile kontua automatikoki {{GENDER:$2|sortu da}}",
        "logentry-upload-upload": "$1(e)k $3 {{GENDER:$2|igo du}}",
index dcc7244..ff28894 100644 (file)
        "blockedtitle": "کاربر بسته شده‌است",
        "blockedtext": "<strong>دسترسی حساب کاربری یا نشانی آی‌پی شما بسته شده‌است.</strong>\n\nاین قطع دسترسی توسط $1 انجام شده است.\nدلیل ارائه‌شده چنین است: <em>$2</em>\n\n* شروع قطع دسترسی: $8\n* پایان قطع دسترسی: $6\n* کاربری هدف قطع دسترسی: $7\n\nشما می‌توانید با $1 یا [[{{MediaWiki:Grouppage-sysop}}|مدیری]] دیگر تماس بگیرید و در این باره صحبت کنید.\nتوجه کنید که شما نمی‌توانید از قابلیت «ایمیل به این کاربر» استفاده کنید مگر آنکه آدرس ایمیل معتبری در [[Special:Preferences|ترجیحات کاربری]] خودتان ثبت کرده باشید و نیز باید امکان استفاده از این قابلیت برای شما قطع نشده باشد.\nنشانی آی‌پی فعلی شما $3 و شمارهٔ قطع دسترسی شما $5 است.\nلطفاً تمامی جزئیات فوق را در کلیهٔ درخواست‌هایی که در این باره مطرح می‌کنید ذکر کنید.",
        "autoblockedtext": "دسترسی نشانی آی‌پی شما قطع شده‌است، زیرا این نشانی آی‌پی توسط کاربر دیگری استفاده شده که دسترسی او توسط $1 قطع شده‌است.\nدلیل ارائه‌شده چنین است:\n\n:''$2''\n\n* شروع قطع دسترسی: $8\n* پایان قطع دسترسی: $6\n* کاربری هدف قطع دسترسی: $7\n\nشما می‌توانید با $1 یا [[{{MediaWiki:Grouppage-sysop}}|مدیری]] دیگر تماس بگیرید و در این باره صحبت کنید.\nتوجه کنید که شما نمی‌توانید از قابلیت «ایمیل به این کاربر» استفاده کنید مگر آنکه نشانی ایمیل معتبری در [[Special:Preferences|ترجیحات کاربری]] خودتان ثبت کرده باشید و نیز باید امکان استفاده از این قابلیت برای شما قطع نشده باشد.\nنشانی آی‌پی فعلی شما $3 و شمارهٔ قطع دسترسی شما $5 است.\nلطفاً تمامی جزئیات فوق را در کلیهٔ درخواست‌هایی که در این باره مطرح می‌کنید ذکر کنید.",
+       "systemblockedtext": "نام کاربری یا نشانی آی‌پی شما خودکار توسط مدیاویکی مسدود شده‌است.\nدلیل ارائه‌شده:\n\n:<em>$2</em>\n\n* آغاز بلاک: $8\n* پایان بلاک: $6\n* قطع دسترسی‌شده مورد نظر: $7\n\nنشانی آی‌پی کنونی شما $3 است.\nخواهشمند است تمام جزئیات بالا را در هر پرس‌وجویی که انجام می‌دهید قرار دهید.",
        "blockednoreason": "دلیلی مشخص نشده‌است",
        "whitelistedittext": "برای ویرایش مقاله‌ها باید $1.",
        "confirmedittext": "شما باید، پیش از ویرایش صفحات، آدرس ایمیل خود را مشخص و تأیید کنید. لطفاً از طریق [[Special:Preferences|ترجیحات کاربر]] این کار را صورت دهید.",
        "youremail": "ایمیل:",
        "username": "{{GENDER:$1|نام کاربری}}:",
        "prefs-memberingroups": "{{GENDER:$2|عضو}} {{PLURAL:$1|گروه|گروه}}:",
+       "group-membership-link-with-expiry": "$1 (تا $2)",
        "prefs-registration": "زمان ثبت‌نام:",
        "yourrealname": "نام واقعی:",
        "yourlanguage": "زبان:",
        "userrights-user-editname": "یک نام کاربری وارد کنید:",
        "editusergroup": "بارگیری گروه‌های کاربر",
        "editinguser": "تغییر اختیارات کاربری کاربر {{GENDER:$1|کاربر}} <strong>[[User:$1|$1]]</strong> $2",
-       "userrights-editusergroup": "ویرایش گروه‌های کاربری",
+       "viewinguserrights": "دیدن دسترسی {{GENDER:$1|کاربری}} <strong>[[User:$1|$1]]</strong> $2",
+       "userrights-editusergroup": "ویرایش گروه‌های {{GENDER:$1|کاربر}}",
+       "userrights-viewusergroup": "مشاهدهٔ گروه‌های {{GENDER:$1|کاربر}}",
        "saveusergroups": "ثبت گروه‌های {{GENDER:$1|کاربری}}",
        "userrights-groupsmember": "عضو:",
        "userrights-groupsmember-auto": "عضو ضمنی:",
-       "userrights-groups-help": "شما می‌توانید گروه‌هایی را که کاربر در آن قرار دارد تغییر دهید:\n* جعبهٔ علامت‌خورده نشانهٔ بودن کاربر در آن گروه است.\n* جعبهٔ خالی نشانهٔ نبودن کاربر در آن گروه است.\n* علامت * به این معنی‌است که اگر آن گروه را بیفزایید نمی‌توانید بعداً برش دارید، و برعکس.",
+       "userrights-groups-help": "شما می‌توانید گروه‌هایی را که کاربر در آن قرار دارد تغییر دهید:\n* جعبهٔ علامت‌خورده نشانهٔ بودن کاربر در آن گروه است.\n* جعبهٔ خالی نشانهٔ نبودن کاربر در آن گروه است.\n* علامت * به این معنی‌است که اگر آن گروه را بیفزایید نمی‌توانید بعداً برش دارید، و برعکس.\n* علامت # را فقط می‌توانید پیش از تاریخ انقضای گروه قرار دهید؛ نمی‌توانید آن را جلو بیاورید.",
        "userrights-reason": "دلیل:",
        "userrights-no-interwiki": "شما اجازهٔ تغییر اختیارات کاربران دیگر ویکی‌ها را ندارید.",
        "userrights-nodatabase": "پایگاه دادهٔ $1 وجود ندارد یا محلی نیست.",
        "userrights-expiry": "زمان سرآمدن:",
        "userrights-expiry-existing": "زمان انقضای موجود: $2، $3",
        "userrights-expiry-othertime": "زمانی دیگر:",
+       "userrights-expiry-options": "۱ روز:1 day,۱ هفته:1 week,۱ ماه:1 month,۳ ماه:3 months,۶ ماه:6 months,۱ سال:1 year",
+       "userrights-invalid-expiry": "زمان انقضای گروه «$1» نادرست است.",
+       "userrights-expiry-in-past": "زمان انقضای گروه «$1» گذشته‌است.",
+       "userrights-cannot-shorten-expiry": "امکان جلو آوردن تاریخ انقضای گروه  \"$1\" را ندارید. تنها کاربرانی که دسترسی اضافه و حذف این گروه را دارند می‌توانند تاریخ انقضا را جلو بیاورند.",
        "userrights-conflict": "تعارض دسترسی‌های کاربری! لطفاً بررسی کنید و تغییرات را تأیید کنید.",
        "group": "گروه:",
        "group-user": "کاربران",
        "action-upload_by_url": "بارگذاری این پرونده از یک نشانی اینترنتی",
        "action-writeapi": "استفاده از API نوشتن",
        "action-delete": "حذف این صفحه",
-       "action-deleterevision": "حذف این نسخه",
+       "action-deleterevision": "حذف نسخه‌ها",
+       "action-deletelogentry": "حذف سیاههٔ ورودی‌ها",
        "action-deletedhistory": "مشاهدهٔ تاریخچهٔ حذف شدهٔ این صفحه",
+       "action-deletedtext": "مشاهدهٔ متن نسخهٔ حذف‌شده",
        "action-browsearchive": "جستجوی صفحه‌های حذف‌شده",
-       "action-undelete": "احÛ\8cاÛ\8c Ø§Û\8cÙ\86 ØµÙ\81Ø­Ù\87",
+       "action-undelete": "احÛ\8cاÛ\8c ØµÙ\81Ø­Ù\87â\80\8cÙ\87ا",
        "action-suppressrevision": "مشاهده و احیای ویرایش‌های حذف شده",
        "action-suppressionlog": "مشاهدهٔ این سیاههٔ خصوصی",
        "action-block": "قطع دسترسی این کاربر از ویرایش‌کردن",
        "action-userrights-interwiki": "ویرایش اختیارات کاربری کاربران یک ویکی دیگر",
        "action-siteadmin": "قفل‌کردن و بازکردن پایگاه داده‌ها",
        "action-sendemail": "ارسال ایمیل",
+       "action-editmyoptions": "ویرایش ترجیحاتتان",
        "action-editmywatchlist": "فهرست پیگیری‌های خود را ویرایش کنید",
        "action-viewmywatchlist": "فهرست پیگیری‌های خود را ببینید",
        "action-viewmyprivateinfo": "اطلاعات خصوصی خود را ببینید",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (همچنین به [[Special:NewPages|فهرست صفحات تازه]] نگاه کنید)",
        "recentchanges-legend-plusminus": "(<em>±۱۲۳</em>)",
        "recentchanges-submit": "نمایش",
+       "rcfilters-activefilters": "فعال‌کردن پالایه‌ها",
+       "rcfilters-restore-default-filters": "بازگردانی پالایه‌های پیش‌فرض",
+       "rcfilters-clear-all-filters": "پاک‌کردن پالایش‌ها",
+       "rcfilters-search-placeholder": "پالایش تغییرات اخیر (جستجو یا شروع به تایپ)",
+       "rcfilters-invalid-filter": "پالایهٔ نامعتبر",
+       "rcfilters-empty-filter": "پالایه‌ای فعال نیست. همهٔ مشارکت‌های دیده می‌شوند.",
+       "rcfilters-filterlist-title": "پالایه‌ها",
+       "rcfilters-filterlist-feedbacklink": "ارسال بازخورد برای پالایه‌های جدید (آزمایشی)",
+       "rcfilters-highlightbutton-title": "پررنگ کردن نتایج",
+       "rcfilters-highlightmenu-title": "انتخاب رنگ",
+       "rcfilters-filterlist-noresults": "پالایه‌ای یافت نشد",
+       "rcfilters-filtergroup-registration": "ثبت‌نام کاربر",
+       "rcfilters-filter-registered-label": "ثبت شده",
+       "rcfilters-filter-registered-description": "ورود ویرایشگران.",
+       "rcfilters-filter-unregistered-label": "ثبت‌نام نکرده",
+       "rcfilters-filter-unregistered-description": "ویرایشگرانی که به سامانه وارد نشده‌اند.",
+       "rcfilters-filtergroup-authorship": "ویرایش نویسندگی",
+       "rcfilters-filter-editsbyself-label": "ویرایش‌های شما",
+       "rcfilters-filter-editsbyself-description": "ویرایش‌های انجام شده توسط شما.",
+       "rcfilters-filter-editsbyother-label": "ویرایش‌های دیگران",
+       "rcfilters-filter-editsbyother-description": "ویرایش‌های ایجاد شده توسط دیگران (نه شما).",
+       "rcfilters-filtergroup-userExpLevel": "درجهٔ تجربه (فقط برای کاربران ثبت‌نام کرده)",
+       "rcfilters-filter-userExpLevel-newcomer-label": "تازه‌واردها",
+       "rcfilters-filter-userExpLevel-newcomer-description": "کمتر از ۱۰ ویرایش یا ۴ روز فعالیت.",
+       "rcfilters-filter-userExpLevel-learner-label": "آموزندگان",
+       "rcfilters-filter-userExpLevel-learner-description": "فعالیت و تعداد روز بیشتر از تازه‌وارد ولی کمتر از کاربر باتجریه.",
+       "rcfilters-filter-userExpLevel-experienced-label": "کاربران باتجربه",
+       "rcfilters-filter-userExpLevel-experienced-description": "بیشتر از ۳۰ روز فعالیت و ۵۰۰ ویرایش.",
+       "rcfilters-filtergroup-automated": "ویرایش‌های خودکار",
+       "rcfilters-filter-bots-label": "ربات",
+       "rcfilters-filter-bots-description": "ویرایش توسط ابزارهای خودکار.",
+       "rcfilters-filter-humans-label": "انسان (ربات نه)",
+       "rcfilters-filter-humans-description": "ویرایش توسط انسان.",
+       "rcfilters-filtergroup-significance": "اهمیت",
+       "rcfilters-filter-minor-label": "ویرایش‌های جزئی",
+       "rcfilters-filter-minor-description": "ویرایش‌هایی که به عنوان جزئی برچسب خورده‌اند.",
+       "rcfilters-filter-major-label": "ویرایش‌های غیرجزئی",
+       "rcfilters-filter-major-description": "ویرایش‌هایی که برچسب جزئی نخوردند.",
+       "rcfilters-filtergroup-changetype": "نوع تغییرات",
+       "rcfilters-filter-pageedits-label": "ویرایش‌های صفحه",
+       "rcfilters-filter-pageedits-description": "ویرایش‌های محتوای ویکی، بحث‌ها، توضیحات رده...",
+       "rcfilters-filter-newpages-label": "ایجاد صفحه",
+       "rcfilters-filter-newpages-description": "ویرایش‌هایی که منجر به ایجاد صفحه شده‌اند.",
+       "rcfilters-filter-categorization-label": "تغییرات رده",
+       "rcfilters-filter-categorization-description": "سیاههٔ صفحاتی که به رده افزوده یا حذف شده‌اند.",
+       "rcfilters-filter-logactions-label": "سیاههٔ فعالیت‌ها",
+       "rcfilters-filter-logactions-description": "فعالیت‌های مدیریتی، ایجاد حساب، حذف صفحه، بارگذاری‌ها ....",
        "rcnotefrom": "در زیر تغییرات از <strong>$3, $4</strong> (تا <strong>$1</strong> {{PLURAL:$5|نشان داده شده‌است|نشان داده شده‌اند}}).",
        "rclistfrom": "نمایش تغییرات تازه با شروع از $3 $2",
        "rcshowhideminor": "$1 ویرایش‌های جزئی",
        "uncategorizedcategories": "رده‌های رده‌بندی‌نشده",
        "uncategorizedimages": "پرونده‌های رده‌بندی‌نشده",
        "uncategorizedtemplates": "الگوهای رده‌بندی‌نشده",
+       "uncategorized-categories-exceptionlist": "# شامل فهرست رده‌هایی که باید در ویژه:رده‌های_رده‌بندی‌نشده اصلاح شوند. هر خطی که با \"*\" شروع شده‌است. خطوطی که با نویسه‌های دیگر شروع شده‌اند در نظر گرفته نمی‌شوند (حتی فاصله). برای توضیحات از \"#\" استفاده کنید.",
        "unusedcategories": "رده‌های استفاده‌نشده",
        "unusedimages": "پرونده‌های استفاده‌نشده",
        "wantedcategories": "رده‌های مورد نیاز",
        "apisandbox-sending-request": "ارسال درخواست ای‌پی‌آی...",
        "apisandbox-loading-results": "دریافت درخواست‌های ای‌پی‌آی...",
        "apisandbox-results-error": "در زمان بارگیری پاسخ کوئری API خطایی رخ داده‌است: $1.",
+       "apisandbox-request-selectformat-label": "نمایش داده‌های مورد درخواست به عنوان:",
+       "apisandbox-request-format-url-label": "آدرس اینترنتی متن پرسمان",
        "apisandbox-request-url-label": "درخواست آدرس:",
+       "apisandbox-request-json-label": "درخواست JSON:",
        "apisandbox-request-time": "زمان درخواست: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "توکن را اصلاح کنید و از نو ارسال کنید",
        "apisandbox-results-fixtoken-fail": "خطا در دریافت توکن \"$1\"",
        "emailccsubject": "رونوشت پیغام شما به $1: $2",
        "emailsent": "ایمیل ارسال شد",
        "emailsenttext": "پیام ایمیل شما فرستاده شد.",
-       "emailuserfooter": "این ایمیل با استفاده از ویژگی «{{int:emailuser}}» {{SITENAME}} توسط $1 به {{GENDER:$2|$2}} {{GENDER:$1|ارسال شد}}.",
+       "emailuserfooter": "این ایمیل با استفاده از ویژگی «{{int:emailuser}}» {{SITENAME}} توسط $1 به {{GENDER:$2|$2}} {{GENDER:$1|ارسال شد}}.\n\nاگر {{GENDER:$2|شما}} به این ایمیل پاسخ دهید، به {{GENDER:$2|فرستنده}} ایمیل اصلی را ارسال {{GENDER:$1|کنید}}، آدرس ایمیل شما برای {{GENDER:$1|آنها}} ارسال می‌شود.",
        "usermessage-summary": "گذاشتن پیغام سامانه.",
        "usermessage-editor": "پیغام رسان سامانه",
        "watchlist": "فهرست پی‌گیری",
        "editcomment": "خلاصهٔ ویرایش این بود:  <em>«$1»</em>.",
        "revertpage": "ویرایش [[Special:Contributions/$2|$2]] ([[User talk:$2|بحث]]) به آخرین تغییری که [[User:$1|$1]] انجام داده بود واگردانده شد",
        "revertpage-nouser": "ویرایش‌های انجام‌شده توسط (نام کاربری حذف شده) به آخرین ویرایش [[User:$1|$1]] واگردانی شد.",
-       "rollback-success": "ویرایش‌های $1 واگردانی شد؛\nصفحه به آخرین ویرایش $2 برگردانده شد.",
+       "rollback-success": "ویرایش‌های {{GENDER:$3|$1}} واگردانی شد؛\nصفحه به آخرین ویرایش {{GENDER:$4|$2}} برگردانده شد.",
        "rollback-success-notify": "ویرایش‌های توسط $1 واگردانی شد؛\nبه آخرین نسخه توسط $2 بازگردانی شد. [$3 نمایش تغییرات]",
        "sessionfailure-title": "خطای نشست کاربری",
        "sessionfailure": "به نظر می‌رسد مشکلی در مورد نشست کاربری شما وجود دارد؛\nعمل درخواست شده در اقدامی پیشگیرانه در برابر ربوده‌شدن اطلاعات نشست کاربری، لغو شد.\nلطفاً دکمهٔ «بازگشت» را در مرورگر خود بفشارید و صفحه‌ای که از آن به اینجا رسیده‌اید را دوباره فراخوانی کنید، سپس مجدداً سعی کنید.",
        "changecontentmodel-emptymodels-title": "هيچ مدل محتوایی در دسترس نيست",
        "changecontentmodel-emptymodels-text": "محتوای موجود در [[:$1]] به هيچ نوعی نمی‌تواند تبديل شود.",
        "log-name-contentmodel": "سیاهه تغییر نمونه محتوی",
-       "log-description-contentmodel": "رÙ\88Û\8cدادÙ\87اÛ\8c Ù\85رتبط Ø¨Ø§ Ù\86Ù\85Ù\88Ù\86Ù\87 Ù\85حتÙ\88Û\8câ\80\8cÙ\87اÛ\8c Û\8cÚ© ØµÙ\81Ø­Ù\87",
+       "log-description-contentmodel": "اÛ\8cÙ\86 ØµÙ\81Ø­Ù\87 ØªØºÛ\8cÛ\8cرات Ù\85حتÙ\88Û\8c ØµÙ\81حاتÛ\8c Ú©Ù\87 Ø¨Ø§ Ù\85حتÙ\88Û\8c ØºÛ\8cر Ø§Ø² Ù¾Û\8cØ´â\80\8cÙ\81رض Ø§Û\8cجاد Ø´Ø¯Ù\87â\80\8cاÙ\86دØ\8c Ø±Ø§ Ù\81Ù\87رست Ù\85Û\8câ\80\8cÚ©Ù\86د.",
        "logentry-contentmodel-new": "صفحهٔ $3 با استفاده از مدل‌های محتوایی غیر پیش‌فرض «$5» توسط $1 {{GENDER:$2|ساخته شد}}",
        "logentry-contentmodel-change": "نمونه محتوای صفحهٔ $3 از \"$4\" به \"$5\" توسط $1 {{GENDER:$2|تغییر داده شد}}",
        "logentry-contentmodel-change-revertlink": "واگردانی",
        "proxyblockreason": "نشانی آی‌پی شما بسته شده است چون متعلق به یک پروکسی باز است.\nلطفاً با ارائه دهندهً خدمات اینترنت خود یا پشتیبانی فنی تماس بگیرید و آنها را از این مشکل امنیتی جدی آگاه کنید.",
        "sorbsreason": "نشانی آی‌پی شما توسط DNSBL مورد استفاده {{SITENAME}} به عنوان یک پروکسی باز گزارش شده است.",
        "sorbs_create_account_reason": "نشانی آی‌پی شما توسط DNSBL مورد استفاده {{SITENAME}} به عنوان یک پروکسی باز گزارش شده‌است.\nشما اجازهٔ ساختن حساب کاربری ندارید.",
+       "softblockrangesreason": "کاربران ثبت‌نام نکرده نمی‌توانند از IP شما ($1) برای ویرایش استفاده کنند. لطفاً به سامانه وارد شوید.",
        "xffblockreason": "نشانی آی‌پی در X-Forwarded-For header موجود است و پروکسی شما یا سروری که از آن استفاده می‌کنید بسته‌شده‌است. دلیل بسته‌شدن: $1",
        "cant-see-hidden-user": "کاربری که می‌خواهید ببندید قبلاً بسته شده و پنهان گردیده است. چون شما دسترسی پنهان کردن کاربران را ندارید، نمی‌توانید قطع دسترسی کاربر را ببینید یا ویرایش کنید.",
        "ipbblocked": "شما نمی‌توانید دسترسی دیگر کاربران را ببندید یا باز کنید زیرا دسترسی خودتان بسته است.",
        "cant-move-to-user-page": "شما اجازه ندارید که یک صفحه را به یک صفحهٔ کاربر انتقال دهید (به استثنای زیر صفحه‌های کاربری).",
        "cant-move-category-page": "شما اجازهٔ انتقال دادن صفحهٔ رده‌ها را ندارید.",
        "cant-move-to-category-page": "شما مجوز برای انتقال صفحه به صفحه رده ندارید.",
+       "cant-move-subpages": "شما اجازهٔ انتقال دادن زیرصفحات را ندارید.",
+       "namespace-nosubpages": "فضای نام \"$1\" اجازهٔ استفاده یا ایجاد زیرصفحه نمی‌دهد.",
        "newtitle": "عنوان تازه:",
        "move-watch": "پی‌گیری صفحه‌های مبدأ و مقصد",
        "movepagebtn": "صفحه منتقل شود",
        "pageinfo-length": "حجم صفحه  (بایت)",
        "pageinfo-article-id": "شناسهٔ صفحه",
        "pageinfo-language": "زبان محتوای صفحه",
+       "pageinfo-language-change": "تغییر",
        "pageinfo-content-model": "ساختار محتوای صفحه",
        "pageinfo-content-model-change": "تغییر",
        "pageinfo-robot-policy": "‌فهرست‌کردن توسط ربات‌ها",
        "logentry-tag-update-logentry": "$1 برچسب سیاههٔ $5 صفحهٔ $3 را {{GENDER:$2|به‌روز کرد}} ($6 {{PLURAL:$7|افزوده‌شد}}؛ $8 {{PLURAL:$9|حذف شد}})",
        "rightsnone": "(هیچ)",
        "revdelete-summary": "خلاصه ویرایش",
+       "rightslogentry-temporary-group": "$1 (موقت، تا $2)",
        "feedback-adding": "افزودن بازخورد به صفحه...",
        "feedback-back": "بازگشت",
        "feedback-bugcheck": "عالی‌است! فقط بررسی کنید که از [$1 ایرادهای شناخته‌شده] نباشد.",
        "api-error-emptypage": "ایجاد صفحه‌های خالی مجاز نیست.",
        "api-error-publishfailed": "خطای داخلی: کارساز نمی‌تواند پرونده موقت را ذخیره کند.",
        "api-error-stashfailed": "خطای داخلی: کارساز نمی‌تواند پرونده موقت را ذخیره کند.",
-       "api-error-unknown-warning": "اخطار ناشناخته: $1",
+       "api-error-unknown-warning": "اخطار ناشناخته: \"$1\".",
        "api-error-unknownerror": "خطای ناشناخته: «$1».",
        "duration-seconds": "$1 ثانیه",
        "duration-minutes": "$1 دقیقه",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|بایت|بایت}}",
        "limitreport-expansiondepth": "بیشترین عمق گسترش",
        "limitreport-expensivefunctioncount": "تعداد تابع تجزیه‌گر پرمصرف",
-       "expandtemplates": "بسطدادن الگوها",
+       "expandtemplates": "بسط دادن الگوها",
        "expand_templates_intro": "این صفحهٔ ویژه متنی را دریافت کرده و تمام الگوهای به‌کاررفته در آن را به طور بازگشتی بسط می‌دهد. همچنین تابع‌های تجزیه چون <code><nowiki>{{</nowiki>#language:…}}</code> و متغیرهایی چون  <code><nowiki>{{</nowiki>CURRENTDAY}}</code> را هم بسط می‌دهد — در واقع تقریباً هرچه را که داخل دوآکولاد باشد. این کار با صدازدن مرحلهٔ تجزیهٔ مربوط در خود مدیاویکی صورت می‌گیرد.",
        "expand_templates_title": "عنوان موضوع، برای {{FULLPAGENAME}} و غیره:",
        "expand_templates_input": "متن ورودی:",
        "pagelang-language": "زبان",
        "pagelang-use-default": "استفاده از زبان پیش‌فرض",
        "pagelang-select-lang": "انتخاب زبان",
+       "pagelang-reason": "دلیل",
        "pagelang-submit": "اعمال",
+       "pagelang-nonexistent-page": "صفحهٔ $1 وجود ندارد.",
+       "pagelang-unchanged-language": "صفحهٔ $1 برای زبان $2 تنظیم شده‌است.",
+       "pagelang-unchanged-language-default": "صفحهٔ $1 برای محتوی زبانی پیش‌فرض ویکی، تعریف شده‌است.",
+       "pagelang-db-failed": "پایگاه داده برای تغییر زبان صفحه خطا داد.",
        "right-pagelang": "تغییر صفحهٔ زبان",
        "action-pagelang": "تغییر زبان صفحه",
        "log-name-pagelang": "سیاههٔ تغییر زبان",
        "mw-widgets-titleinput-description-new-page": "این صفحه هنوز وجود ندارد",
        "mw-widgets-titleinput-description-redirect": "تغییر مسیر به $1",
        "mw-widgets-categoryselector-add-category-placeholder": "در حال افزودن رده ...",
+       "mw-widgets-usersmultiselect-placeholder": "افزودن بیشتر...",
        "sessionmanager-tie": "نمی‌توان چندین نوع درخواست هویت‌سنجی را ترکیب کرد: $1.",
        "sessionprovider-generic": "$1 فصل",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "فصل‌های کوکی‌محور",
        "sessionprovider-nocookies": "کوکی‌ها ممکن است غیر فعال شده باشند. اطمینان کسب کنید که کوکی‌ها را فعال کرده‌اید و دوباره آغاز کنید.",
        "randomrootpage": "صفحهٔ ریشهٔ تصادفی",
        "log-action-filter-block": "نوع بسته شدن:",
-       "log-action-filter-contentmodel": "تغییر نوع contentmodel:",
+       "log-action-filter-contentmodel": "نوع تغییرات مدل محتوا:",
        "log-action-filter-delete": "نوع حذف:",
        "log-action-filter-import": "نوع واردات",
        "log-action-filter-managetags": "نوع مدیریت",
        "log-action-filter-block-reblock": "تصحیح بلاک",
        "log-action-filter-block-unblock": "باز شدن",
        "log-action-filter-contentmodel-change": "تغییر مدل محتوا",
-       "log-action-filter-contentmodel-new": "ایجاد صفحه با contentmodel غیر استاندارد",
+       "log-action-filter-contentmodel-new": "ایجاد صفحه با مدل محتوای غیر استاندارد",
        "log-action-filter-delete-delete": "حذف صفحه",
        "log-action-filter-delete-delete_redir": "رونویسی تغییرمسیر",
        "log-action-filter-delete-restore": "احیای صفحه",
        "usercssispublic": "لطفاً توجه کنید: زیرصفحه‌های سی‌اس‌اس نباید حاوی اطلاعات محرمانه باشند چون توسط دیگران قابل مشاهده هستند.",
        "restrictionsfield-badip": "نشانی یا بازهٔ آی‌پی نامعتبر: $1",
        "restrictionsfield-label": "بازه‌های آی‌پی مجاز:",
-       "restrictionsfield-help": "یک نشانی آی‌پی یا بازهٔ سی‌آی‌دی‌ار در هر خط وارد کنید. برای فعال کردن همه‌چیز، این مقدار را استفاده کنید: <code>0.0.0.0/0</code><br><code>::/0</code>"
+       "restrictionsfield-help": "یک نشانی آی‌پی یا بازهٔ سی‌آی‌دی‌ار در هر خط وارد کنید. برای فعال کردن همه‌چیز، این مقدار را استفاده کنید: <code>0.0.0.0/0</code><br /><code>::/0</code>",
+       "revid": "نسخهٔ $1",
+       "pageid": "شناسهٔ صفحهٔ $1"
 }
index 1e72167..aa1e090 100644 (file)
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Näytä",
        "rcfilters-activefilters": "Aktiiviset suodattimet",
+       "rcfilters-restore-default-filters": "Palauta oletussuodattimet",
        "rcfilters-clear-all-filters": "Tyhjennä kaikki suodattimet",
        "rcfilters-search-placeholder": "Suodattimen viimeaikaiset muutokset (selaa tai aloita kirjoittaa)",
        "rcfilters-invalid-filter": "Suodatin on epäkelpo",
        "rcfilters-empty-filter": "Ei aktiivisia suodattimia. Kaikki muutokset näytetään.",
        "rcfilters-filterlist-title": "Suodattimet",
+       "rcfilters-highlightmenu-title": "Valitse väri",
        "rcfilters-filterlist-noresults": "Ei löytynyt suodattimia",
+       "rcfilters-filtergroup-registration": "Käyttäjän rekisteröinti",
        "rcfilters-filter-registered-label": "Rekisteröitynyt",
        "rcfilters-filter-registered-description": "Kirjautuneet muokkaukset.",
+       "rcfilters-filter-unregistered-label": "Rekisteröimätön",
        "rcfilters-filter-unregistered-description": "Muokkaajat, jotka eivät ole kirjautuneet sisään.",
        "rcfilters-filter-editsbyself-label": "Omat muokkauksesi",
        "rcfilters-filter-editsbyself-description": "Muokkauksesi",
        "apisandbox-sending-request": "API-pyyntöä lähetetään...",
        "apisandbox-loading-results": "API-tuloksia vastaanotetaan...",
        "apisandbox-results-error": "Tapahtui virhe ladattaessa API-kyselyn vastausta: $1",
+       "apisandbox-request-format-url-label": "URL-kyselymerkkijono",
        "apisandbox-request-url-label": "Pyynnön URL",
        "apisandbox-request-time": "Pyyntöön kulunut aika: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Korjaa \"token\" ja lähetä uudelleen",
        "authmanager-realname-label": "Oikea nimi",
        "authmanager-realname-help": "Käyttäjän oikea nimi",
        "authmanager-provider-password": "Salasanapohjainen varmennus",
+       "authmanager-provider-password-domain": "Salasana- ja toimialue-pohjainen todennus",
        "authmanager-provider-temporarypassword": "Väliaikainen salasana",
        "authprovider-confirmlink-message": "Viimeisimpien kirjautumisyritystesi perusteella seuraavat tunnukset voidaan linkittää wikitunnuksellesi. Tunnusten linkittäminen mahdollistaa sisäänkirjautumisen niitä käyttämällä. Valitse tunnukset, jotka tulisi linkittää.",
        "authprovider-confirmlink-request-label": "Tunnukset, jotka tulisi yhdistää",
index 561e0dc..4b0fa74 100644 (file)
                        "Derugon",
                        "Benoit Rochon",
                        "Fitoschido",
-                       "Archaeodontosaurus"
+                       "Archaeodontosaurus",
+                       "Trizek (WMF)"
                ]
        },
        "tog-underline": "Soulignement des liens :",
        "rcfilters-invalid-filter": "Filtre non valide",
        "rcfilters-empty-filter": "Aucun filtre actif. Toutes les contributions sont affichées.",
        "rcfilters-filterlist-title": "Filtres",
+       "rcfilters-filterlist-feedbacklink": "Fournir un commentaire sur les nouveaux filtres (en bêta)",
        "rcfilters-highlightbutton-title": "Mettre en valeur les résultats",
        "rcfilters-highlightmenu-title": "Choisir une couleur",
        "rcfilters-filterlist-noresults": "Aucun filtre trouvé",
        "rcfilters-filtergroup-registration": "Inscription de l’utilisateur",
-       "rcfilters-filter-registered-label": "Enregistré",
+       "rcfilters-filter-registered-label": "Connectés",
        "rcfilters-filter-registered-description": "Éditeurs connectés.",
-       "rcfilters-filter-unregistered-label": "Désinscrit",
+       "rcfilters-filter-unregistered-label": "Non connectés",
        "rcfilters-filter-unregistered-description": "Éditeurs qui ne sont pas connectés.",
        "rcfilters-filtergroup-authorship": "Modifier la paternité",
        "rcfilters-filter-editsbyself-label": "Vos propres modifications",
        "htmlform-user-not-exists": "<strong>$1</strong> n’existe pas.",
        "htmlform-user-not-valid": "<strong>$1</strong> n’est pas un nom d’utilisateur valide.",
        "logentry-delete-delete": "$1 {{GENDER:$2|a supprimé}} la page $3",
-       "logentry-delete-delete_redir": "$1 {{GENDER:$2|supprimé}} redirigé vers $3 par écrasement.",
+       "logentry-delete-delete_redir": "$1 a {{GENDER:$2|supprimé}} la redirection vers $3 par écrasement.",
        "logentry-delete-restore": "$1 {{GENDER:$2|a restauré}} la page $3",
        "logentry-delete-event": "$1 {{GENDER:$2|a modifié}} la visibilité {{PLURAL:$5|d'un événement du journal|de $5 événements du journal}} sur $3: $4",
        "logentry-delete-revision": "$1 {{GENDER:$2|a modifié}} la visibilité {{PLURAL:$5|d'une révision|de $5 révisions}} sur la page $3 : $4",
index 7047334..ee93166 100644 (file)
        "rcfilters-invalid-filter": "Filtro no válido",
        "rcfilters-empty-filter": "Non hai filtros activos. Móstranse tódalas contribucións.",
        "rcfilters-filterlist-title": "Filtros",
+       "rcfilters-filterlist-feedbacklink": "Deixar comentarios sobre os novos filtros (en fase beta)",
        "rcfilters-highlightbutton-title": "Resaltar resultados",
        "rcfilters-highlightmenu-title": "Seleccione unha cor",
        "rcfilters-filterlist-noresults": "Non se atoparon filtros",
        "editcomment": "O resumo de edición foi: <em>$1</em>.",
        "revertpage": "Desfixéronse as edicións de [[Special:Contributions/$2|$2]] ([[User talk:$2|conversa]]); cambiado á última versión feita por [[User:$1|$1]]",
        "revertpage-nouser": "Desfixéronse as edicións dun usuario agochado; cambiado á última versión feita por {{GENDER:$1|[[User:$1|$1]]}}",
-       "rollback-success": "Desfixéronse as edicións de $1;\nvolveuse á última edición, feita por $2.",
+       "rollback-success": "Desfixéronse as edicións de {{GENDER:$3|$1}};\nvolveuse á última edición, feita por {{GENDER:$4|$2}}.",
        "rollback-success-notify": "Revertéronse as edicións de $1;\nrestaurouse a última revisión de $2. [$3 Mostrar os cambios]",
        "sessionfailure-title": "Erro de sesión",
        "sessionfailure": "Parece que hai un problema co rexistro da súa sesión;\nesta acción cancelouse como precaución fronte ao secuestro de sesións.\nPrema no botón \"atrás\", volva cargar a páxina da que proviña e inténteo de novo.",
index 46af76a..bb6c4bc 100644 (file)
        "recentchanges-label-unpatrolled": "اي دچينواچين هلئه گشتزني نۊبؤ",
        "recentchanges-label-plusminus": "ولگˇ حجم اي مقدار بايتˇ واويراز تغيير بؤده",
        "recentchanges-legend-heading": "<strong>اختصارؤن:</strong>",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}}( [[Special:NewPages|تازه ولگؤنˇ ليسته]] بينين)",
        "rclistfrom": "تازه تغييرؤنˇ نۊشؤن دأنˇ سرأگيري $3 $2ˇ جي",
        "rcshowhideminor": "$1 نيميزگره دچينواچينؤن",
        "rcshowhideminor-show": "نۊشؤن دأن",
index edb1b85..93c5007 100644 (file)
        "specialpages-group-changes": "D letschte Änderige un Logbüecher",
        "specialpages-group-media": "Medie",
        "specialpages-group-users": "Benutzer un Rächt",
-       "specialpages-group-highuse": "Syte wo oft bruucht werde",
+       "specialpages-group-highuse": "Syte wo hüüfig bruucht werde",
        "specialpages-group-pages": "Lischte vo Syte",
        "specialpages-group-pagetools": "Sytewerchzüüg",
        "specialpages-group-wiki": "Date un Wärchzyyg",
index 76e652a..27db784 100644 (file)
        "rcfilters-invalid-filter": "מסנן בלתי־תקין",
        "rcfilters-empty-filter": "אין מסננים פעילים. כל התרומות מוצגות.",
        "rcfilters-filterlist-title": "מסננים",
+       "rcfilters-filterlist-feedbacklink": "שליחת משוב על המסננים החדשים (בטא)",
        "rcfilters-highlightbutton-title": "הבלטת התוצאות",
        "rcfilters-highlightmenu-title": "בחירת צבע",
        "rcfilters-filterlist-noresults": "לא נמצאו מסננים",
        "log-action-filter-upload-upload": "העלאות של קבצים חדשים",
        "log-action-filter-upload-overwrite": "דריסות של קבצים קיימים",
        "authmanager-authn-not-in-progress": "האימות נכשל או שנתוני הפעולה נאבדו. נא להתחיל את התהליך מחדש.",
-       "authmanager-authn-no-primary": "×\9c×\90 × ×\99ת×\9f ×\94×\99×\94 ×\9c×\90×\9eת ×\90ת ×\94×\90×\99ש×\95ר×\99×\9d שסופקו.",
-       "authmanager-authn-no-local-user": "×\94×\90×\99ש×\95ר×\99×\9d שסופקו אינם שייכים לשום משתמש באתר זה.",
+       "authmanager-authn-no-primary": "×\9c×\90 × ×\99ת×\9f ×\94×\99×\94 ×\9c×\90×\9eת ×\90ת × ×ª×\95× ×\99 ×\94×\94×\96×\93×\94×\95ת שסופקו.",
+       "authmanager-authn-no-local-user": "נת×\95× ×\99 ×\94×\94×\96×\93×\94×\95ת שסופקו אינם שייכים לשום משתמש באתר זה.",
        "authmanager-authn-no-local-user-link": "נתוני ההאמנה שניתנו תקינים, אבל אינם משויכים לשום משתמש בוויקי הזה. נא להיכנס לחשבון באופן שונה, או ליצור משתמש חדש ואז תהיה לך אפשרות לקשר את נתוני ההאמנה הקודמים שלך לחשבון ההוא.",
        "authmanager-authn-autocreate-failed": "יצירה אוטומטית של חשבון מקומי נכשלה: $1",
        "authmanager-change-not-supported": "לא ניתן לשנות את נתוני ההאמנה שניתנו, כי שום דבר לא ישתמש בהם.",
        "authmanager-create-disabled": "אפשרות יצירת החשבונות מבוטלת.",
        "authmanager-create-from-login": "כדי ליצור את החשבון, יש למלא את השדות.",
        "authmanager-create-not-in-progress": "יצירת החשבון נכשלה או שנתוני הפעולה נאבדו. נא להתחיל את התהליך מחדש.",
-       "authmanager-create-no-primary": "×\94×\90×\99ש×\95ר×\99×\9d שסופקו לא יכולים להיות בשימוש ביצירת חשבון.",
-       "authmanager-link-no-primary": "×\94×\90×\99ש×\95ר×\99×\9d ×©×¡×\95פק×\95 ×\9c×\90 ×\99×\9b×\95×\9c×\99×\9d ×\9c×\94×\99×\95ת ×\91ש×\99×\9e×\95ש ×\91קישור חשבונות.",
+       "authmanager-create-no-primary": "נת×\95× ×\99 ×\94×\94×\96×\93×\94×\95ת שסופקו לא יכולים להיות בשימוש ביצירת חשבון.",
+       "authmanager-link-no-primary": "נת×\95× ×\99 ×\94×\94×\96×\93×\94×\95ת ×©×¡×\95פק×\95 ×\9c×\90 ×\99×\9b×\95×\9c×\99×\9d ×\9c×\94×\99×\95ת ×\91ש×\99×\9e×\95ש ×\9cש×\9d קישור חשבונות.",
        "authmanager-link-not-in-progress": "קישור החשבונות נכשל או שנתוני הפעולה נאבדו. נא להתחיל את התהליך מחדש.",
        "authmanager-authplugin-setpass-failed-title": "שינוי הסיסמה נכשל",
        "authmanager-authplugin-setpass-failed-message": "תוסף האימות דחה את שינוי הסיסמה.",
        "authpage-cannot-link-continue": "לא ניתן להמשיך בתהליך קישור החשבונות. כנראה שזמן ההמתנה של הפעולה חלף.",
        "cannotauth-not-allowed-title": "הגישה נדחתה",
        "cannotauth-not-allowed": "אינך מורשה להשתמש בדף זה",
-       "changecredentials": "ש×\99× ×\95×\99 ×\94×\90×\99ש×\95ר×\99×\9d",
-       "changecredentials-submit": "ש×\99× ×\95×\99 ×\94×\90×\99ש×\95ר×\99×\9d",
+       "changecredentials": "ש×\99× ×\95×\99 × ×ª×\95× ×\99 ×\94×\94×\96×\93×\94×\95ת",
+       "changecredentials-submit": "ש×\99× ×\95×\99 × ×ª×\95× ×\99 ×\94×\94×\96×\93×\94×\95ת",
        "changecredentials-invalidsubpage": "$1 אינו סוג אישור תקין.",
-       "changecredentials-success": "×\94×\90×\99ש×\95ר×\99×\9d שלך שונו.",
-       "removecredentials": "×\94סרת ×\94×\90×\99ש×\95ר×\99×\9d",
-       "removecredentials-submit": "×\94סרת ×\94×\90×\99ש×\95ר×\99×\9d",
+       "changecredentials-success": "נת×\95× ×\99 ×\94×\94×\96×\93×\94×\95ת שלך שונו.",
+       "removecredentials": "×\94סרת × ×ª×\95× ×\99 ×\94×\94×\96×\93×\94×\95ת",
+       "removecredentials-submit": "×\94סרת × ×ª×\95× ×\99 ×\94×\94×\96×\93×\94×\95ת",
        "removecredentials-invalidsubpage": "$1 אינו סוג אישור תקין.",
-       "removecredentials-success": "×\94×\90×\99ש×\95ר×\99×\9d שלך הוסרו.",
-       "credentialsform-provider": "ס×\95×\92 ×\94×\90×\99ש×\95ר×\99×\9d:",
+       "removecredentials-success": "נת×\95× ×\99 ×\94×\94×\96×\93×\94×\95ת שלך הוסרו.",
+       "credentialsform-provider": "ס×\95×\92 × ×ª×\95× ×\99 ×\94×\94×\96×\93×\94×\95ת:",
        "credentialsform-account": "שם החשבון:",
        "cannotlink-no-provider-title": "אין חשבונות שניתן לקשר",
        "cannotlink-no-provider": "אין חשבונות שניתן לקשר.",
index 7512201..bd4f303 100644 (file)
        "youhavenewmessages": "Imate $1 ($2).",
        "youhavenewmessagesfromusers": "Imate $1 {{PLURAL:$3||od $3 suradnika|od $3 suradnika}} ($2).",
        "youhavenewmessagesmanyusers": "Imate $1 od više suradnika ($2).",
-       "newmessageslinkplural": "{{PLURAL:$1|novu poruku|$1 nove poruke|999=novih poruka}}",
+       "newmessageslinkplural": "{{PLURAL:$1|novu poruku|999=nove poruke}}",
        "newmessagesdifflinkplural": "{{PLURAL:$1|posljednje uređivanje|posljednja $1 uređivanja|posljednjih $1 uređivanja}} na stranici za razgovor",
        "youhavenewmessagesmulti": "Imate nove poruke na $1",
        "editsection": "uredi",
        "minoredit": "Ovo je manja promjena",
        "watchthis": "Prati ovu stranicu",
        "savearticle": "Sačuvaj stranicu",
-       "savechanges": "Spremi promjene",
+       "savechanges": "Sačuvaj stranicu",
        "publishpage": "Objavi stranicu",
        "publishchanges": "Objavi izmjene",
        "preview": "Pregled kako će stranica izgledati",
        "recentchanges-label-minor": "Manja izmjena",
        "recentchanges-label-bot": "Izmjenu napravio bot",
        "recentchanges-label-unpatrolled": "Nepregledana izmjena",
-       "recentchanges-label-plusminus": "Promjena veličine stranice (u bajtovima)",
+       "recentchanges-label-plusminus": "Promjena veličine stranice u bajtovima",
        "recentchanges-legend-heading": "<strong>Legenda:</strong>",
        "recentchanges-legend-newpage": "Nova stranica",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "showhideselectedlogentries": "Otkrij/sakrij odabrane evidencije",
        "checkbox-select": "Odaberite: $1",
        "checkbox-all": "Sve",
-       "checkbox-none": "Nijedan",
+       "checkbox-none": "Ništa",
        "checkbox-invert": "Obrnuto",
        "allpages": "Sve stranice",
        "nextpage": "Sljedeća stranica ($1)",
        "lastmodifiedatby": "Ovu je stranicu posljednji put {{GENDER:$4|mijenjao suradnik|mijenjala suradnica}} $3 dana $1 u $2.",
        "othercontribs": "Temelji se na doprinosu suradnika $1.",
        "others": "drugih",
-       "siteusers": "{{SITENAME}} {{PLURAL:$2|suradnik|suradnici}} $1",
+       "siteusers": "{{SITENAME}} {{PLURAL:$2|{{GENDER:$1|suradnik|suradnica}}|suradnici}} $1",
        "anonusers": "{{SITENAME}} {{PLURAL:$2|anonimni suradnik|anonimni suradnici}} $1",
        "creditspage": "Autori stranice",
        "nocredits": "Za ovu stranicu nema podataka o autorima.",
        "logentry-move-move-noredirect": "$1 je {{GENDER:$2|premjestio|premjestila}} stranicu $3 na $4 bez preusmjeravanja",
        "logentry-move-move_redir": "$1 je {{GENDER:$2|premjestio|premjestila}} stranicu $3 na $4 preko preusmjeravanja",
        "logentry-move-move_redir-noredirect": "$1 je {{GENDER:$2|premjestio|premjestila}} stranicu $3 na $4 preko preusmjeravanja bez ostavljanja preusmjeravanja",
-       "logentry-patrol-patrol": "$1 je {{GENDER:$2|označio|označila}} uređivanje $4 stranice $3 pregledanim",
+       "logentry-patrol-patrol": "$1 {{GENDER:$2|označio|označila}} je uređivanje $4 stranice $3 ophođenim",
        "logentry-patrol-patrol-auto": "$1 je automatski {{GENDER:$2|označio|označila}} uređivanje $4 stranice $3 pregledanim",
        "logentry-newusers-newusers": "$1 je {{GENDER:$2|otvorio|otvorila}} suradnički račun",
        "logentry-newusers-create": "$1 je {{GENDER:$2|stvorio|stvorila}} suradnički račun.",
index e5cbf84..1bceb36 100644 (file)
        "searcharticle": "Անցնել",
        "history": "Էջի պատմություն",
        "history_short": "Պատմություն",
-       "updatedmarker": "թարմացվել է իմ վերջին այցից հետո",
+       "updatedmarker": "փոփոխվել է ձեր վերջին այցից հետո",
        "printableversion": "Տպելու տարբերակ",
        "permalink": "Մշտական հղում",
        "print": "Տպել",
        "retypenew": "Հաստատեք նոր գաղտնաբառը.",
        "resetpass_submit": "Հաստատել գաղտնաբառը և մտնել համակարգ",
        "changepassword-success": "Ձեր գաղտնաբառը փոփոխվեց։",
-       "botpasswords": "Ô²Õ¸Õ¿Õ¥Ö\80Õ« Õ®Õ¡Õ®Õ¯Õ¡Õ£Ö\80եր",
-       "botpasswords-disabled": "Ô²Õ¸Õ¿Õ¥Ö\80Õ« Õ®Õ¡Õ®Õ¯Õ¡Õ£Ö\80Õ¥Ö\80Õ¶ անջատված են:",
-       "botpasswords-existing": "Ô³Õ¸ÕµÕ¸Ö\82Õ©ÕµÕ¸Ö\82Õ¶ Õ¸Ö\82Õ¶Õ¥Ö\81Õ¸Õ² Õ¢Õ¸Õ¿Õ¡ÕµÕ«Õ¶ Õ®Õ¡Õ®Õ¯Õ¡Õ£Ö\80Õ¥Ö\80Õ¨",
-       "botpasswords-createnew": "Õ\8dÕ¿Õ¥Õ²Õ®Õ¥Õ¬ Õ¶Õ¸Ö\80 Õ¢Õ¸Õ¿Õ¡ÕµÕ«Õ¶ Õ®Õ¡Õ®Õ¯Õ¡Õ£Õ«Ö\80",
-       "botpasswords-editexisting": "Խմբագրել առկա բոտային ծածկագիրը",
+       "botpasswords": "Ô²Õ¸Õ¿Õ¥Ö\80Õ« Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼եր",
+       "botpasswords-disabled": "Ô²Õ¸Õ¿Õ¥Ö\80Õ« Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼Õ¥Ö\80Õ¨ անջատված են:",
+       "botpasswords-existing": "Ô³Õ¸ÕµÕ¸Ö\82Õ©ÕµÕ¸Ö\82Õ¶ Õ¸Ö\82Õ¶Õ¥Ö\81Õ¸Õ² Õ¢Õ¸Õ¿Õ¥Ö\80Õ« Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼Õ¥Ö\80",
+       "botpasswords-createnew": "Õ\8dÕ¿Õ¥Õ²Õ®Õ¥Õ¬ Õ¶Õ¸Ö\80 Õ¢Õ¸Õ¿Õ« Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼",
+       "botpasswords-editexisting": "Փոխել եղած բոտի գաղտնաբառը",
        "botpasswords-label-appid": "Բոտի անուն՝",
        "botpasswords-label-create": "Ստեղծել",
        "botpasswords-label-update": "Թարմացնել",
        "botpasswords-label-cancel": "Չեղարկել",
        "botpasswords-label-delete": "Ջնջել",
-       "botpasswords-label-resetpassword": "Õ\8eÕ¥Ö\80Õ¡Õ¯Õ¡Õ¶Õ£Õ¶Õ¥Õ¬ Õ®Õ¡Õ®Õ¯Õ¡Õ£Õ«Ö\80ը",
+       "botpasswords-label-resetpassword": "Õ\8eÕ¥Ö\80Õ¡Õ¯Õ¡Õ¶Õ£Õ¶Õ¥Õ¬ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼ը",
        "botpasswords-label-grants-column": "Թույլատրված է",
        "botpasswords-bad-appid": "\"$1\" բոտի անունն անթույլատրելի է:",
        "botpasswords-created-title": "Բոտի ծածկագիրը ստեղծվել է",
        "botpasswords-created-body": "$2 մասնակցի $1 բոտի համար բոտի ծածկագիրը ստեղծվել է:",
-       "botpasswords-updated-title": "Ô²Õ¸Õ¿Õ« Õ®Õ¡Õ®Õ¯Õ¡Õ£Õ«Ö\80ը թարմացվել է",
-       "botpasswords-updated-body": "$2 Õ´Õ¡Õ½Õ¶Õ¡Õ¯Ö\81Õ« $1 Õ¢Õ¸Õ¿Õ« Õ°Õ¡Õ´Õ¡Ö\80 Õ¢Õ¸Õ¿Õ« Õ®Õ¡Õ®Õ¯Õ¡Õ£Õ«Ö\80Õ¨ Õ½Õ¿Õ¥Õ²Õ®Õ¾Õ¥Õ¬ Õ§:",
-       "botpasswords-deleted-title": "Ô²Õ¸Õ¿Õ« Õ®Õ¡Õ®Õ¯Õ¡Õ£Õ«Ö\80Õ¨ Õ»Õ¶Õ»Õ¾Õ¡Õ® Õ§",
+       "botpasswords-updated-title": "Ô²Õ¸Õ¿Õ« Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼ը թարմացվել է",
+       "botpasswords-updated-body": "$2 Õ´Õ¡Õ½Õ¶Õ¡Õ¯Ö\81Õ« $1 Õ¢Õ¸Õ¿Õ« Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼Õ¨ Ö\83Õ¸Ö\83Õ¸Õ­Õ¾Õ¥Ö\81:",
+       "botpasswords-deleted-title": "Ô²Õ¸Õ¿Õ« Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼Õ¨ Õ»Õ¶Õ»Õ¾Õ¥Ö\81",
        "botpasswords-deleted-body": "$2 մասնակցի $1 բոտի համար բոտի ծածկագիրը ջնջվել է:",
        "resetpass_forbidden": "Գաղտնաբառը չի կարող փոխվել",
        "resetpass-no-info": "Այս էջին ուղիղ դիմելու համար անհրաժեշտ է մտնել համակարգ։",
index 412a133..c8c6fa0 100644 (file)
        "selfredirect": "<strong>Peringatan:</strong> Anda mengalihkan halaman ini kembali ke halaman semula.\nAnda bisa jadi telah memberikan tujuan pengalihan yang salah, atau telah menyunting halaman yang salah.\nJika Anda mengeklik \"{{int:savearticle}}\" sekali lagi, halaman pengalihan akan dibuat.",
        "missingcommenttext": "Harap masukkan komentar di bawah ini.",
        "missingcommentheader": "'''Peringatan:''' Anda belum memberikan subjek atau judul untuk komentar Anda. Jika Anda kembali menekan \"{{int:savearticle}}\", suntingan Anda akan disimpan tanpa komentar tersebut.",
-       "summary-preview": "Pratayang ringkasan:",
+       "summary-preview": "Pratayang ringkasan suntingan:",
        "subject-preview": "Pratayang subjek:",
        "previewerrortext": "Kesalahan terjadi saat mencoba memperlihatkan pratayang perubahan Anda.",
        "blockedtitle": "Pengguna diblokir",
        "search-interwiki-caption": "Proyek lain",
        "search-interwiki-default": "Hasil dari $1:",
        "search-interwiki-more": "(selanjutnya)",
+       "search-interwiki-more-results": "Hasil lainnya",
        "search-relatedarticle": "Berkaitan",
        "searchrelated": "berkaitan",
        "searchall": "semua",
        "editusergroup": "Muat kelompok pengguna",
        "editinguser": "Mengubah hak pengguna untuk {{GENDER:$1|pengguna}} <strong>[[User:$1|$1]]</strong> $2",
        "viewinguserrights": "Melihat hak pengguna dari {{GENDER:$1|pengguna}} <strong>[[User:$1|$1]]</strong> $2",
-       "userrights-editusergroup": "Sunting kelompok pengguna",
-       "userrights-viewusergroup": "Lihat kelompok pengguna",
+       "userrights-editusergroup": "Sunting kelompok {{GENDER:$1|pengguna}}",
+       "userrights-viewusergroup": "Lihat kelompok {{GENDER:$1|pengguna}}",
        "saveusergroups": "Simpan kelompok {{GENDER:$1|pengguna}}",
        "userrights-groupsmember": "Anggota dari:",
        "userrights-groupsmember-auto": "Anggota implisit dari:",
        "userrights-changeable-col": "Kelompok yang dapat Anda ubah",
        "userrights-unchangeable-col": "Kelompok yang tidak dapat Anda ubah",
        "userrights-irreversible-marker": "$1*",
+       "userrights-expiry-current": "Udang $1",
+       "userrights-expiry-none": "Tidak usang",
+       "userrights-expiry": "Usang:",
        "userrights-expiry-othertime": "Waktu lain:",
        "userrights-conflict": "Konflik perubahan hak pengguna! Silakan tinjau ulang dan konfirmasi perubahan Anda.",
        "group": "Kelompok:",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (lihat pula [[Special:NewPages|daftar halaman baru]])",
        "recentchanges-submit": "Tampilkan",
        "rcfilters-activefilters": "Filter aktif",
+       "rcfilters-restore-default-filters": "Kembalikan filter bawaan",
+       "rcfilters-clear-all-filters": "Hapus semua penyaringan",
+       "rcfilters-search-placeholder": "Filter perubahan terbaru (jelajahi atau masukan input)",
+       "rcfilters-invalid-filter": "Penyqringan tidak sah",
+       "rcfilters-empty-filter": "Tidak ada filter aktif. Semua kontribusi ditampilkan.",
+       "rcfilters-filterlist-title": "Penyaringan",
+       "rcfilters-filterlist-feedbacklink": "Berikan umpan balik untuk filter uji coba baru",
+       "rcfilters-highlightmenu-title": "Pilih warna",
+       "rcfilters-filterlist-noresults": "Tidak ada penyaring ditemukan",
+       "rcfilters-filtergroup-registration": "Pendaftaran pengguna",
        "rcfilters-filter-registered-label": "Terdaftar",
+       "rcfilters-filter-registered-description": "Penyunting masuk log",
        "rcfilters-filter-unregistered-label": "Tidak terdaftar",
+       "rcfilters-filter-unregistered-description": "Penyunting yang tidak masuk log",
+       "rcfilters-filter-editsbyself-label": "Suntingan Anda",
+       "rcfilters-filter-editsbyself-description": "Suntingan oleh Anda",
+       "rcfilters-filter-editsbyother-label": "Suntingan orang lain",
+       "rcfilters-filter-editsbyother-description": "Suntingan dibuat oleh orang lain (bukan Anda)",
        "rcfilters-filter-userExpLevel-newcomer-label": "Pendatang baru",
+       "rcfilters-filter-userExpLevel-newcomer-description": "Kurang dari 10 suntingan dan aktivitas selama 4 hari.",
+       "rcfilters-filter-userExpLevel-learner-label": "Pelajar",
+       "rcfilters-filter-userExpLevel-experienced-label": "Pengguna berpengalaman",
+       "rcfilters-filtergroup-automated": "Kontribusi otomatis",
        "rcfilters-filter-bots-label": "Bot",
+       "rcfilters-filter-bots-description": "Suntingan yang dibuat dengan perkakas terotomatisasi.",
+       "rcfilters-filter-humans-label": "Manusia (bukan bot)",
+       "rcfilters-filter-humans-description": "Suntingan yang dibuat oleh penyunting manusia.",
+       "rcfilters-filtergroup-significance": "Kepentingan",
        "rcfilters-filter-minor-label": "Suntingan kecil",
+       "rcfilters-filter-minor-description": "Suntingan yang ditandai penyunting sebagai suntingan kecil",
+       "rcfilters-filter-major-label": "Suntingan yang bukan suntingan kecil",
+       "rcfilters-filter-major-description": "Suntingan yang ditandai sebagai suntingan kecil",
+       "rcfilters-filtergroup-changetype": "Jenis perubahan",
+       "rcfilters-filter-pageedits-label": "Suntingan halaman",
+       "rcfilters-filter-pageedits-description": "Suntingan pada konten wiki, diskusi, deskripsi kategori....",
+       "rcfilters-filter-newpages-label": "Pembuatan halaman",
+       "rcfilters-filter-newpages-description": "Suntingan yang membuat halaman baru",
        "rcfilters-filter-categorization-label": "Perubahan kategori",
+       "rcfilters-filter-categorization-description": "Rekam jejak halaman yang telah ditambahkan atau dihapus dari kategori.",
+       "rcfilters-filter-logactions-label": "Tindakan tercatat",
+       "rcfilters-filter-logactions-description": "Tindakan administratif, pembuatan akun, penghapusan halaman, pengunggahan....",
        "rcnotefrom": "Di bawah ini adalah {{PLURAL:$5|perubahan}} sejak <strong>$3, $4</strong> (ditampilkan sampai <strong>$1</strong> perubahan).",
        "rclistfrom": "Perlihatkan perubahan terbaru sejak $3 $2",
        "rcshowhideminor": "$1 suntingan kecil",
        "apisandbox-sending-request": "Mengirim permintaan API...",
        "apisandbox-loading-results": "Menerima hasil API...",
        "apisandbox-results-error": "Sebuah galat terjadi ketika memuat permintaan respon API: $1.",
+       "apisandbox-request-selectformat-label": "Tampilkan permintaan data sebagai:",
        "apisandbox-request-url-label": "URL Permintaan:",
+       "apisandbox-request-json-label": "Meminta JSON:",
        "apisandbox-request-time": "Lama permintaan: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Perbaiki token dan kirim kembali",
        "apisandbox-results-fixtoken-fail": "Gagal mendapatkan token \"$1\".",
        "apisandbox-alert-field": "Nilai dalam kolom ini tidak valid.",
        "apisandbox-continue": "Lanjutkan",
        "apisandbox-continue-clear": "Kosongkan",
+       "apisandbox-param-limit": "Masukan <kbd>max</kbd> untuk menggunakan batas maksimum.",
+       "apisandbox-multivalue-all-namespaces": "$1 (Semua ruang nama)",
+       "apisandbox-multivalue-all-values": "$1 (Semua nilai)",
        "booksources": "Sumber buku",
        "booksources-search-legend": "Cari di sumber buku",
        "booksources-isbn": "ISBN:",
        "booksources-search": "Cari",
        "booksources-text": "Di bawah ini adalah daftar pranala ke situs lain yang menjual buku baru dan bekas, dan mungkin juga mempunyai informasi lebih lanjut mengenai buku yang sedang Anda cari:",
        "booksources-invalid-isbn": "ISBN yang diberikan tampaknya tidak valid; periksa kesalahan penyalinan dari sumber asli.",
+       "magiclink-tracking-rfc": "Halaman menggunakan pranala magis RFC",
+       "magiclink-tracking-pmid": "Halaman menggunakan pranala magis PMID",
+       "magiclink-tracking-isbn": "Halaman yang menggunakan pranala magis ISBN",
        "specialloguserlabel": "Pengguna:",
        "speciallogtitlelabel": "Target (judul atau{{ns:pengguna}}:nama pengguna untuk pengguna)",
        "log": "Catatan (Log)",
        "activeusers-intro": "Berikut adalah daftar pengguna yang memiliki suatu bentuk aktivitas selama paling tidak $1 {{PLURAL:$1|hari|hari}} terakhir.",
        "activeusers-count": "$1 {{PLURAL:$1|aktivitas|aktivitas}} dalam {{PLURAL:$3|1 hari|$3 hari}} terakhir",
        "activeusers-from": "Tampilkan pengguna mulai dari:",
+       "activeusers-groups": "Tampilkan pengguna yang termasuk kelompok:",
+       "activeusers-excludegroups": "Sembunyikan pengguna yang termasuk kelompok:",
        "activeusers-noresult": "Pengguna tidak ditemukan.",
        "activeusers-submit": "Tampilkan pengguna aktif",
        "listgrouprights": "Daftar hak kelompok",
        "rollbacklinkcount-morethan": "kembalikan lebih dari $1 {{PLURAL:$1|suntingan|suntingan}}",
        "rollbackfailed": "Pengembalian gagal dilakukan",
        "rollback-missingparam": "Parameter dibutuhkan ketika diminta tidak tersedia.",
+       "rollback-missingrevision": "Tidak mampu memuat data revisi.",
        "cantrollback": "Tidak dapat membatalkan suntingan;\nkontributor terakhir adalah satu-satunya penulis halaman ini.",
        "alreadyrolled": "Tidak dapat melakukan pengembalian ke revisi terakhir [[:$1]] oleh [[User:$2|$2]] ([[User talk:$2|bicara]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);\npengguna lain telah menyunting atau melakukan pengembalian terhadap halaman ini.\n\nSuntingan terakhir dilakukan oleh [[User:$3|$3]] ([[User talk:$3|bicara]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Komentar penyuntingan adalah: <em>$1</em>.",
        "revertpage": "←Suntingan [[Special:Contributions/$2|$2]] ([[User talk:$2|bicara]]) dibatalkan ke versi terakhir oleh [[User:$1|$1]]",
        "revertpage-nouser": "Mengembalikan suntingan oleh (nama pengguna dihapus) ke suntingan terakhir oleh [[User:$1|$1]]",
-       "rollback-success": "Pembatalan suntingan oleh $1; dibatalkan ke versi terakhir oleh $2.",
+       "rollback-success": "Pembatalan suntingan oleh {{GENDER:$3|$1}}; dibatalkan ke versi terakhir oleh {{GENDER:$4|$2}}.",
        "rollback-success-notify": "Mengembalikan suntingan oleh $1; rubah kembali untuk revisi terakhir oleh $2. [$3 Lihat perubahan]",
        "sessionfailure-title": "Kegagalan sesi",
        "sessionfailure": "Sepertinya ada masalah dengan sesi log Anda; log Anda telah dibatalkan untuk mencegah pembajakan. Silakan tekan tombol \"kembali\" dan muat kembali halaman sebelum Anda masuk, lalu coba lagi.",
        "sorbs": "DNSBL",
        "sorbsreason": "Alamat IP anda terdaftar sebagai proxy terbuka di DNSBL.",
        "sorbs_create_account_reason": "Alamat IP anda terdaftar sebagai proxy terbuka di DNSBL. Anda tidak dapat membuat akun.",
+       "softblockrangesreason": "Kontribusi anonim tidak diizinkan dari alamat IP Anda ($1). Silakan masuk log.",
        "xffblockreason": "Sebuah alamat IP terdapat di kepala X-Forwarded-For, entah milik Anda atau peladen ''proxy'' yang Anda gunakan, telah diblokir. Alasan pemblokirannya adalah: $1",
        "cant-see-hidden-user": "Pengguna yang Anda coba blokir telah diblokir dan disembunyikan. Selama Anda tidak memiliki hak sembunyikan pengguna, Anda tidak dapat melihat atau menyunting pemblokiran pengguna ini.",
        "ipbblocked": "Anda tidak dapat memblokir atau membuka blokir pengguna lain, karena Anda sendiri diblokir.",
        "cant-move-to-user-page": "Anda tidak memiliki hak akses untuk memindahkan halaman ke suatu halaman pengguna (kecuali ke subhalaman pengguna).",
        "cant-move-category-page": "Anda tidak memiliki izin untuk memindahkan halaman kategori.",
        "cant-move-to-category-page": "Anda tidak memiliki izin untuk memindahkan halaman ke halaman kategori.",
+       "cant-move-subpages": "Anda tidak memiliki izin untuk memindahkan subhalaman",
+       "namespace-nosubpages": "Ruang nama \"$1\" tidak mengizinkan subhalaman.",
        "newtitle": "Judul baru:",
        "move-watch": "Pantau halaman ini",
        "movepagebtn": "Pindahkan halaman",
        "newimages-showbots": "Tampilkan unggahan oleh bot",
        "newimages-hidepatrolled": "Sembunyikan unggahan yang telah dipatroli",
        "noimages": "Tidak ada yang dilihat.",
+       "gallery-slideshow-toggle": "Beralih  ''thumbnails''",
        "ilsubmit": "Cari",
        "bydate": "berdasarkan tanggal",
        "sp-newimages-showfrom": "Tampilkan berkas baru dimulai dari $2, $1",
        "tag-filter": "Filter [[Special:Tags|tag]]:",
        "tag-filter-submit": "Penyaring",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag}}]]: $2)",
+       "tag-mw-contentmodelchange": "Perubahan model konten",
+       "tag-mw-contentmodelchange-description": "Perubahan yang [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel mengubah model konten] suatu halaman",
        "tags-title": "Tanda",
        "tags-intro": "Halaman ini berisi daftar tag yang dapat ditandai oleh perangkat lunak terhadap suatu suntingan berikut artinya.",
        "tags-tag": "Nama tag",
        "tags-apply-not-allowed-multi": "{{PLURAL:$2|Tag|Tag}} berikut tidak diizinkan untuk diterapkan secara manual: $1",
        "tags-update-no-permission": "Anda tidak memiliki izin untuk menambah atau menghapus perubahan tag dari revisi atau entri log individu.",
        "tags-update-blocked": "Anda tidak dapat menambahkan atau menghapus perubahan tag ketika {{GENDER:$1|Anda}} sedang diblokir.",
+       "tags-update-add-not-allowed-one": "Tag \"$1\"tidak diizinkan untuk ditambahkan secara manual.",
+       "tags-update-add-not-allowed-multi": "{{PLURAL:$2|tag is|Tag ini}} tidak diizinkan untuk ditambahkan secara manual: $1",
+       "tags-update-remove-not-allowed-one": "Tag \"$1\" tidak diizinkan untuk dihapus.",
        "tags-edit-title": "Sunting tag",
        "tags-edit-manage-link": "Kelola tag",
        "tags-edit-revision-selected": "{{PLURAL:$1|Revisi terpilih|Revisi terpilih}} dari [[:$2]]:",
        "htmlform-time-placeholder": "JJ:MM:DD",
        "htmlform-datetime-placeholder": "TTTT-BB-HH JJ:MM:DD",
        "htmlform-date-invalid": "Nilai yang diberikan tidak dikenali sebagai tanggal. Coba lagi menggunakan format TTTT-BB-HH.",
+       "htmlform-time-invalid": "Nilai yang Anda tentukan bukan waktu yang dikenali. Cobalah menggunakan format HH:MM:SS",
        "htmlform-datetime-invalid": "Nilai yang Anda masukkan tidak dikenali sebagai tanggal dan waktu. Coba gunakan format YYYY-MM-DD HH:MM:SS",
        "htmlform-date-toolow": "Nilai yang Anda masukkan adalah sebelum tanggal paling dini yang dibolehkan $1",
        "htmlform-date-toohigh": "Nilai yang Anda masukkan adalah setelah tanggal paling akhir  yang dibolehkan $1",
        "htmlform-time-toolow": "Nilai yang Anda tentukan adalah sebelum waktu paling dini yang dibolehkan $1",
        "htmlform-time-toohigh": "Nilai yang Anda tentukan adalah setelah waktu paling baru yang dibolehkan $1",
+       "htmlform-datetime-toolow": "Nilai yang Anda tentukan berada sebelum tanggal dan waktu paling awal yang diperbolehkan $1",
+       "htmlform-datetime-toohigh": "Nilai yang Anda masukan telah terlewati setelah tanggal dan waktu terakhir yang diperbolehkan $1.",
        "htmlform-title-badnamespace": "[[:$1]] tidak berada dalam ruang nama \"{{ns:$2}}\".",
        "htmlform-title-not-creatable": "\"$1\" bukan merupakan judul halaman yang dapat dibuat",
        "htmlform-title-not-exists": "$1 tidak ada.",
        "logentry-tag-update-logentry": "$1 {{GENDER:$2|memperbarui}} tag pada entri log $5 dari halaman $3 ({{PLURAL:$7|menambahkan}} $6; {{PLURAL:$9|menghapus}} $8)",
        "rightsnone": "(tidak ada)",
        "revdelete-summary": "ringkasan",
+       "rightslogentry-temporary-group": "$1 (sementara, hingga $2)",
        "feedback-adding": "Menambahkan umpan balik ke halaman...",
        "feedback-back": "Kembali",
        "feedback-bugcheck": "Hebat! Hanya periksa bahwa itu bukan satu di antara [$1 bug yang telah dikenal].",
        "pagelang-language": "Bahasa",
        "pagelang-use-default": "Gunakan bahasa baku",
        "pagelang-select-lang": "Pilih bahasa",
+       "pagelang-reason": "Alasan",
        "pagelang-submit": "Kirim",
+       "pagelang-nonexistent-page": "Halaman $1 tidak tersedia",
+       "pagelang-unchanged-language": "Halaman $1 telah di atur ke bahasa $2",
+       "pagelang-unchanged-language-default": "Halaman $1 Telah diatur ke bahasa konten bawaan.",
+       "pagelang-db-failed": "Basis data gagal mengubah bahasa halaman",
        "right-pagelang": "Ubah bahasa halaman",
        "action-pagelang": "mengubah bahasa halaman",
        "log-name-pagelang": "Log perubahan bahasa",
        "mw-widgets-titleinput-description-new-page": "halaman belum ada",
        "mw-widgets-titleinput-description-redirect": "mengalihkan ke $1",
        "mw-widgets-categoryselector-add-category-placeholder": "Tambah sebuah kategori...",
+       "mw-widgets-usersmultiselect-placeholder": "Tambahkan lebih banyak...",
        "sessionmanager-tie": "Tidak dapat menggabungkan banyak jenis otentikasi permintaan: $1.",
        "sessionprovider-generic": "sesi $1",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sesi berdasarkan kuki",
        "sessionprovider-nocookies": "Kuki mungkin dimatikan. Pastikan Anda telah mengaktifkan kuki dan coba mulai kembali.",
        "randomrootpage": "Halaman dasar sembarang",
        "log-action-filter-block": "Jenis pemblokiran:",
-       "log-action-filter-contentmodel": "Jenis modifikasi modelkonten:",
+       "log-action-filter-contentmodel": "Jenis perubahan modelkonten:",
        "log-action-filter-delete": "Jenis penghapusan:",
        "log-action-filter-import": "Jenis impor:",
        "log-action-filter-managetags": "Jenis tindakan manajemen tag:",
        "authmanager-link-no-primary": "Kredensial yang diberikan tidak dapat digunakan untuk menautkan akun.",
        "authmanager-link-not-in-progress": "Penautan akun tidak dilanjutkan atau data sesi telah hilang. Ulang kembali dari awal.",
        "authmanager-authplugin-setpass-failed-title": "Penggantian kata sandi gagal",
+       "authmanager-authplugin-setpass-failed-message": "Plugin autentikasi mencegah pengubahan pasword.",
+       "authmanager-authplugin-create-fail": "Plugin autentikasi mencegah pembuatan akun.",
+       "authmanager-authplugin-setpass-denied": "Plugin autentikasi tidak memperbolehkan mengubah kata kunci.",
        "authmanager-authplugin-setpass-bad-domain": "Domain tidak sah.",
        "authmanager-autocreate-noperm": "Pembuatan akun otomatis tidak diizinkan.",
        "authmanager-autocreate-exception": "Pembuatan akun otomatis dimatikan sementara karena galat sebelumnya.",
index 6990ca0..7c5bc69 100644 (file)
@@ -38,7 +38,7 @@
        "tog-enotifminoredits": "ОагIонашта а файлашта даь хувцамаш геттара зIамига дале а хоам бе сога",
        "tog-enotifrevealaddr": "ДIахайта хоамбараш чу бIаргадейта са почта адрес",
        "tog-shownumberswatching": "Шоаш зем бу оагIонашта юкъе ер оагIув чуяьккха доакьошхоша таьрахь гойта",
-       "tog-oldsig": "ХIанзара яздаь кулг:",
+       "tog-oldsig": "Хьа карара кулг яздар:",
        "tog-fancysig": "Кулг яздара ший йола вики-разметка (автоматически тIахьожаярг йоацаш)",
        "tog-uselivepreview": "Пайда эца сиха дола хьалххе бIаргтохар",
        "tog-forceeditsummary": "ДIахьалхадаккха, нагахьа санна хувцама йоазонца сурт оттадара моттиг хьалъйизанза яле",
        "category-file-count-limited": "Укх категори чу {{PLURAL:$1|$1 файл|$1 файлаш|1=цаI мара файл яц}}.",
        "listingcontinuesabbrev": "(дIахо)",
        "index-category": "Индекс оттаеш оагIонаш",
-       "noindex-category": "Индекс ца оттаеш оагIонаш",
+       "noindex-category": "Индекс оттайинза оагIонаш",
        "broken-file-category": "Файла тIахьожаяргаш болхбеш йоаца оагIонаш",
        "about": "Сурт оттадар",
        "article": "Статья",
        "newwindow": "&nbsp;(керда кора чу)",
        "cancel": "Юхадаккха",
        "moredotdotdot": "ДIахо...",
-       "morenotlisted": "Ð\95Ñ\80 Ñ\81пиÑ\81ок Ñ\85Ñ\8cалйиза Ñ\8fÑ\86.",
+       "morenotlisted": "Ð\95Ñ\80 Ñ\85Ñ\8cаÑ\8fзÑ\8fÑ\8cÑ\80 Ñ\85Ñ\8cалйизанза Ñ\85ила Ð¼ÐµÐ³Ð°Ñ\88 Ñ\8f.",
        "mypage": "ОагIув",
        "mytalk": "Дувца оттадар",
        "anontalk": "Дувца оттадар",
        "showpreview": "Хьалххе бIаргтохар",
        "showdiff": "Даь дола хувцамаш",
        "anoneditwarning": "<strong>Теркам бе!</strong> Хьо автор хинна система чуваьннавац. Нагахьа санна Iа моллагIа хувцам бой, Хьа IP-адрес дийла массанен бIаргагуш хургда. Нагахьа санна Хьо <strong>[$1 хьачувоале]</strong> е <strong>[$2 дагара йоазув хьакхолле]</strong>, нийсдараш (хувцамаш) бувзам болаш хургда Хьа доакъашхой цIерца, иштта кхыдола толажагIи гIойленагIи дола дикаьш хургда Хьона.",
-       "summary-preview": "СÑ\83Ñ\80Ñ\82 Ð¾Ñ\82Ñ\82адаÑ\80 Ñ\85Ñ\83Ñ\80гда:",
-       "subject-preview": "Ð\94аÑ\8cкÑ\8aа Ñ\86Iи Ñ\85Ñ\83Ñ\80гÑ\8cÑ\8f Ð¸Ñ\88Ñ\82Ñ\82а:",
+       "summary-preview": "Ð¥Ñ\83вÑ\86ама Ñ\81Ñ\83Ñ\80Ñ\82 Ð¾Ñ\82Ñ\82адаÑ\80а Ñ\85Ñ\8cалÑ\85е Ð±IаÑ\80гÑ\82оÑ\85аÑ\80:",
+       "subject-preview": "Теман/коÑ\80Ñ\82баÑ\80а Ñ\85Ñ\8cалÑ\85Ñ\85е Ð±IаÑ\80гÑ\82оÑ\85аÑ\80:",
        "blockedtitle": "Доакъашхочун чIега техаб",
        "blockednoreason": "бахьан белгалдаьккха дац",
        "loginreqlink": "довзийта",
        "notextmatches": "ОагIонай тексташта юкъе цхьатара хилар дац",
        "prevn": "{{PLURAL:$1|1=хьалхайогIар|хьалхайогIараш}} $1",
        "nextn": "{{PLURAL:$1|1=тIехьайоагIар|тIехьайоагIараш}} $1",
-       "prevn-title": "{{PLURAL:$1|1=$1 хьалхара йоазув|$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а",
        "viewprevnext": "ДIахьажа ($1 {{int:pipe-separator}} $2) ($3)",
-       "searchmenu-exists": "'''Укх вики чу йолаш я оагӀув «[[:$1]]»'''",
+       "searchmenu-exists": "'''Укх вики чу я иштта йола оагӀув «[[:$1]]»'''",
        "searchmenu-new": "<strong>Хьакхолла оагIув «[[:$1]]» укх вики-проекте!</strong>\n{{PLURAL:$2|0=|Иштта хьажа Iайха лийха оагIонга.|Иштта хьажа хьай лахара хьахиннарашка.}}",
        "searchprofile-articles": "Кертера оагIонаш",
        "searchprofile-images": "Мультимедиа",
        "searchprofile-everything-tooltip": "Массайола оагIонаш тIа лахар (дувцар оттадара оагIонаш чулоацаш)",
        "searchprofile-advanced-tooltip": "Iочуязаяь цIерий аренашка лаха",
        "search-result-size": "$1 ({{PLURAL:$2|$2 дош|$2 дешаш}})",
-       "search-result-category-size": "{{PLURAL:$1|1=$1 дакъа|$1 дакъаш}} ({{PLURAL:$2|1=$2 кIалцатег|$2 кIалцатегаш}}, {{PLURAL:$3|1=$3 паьла|$3 паьлий}})",
+       "search-result-category-size": "$1 {{PLURAL:$1|юкъедахар}} ($2 {{PLURAL:$2|кIалкатегори}}, $3 {{PLURAL:$3|файл}})",
        "search-redirect": "(дIа-хьахьожадар $1 тIара)",
        "search-section": "(дáкъа «$1»)",
        "search-suggest": "Хьона эшар ер хила мега: $1",
        "prefs-signature": "Кулг яздар",
        "prefs-preview": "Хьалххе бIаргтохар",
        "userrights-user-editname": "Iочуязъе доакъашхочун цӀи:",
-       "editusergroup": "Ð¥Ñ\83вÑ\86а {{GENDER:$1|доакÑ\8aаÑ\88Ñ\85оÑ\87Ñ\83н}} тоабаш",
+       "editusergroup": "Ð\99оÑ\82Ñ\82а Ð´Ð¾Ð°ÐºÑ\8aаÑ\88Ñ\85ой тоабаш",
        "saveusergroups": "ДIаязъе {{GENDER:$1|доакъашхочун}} тоабаш",
        "userrights-groupsmember": "Дакъа лоаца тоабаш чу:",
        "userrights-reason": "Бахьан:",
        "recentchanges-label-plusminus": "байташкахь боарам хувцар",
        "recentchanges-legend-heading": "<strong>Легенда:&nbsp;</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (хьажа иштта [[Special:NewPages|керда оагIонашка]])",
-       "rcnotefrom": "КIалхагIа хувцамаш хьахьекха я <strong>$2</strong> денза (<strong>$1</strong> кхачалца).",
+       "rcnotefrom": "КIалхагIа {{PLURAL:$5|хувцам белгалбаьккхаб}} <strong>$3, $4</strong> тIера (хьахьекхабац <strong>$1</strong>-л дукхагIа).",
        "rclistfrom": "$3 $2 денза даь хувцамаш хьахьокха",
        "rcshowhideminor": "$1 зIамига нийсдараш",
        "rcshowhideminor-show": "Хьахьокха",
        "newpages": "Керда оагIонаш",
        "move": "ЦIи хувца",
        "movethispage": "ЦIи хувца укх оагIон",
-       "pager-newer-n": "{{PLURAL:$1|кердагIа дара|кердагIа дараш|кердагIа долачаьрахь}} $1",
+       "pager-newer-n": "$1 дукхагIа {{PLURAL:$1|керда}}",
        "pager-older-n": "{{PLURAL:$1|къаьнара дара|къаьнара дараш|къаьнара долaчарех}} $1",
        "booksources": "Джейнай хьасташ (источники)",
        "booksources-search-legend": "Джейнах лаьца хоам лахар",
        "protect_expiry_old": "Чакхадалара ха — дахáр да.",
        "protect-text": "Хьа йиш я оагIон '''$1''' лорадара лагIа бIаргтоха a, хувца a .",
        "protect-locked-access": "Хьа дагара йоазонга тоъал бокъо яц оагIон лорадара лагIа хувца. '''$1''' оагIон карара оттадараш:",
-       "protect-cascadeon": "{{PLURAL:$1|1=КIалхахь хьагойташ йола оагIувчу|КIалхахь хьагойташ йола оагIувнашчу}} ер оагIув чуяккха халарахь, лорам Iоттая я, хурхала лорам Iоттая я. Укх оагIувни лорама лагIа хувца йийш йолаш я, амма хурхала лорам хувцлургдац.",
+       "protect-cascadeon": "Каскадни лорадар оттадаь йолча {{PLURAL:$1|1=кIалхагIа белгалъяь оагIон чу|кIалхагIа белгалъяь оагIонаш чу}} юкъеяьккха хилара бахьане ер оагIув хIанза лораяь я. Укх оагIон лорадара дарж хувцаро каскадни лорадар меттахдоаккхадац.",
        "protect-default": "Лорадар доацаш",
        "protect-fallback": "Могадаьд алхха ше «$1» волача доакъашхошта",
        "protect-level-autoconfirmed": "Могадаьд алхха ше-ше къоабалбаь хинна доакъашхошта",
        "unblocklogentry": "чIега баьстаб $1",
        "block-log-flags-nocreate": "дагара йоазонаш кхоллар пурам деннадац",
        "move-page-legend": "ОагIон цIи хувцар",
-       "movepagetext": "КIалхара кепаца болхабеча, оаш оагIувни цIи хувцаргья, цунна хувцамий тептар кхыйола меттиге дIачудоаккхаш.\nКIаьнара цIерахь керда цIерий дIачудаккхам хургда.\nКIаьнара цIера тIа даь дола дIачудаккхамаш, шун ший лоIамахь кердадаккха йийш хургья.\nИз оаш ца дой, дехар да, [[Special:DoubleRedirects|шолха]] кхы [[Special:BrokenRedirects|вIашагIаяккха дIачудаккхамий]] кардоламахь хьажа.\nОаш жоп лу, шоай чуяккха йола Iинкаш, даим болхбеш хургдолга.\n\nЗем бахка, оагIувни цIи хувцалургьяц, изза мо цIи йолаш оагIув хилача. \nЙолаш йола оагIув хувца йийш яц, амма хийца йола оагIув юха хьахувца йийш я. \n\n'''Хоамхайтар'''\n\nЦIи хувцар, йовзаш йола оагIувнаший, доккха а цаьхха а хувцамшка дIатIадала мегаш да.\nДехар да, оаш дIахо болх белаьхь, хургдола хIама кхеташ долга, кхеталаш.",
-       "movepagetalktext": "ТIаÑ\82еÑ\85а Ð´Ñ\83вÑ\86ама Ð¾Ð°Ð³IÑ\83в, Ñ\88ий Ð»Ð¾IамаÑ\85Ñ\8c Ñ\86Iи Ñ\85Ñ\83влÑ\83Ñ\80гÑ\8cÑ\8f, '''еÑ\80 Ð´Ð°Ð³Ð° Ð° Ð´Ð¾Ð°Ñ\86аÑ\80, Ð´Ð¾Ð°Ñ\86а:'''\n\n*Ð\98зза Ð¼Ð¾ Ñ\86Iи Ð¹Ð¾Ð»Ð°Ñ\88 Ñ\8fÑ\8cÑ\81Ñ\81а Ð´Ñ\83вÑ\86ама Ð¾Ð°Ð³IÑ\83в Ñ\8f Ðµ\n*Ð\9eаÑ\88 ÐºIалÑ\85аÑ\85Ñ\8c Ð±ÐµÐ»Ð³Ð°Ð»Ð¾ Ð´Ð°Ñ\8cдаÑ\86.\n\nÐ\98з Ð¸Ñ\88Ñ\82Ñ\82а Ð´Ð°Ð»Ðµ, ÐºÑ\83лги Ð½Ð¾Ð²ÐºÑ\8aоÑ\81Ñ\82алÑ\86а Ð¾Ð°Ð³IÑ\83внаÑ\88 Ð²IаÑ\88агIаÑ\82оÑ\85а  Ðµ Ð´IадеÑ\85Ñ\8cаÑ\8fккÑ\85а Ð´ÐµÐ·Ð° Ñ\88Ñ\83н.",
+       "movepagetext": "КIалха белгаляьча формах пайда ийца Iа оагIон цIи хувцаргья, цун хувцамий тептар кхыйола моттиге оттаярца цхьанна.\nКъаьнарча цIерах хургья кердача цIера дIа-сахьожадар.\nХьа аьттув ба къаьнарча цIера хинна дIа-сахьожадараш ше-ше кердадаккха.\nНагахьа санна Iа из ца дой, дехар ду, [[Special:DoubleRedirects|шолха]]  а [[Special:BrokenRedirects|хеттанза дIа-сахьожадараш]] долаш дий тахка.\nХьо бехктокхаме ва тIахьожаяргаш шоаш тIахьожаде дезача нийса хилар.\n\nТеркам бе, оагIон цIи <strong>хувцалургьйоацалга</strong> нагахьа санна изза мо цIи йола оагIув йолаш яле. Чу хIама доацача оагIонашта е дIа-сахьожадарашта, кхы а цар хувцамий истори йице, из новкъа дац. Из яхилга да, нагахьа Iа харца цIи хувцар даь дале, ше хинна цIи юхадIахувца йиш я, амма бакъда йолаш йола оагIув ца ховш дIаяккха аьттув бац. \n\n<strong>Белгалдоахар:</strong>\nГIоряьннача оагIонай цIи хувцаро тIехдоккхеи цIаьххеи хувцамаш доаладе мега.\nБоккъала, дIахо хье дIавахалехьа, кхета, хила мегаш дар хургдолга.",
+       "movepagetalktext": "Ð\9dагаÑ\85Ñ\8cа Ñ\81анна Iа ÐµÑ\80 Ð¿Ñ\83нкÑ\82 Ð±ÐµÐ»Ð³Ð°Ð»Ñ\8aйой, Ñ\86Ñ\83нÑ\86а Ð±Ñ\83взам Ð±Ð¾Ð»Ð° Ð´Ñ\83вÑ\86а Ð¾Ñ\82Ñ\82адаÑ\80а Ð¾Ð°Ð³IÑ\83в Ð¸Ñ\88Ñ\82Ñ\82а Ñ\88е-Ñ\88е Ñ\86Iи Ñ\85ийÑ\86а Ñ\85Ñ\83Ñ\80гÑ\8cÑ\8f, Ð½Ð°Ð³Ð°Ñ\85Ñ\8cа Ñ\81анна Ð¸Ð·Ð·Ð° Ð¼Ð¾ Ñ\86Iи Ð¹Ð¾Ð»Ð° Ñ\8fÑ\8cÑ\81Ñ\81а Ð¹Ð¾Ð°Ñ\86а Ð´Ñ\83вÑ\86а Ð¾Ñ\82Ñ\82адаÑ\80а Ð¾Ð°Ð³IÑ\83в Ð¹Ð¾Ð»Ð°Ñ\88 Ð¹Ð¸Ñ\86е.\n\nÐ\98з Ð¸Ñ\88Ñ\82Ñ\82а Ð´Ð°Ð»Ðµ, Ð½Ð°Ð³Ð°Ñ\85Ñ\8cа Ð¸Ð· Ñ\8dÑ\88аÑ\88 Ð´Ð°Ð»Ðµ, IайÑ\85а Ð¾Ð°Ð³Iон  Ñ\86Iи Ð´IаÑ\85Ñ\83вÑ\86а.",
        "newtitle": "Керда цIи:",
        "move-watch": "Ер оагIув зем бара хьаязъяьра юкъеяьккха",
        "movepagebtn": "ОагIон цIи хувца",
index bddf451..dca3547 100644 (file)
        "notloggedin": "Accesso non effettuato",
        "userlogin-noaccount": "Non hai ancora effettuato la registrazione?",
        "userlogin-joinproject": "Registrati su {{SITENAME}}",
-       "nologin": "Non hai ancora un accesso? $1.",
+       "nologin": "Non hai un'utenza? $1.",
        "nologinlink": "Registrati",
        "createaccount": "Registrati",
-       "gotaccount": "Hai già un accesso? $1.",
+       "gotaccount": "Hai già un'utenza? $1.",
        "gotaccountlink": "Entra",
        "userlogin-resetlink": "Hai dimenticato i tuoi dati di accesso?",
        "userlogin-resetpassword-link": "Hai dimenticato la password?",
        "nextn-title": "{{PLURAL:$1|Risultato successivo|$1 risultati successivi}}",
        "shown-title": "Mostra {{PLURAL:$1|un risultato|$1 risultati}} per pagina",
        "viewprevnext": "Vedi ($1 {{int:pipe-separator}} $2) ($3).",
-       "searchmenu-exists": "'''Sul sito esiste una pagina il cui nome è \"[[:$1]]\"'''",
+       "searchmenu-exists": "<strong>Su questo wiki esiste una pagina il cui nome è \"[[:$1]]\".</strong> {{PLURAL:$2|0=|Vedi anche gli altri risultati trovati.}}",
        "searchmenu-new": "<strong>Crea la pagina \"[[:$1]]\" su questo wiki!</strong> {{PLURAL:$2|0=|Vedi anche la pagina trovata con la tua ricerca|Vedi anche i risultati della ricerca}}",
        "searchprofile-articles": "Pagine di contenuti",
        "searchprofile-images": "Multimedia",
        "userrights-expiry-current": "Scade il $1",
        "userrights-expiry-none": "Non ha scadenza",
        "userrights-expiry": "Scadenza:",
+       "userrights-expiry-existing": "Scadenza attuale: $2, $3",
+       "userrights-expiry-othertime": "Altra durata:",
        "userrights-expiry-options": "1 giorno:1 day,1 settimana:1 week,1 mese:1 month,3 mesi:3 months,6 mesi:6 months,1 anno:1 year",
        "userrights-conflict": "Conflitto di modifica dei diritti utente! Controlla e conferma le tue modifiche.",
        "group": "Gruppo:",
        "rcfilters-invalid-filter": "Filtro non valido",
        "rcfilters-empty-filter": "Nessun filtro attivo. Sono mostrati tutti i contributi.",
        "rcfilters-filterlist-title": "Filtri",
-       "rcfilters-highlightmenu-title": "Selezionare un colore",
+       "rcfilters-highlightmenu-title": "Seleziona un colore",
        "rcfilters-filterlist-noresults": "Nessun filtro trovato",
        "rcfilters-filtergroup-registration": "Registrazione utente",
        "rcfilters-filter-registered-label": "Registrato",
        "largefileserver": "Il file supera le dimensioni consentite dalla configurazione del server.",
        "emptyfile": "Il file appena caricato sembra essere vuoto. Ciò potrebbe essere dovuto ad un errore nel nome del file. Verificare che si intenda realmente caricare questo file.",
        "windows-nonascii-filename": "Questo wiki non supporta nomi di file con caratteri speciali.",
-       "fileexists": "Un file con questo nome esiste già.\nVerificare prima <strong>[[:$1]]</strong> se non si è sicuri di volerlo sovrascrivere.\n[[$1|thumb]]",
+       "fileexists": "Un file con questo nome esiste già, verifica prima <strong>[[:$1]]</strong> se non si è sicuri di volerlo sovrascrivere.\n[[$1|thumb]]",
        "filepageexists": "La pagina di descrizione di questo file è già stata creata all'indirizzo <strong>[[:$1]]</strong>, anche se non esiste ancora un file con questo nome. La descrizione dell'oggetto inserita in fase di caricamento non apparirà sulla pagina di descrizione. Per far sì che l'oggetto compaia sulla pagina di descrizione, sarà necessario modificarla manualmente.\n[[$1|thumb]]",
        "fileexists-extension": "Un file con nome simile a questo esiste già: [[$2|thumb]]\n* Nome del file caricato: <strong>[[:$1]]</strong>\n* Nome del file esistente: <strong>[[:$2]]</strong>\nForse vuoi scegliere un nome più caratteristico?.",
        "fileexists-thumbnail-yes": "Il file caricato sembra essere una miniatura ''(thumbnail)''. [[$1|thumb]]\nVerificare, per confronto, il file <strong>[[:$1]]</strong>.\nSe si tratta della stessa immagine, nelle dimensioni originali, non è necessario caricarne altre miniature.",
        "protect-expiry-indefinite": "infinito",
        "protect-cascade": "Protezione ricorsiva (estende la protezione a tutte le pagine incluse in questa).",
        "protect-cantedit": "Non è possibile modificare i livelli di protezione per la pagina in quanto non si dispone dei permessi necessari per modificare la pagina stessa.",
-       "protect-othertime": "Durata non in elenco:",
-       "protect-othertime-op": "durata non in elenco",
+       "protect-othertime": "Altra durata:",
+       "protect-othertime-op": "altra durata",
        "protect-existing-expiry": "Scadenza attuale: $2, $3",
        "protect-existing-expiry-infinity": "Scadenza attuale: infinito",
        "protect-otherreason": "Altri motivi/dettagli:",
        "ipbemailban": "Impedisci all'utente l'invio di email",
        "ipbenableautoblock": "Blocca automaticamente l'ultimo indirizzo IP usato dall'utente e i successivi con cui vengono tentate modifiche",
        "ipbsubmit": "Blocca l'utente",
-       "ipbother": "Durata non in elenco:",
+       "ipbother": "Altra durata:",
        "ipboptions": "2 ore:2 hours,1 giorno:1 day,3 giorni:3 days,1 settimana:1 week,2 settimane:2 weeks,1 mese:1 month,3 mesi:3 months,6 mesi:6 months,1 anno:1 year,infinito:infinite",
        "ipbhidename": "Nascondi il nome utente dalle modifiche e dagli elenchi.",
        "ipbwatchuser": "Segui le pagine e le discussioni utente di questo utente",
index 8e1aa69..9fde977 100644 (file)
@@ -27,7 +27,8 @@
                        "Gi777ga",
                        "Matma Rex",
                        "Sopopruidze",
-                       "Dixtosa"
+                       "Dixtosa",
+                       "OpusDEI"
                ]
        },
        "tog-underline": "ბმულების ხაზგასმა:",
@@ -72,7 +73,7 @@
        "tog-showhiddencats": "დამალული კატეგორიების ჩვენება",
        "tog-norollbackdiff": "ცვლილების გაუქმებისას არ მანახო ცვლილებათა განსხვავება",
        "tog-useeditwarning": "გამაფრთხილე, როდესაც დავტოვებ რედაქტირებად გვერდს, დაუმახსოვრებელი ცვლილებებით",
-       "tog-prefershttps": "á\83£á\83¡á\83\90á\83¤á\83 á\83\97á\83®á\83\9d á\83\99á\83\90á\83\95á\83¨á\83\98á\83 á\83\98á\83¡ á\83\9bá\83£á\83\93á\83\90á\83\9b გამოყენება ავტორიზაციის შემდეგ",
+       "tog-prefershttps": "á\83\9bá\83£á\83\93á\83\90á\83\9b á\83£á\83¡á\83\90á\83¤á\83 á\83\97á\83®á\83\9d á\83\99á\83\90á\83\95á\83¨á\83\98á\83 á\83\98á\83¡ გამოყენება ავტორიზაციის შემდეგ",
        "underline-always": "მუდამ",
        "underline-never": "არასდროს",
        "underline-default": "დამოკიდებული მომხმარებელზე ან ბრაუზერის არჩევანზე",
        "category-file-count-limited": "შემდეგი {{PLURAL:$1|ფაილი|$1 ფაილები}} ამ კატეგორიაშია.",
        "listingcontinuesabbrev": "გაგრძ.",
        "index-category": "გვერდების ინდექსაცია",
-       "noindex-category": "არ არსებობს ინდექსირებული გვერდები",
+       "noindex-category": "არინდექსირებული გვერდები",
        "broken-file-category": "გვერდები ფაილების არასწორი ბმულებით",
        "categoryviewer-pagedlinks": "($1) ($2)",
        "category-header-numerals": "$1–$2",
        "newwindow": "(ახალ ფანჯარაში)",
        "cancel": "გაუქმება",
        "moredotdotdot": "ვრცლად...",
-       "morenotlisted": "á\83\94á\83¡ á\83\90á\83 á\83\90á\83¡á\83 á\83£á\83\9aá\83\98 á\83¡á\83\98á\83\90á\83\90.",
+       "morenotlisted": "á\83\94á\83¡ á\83¡á\83\98á\83\90 á\83¨á\83\94á\83\98á\83«á\83\9aá\83\94á\83\91á\83\90 á\83\98á\83§á\83\9dá\83¡ á\83\90á\83 á\83\90á\83¡á\83 á\83£á\83\9aá\83\98.",
        "mypage": "გვერდი",
        "mytalk": "განხილვა",
        "anontalk": "განხილვა",
        "searcharticle": "გვერდი",
        "history": "გვერდის ისტორია",
        "history_short": "ისტორია",
+       "history_small": "ისტორია",
        "updatedmarker": "განახლდა ჩემი ბოლო შემოსვლის შემდეგ",
        "printableversion": "დასაბეჭდი ვერსია",
        "permalink": "მუდმივი ბმული",
        "viewyourtext": "თქვენ შეგიძლიათ იხილოთ და დააკოპიროთ  <strong>თქვენი რედაქტირებების</strong> საწყისი ტექსტი ამ გვერდზე:",
        "protectedinterface": "ეს გვერდი წარმოადგენს ტექსტურ ინტერფეისს პროგრამული უზრუნველყოფისათვის და დაცულია ვანდალიზმის აღკვეთის მიზნით.",
        "editinginterface": "'''ყურადღება:''' თქვენ არედაქტირებთ გვერდს, რომელიც პროგრამის ინტერფეისის ტექსტს შეიცავს. \nამ გვერდზე განხორციელებული რედაქტირება გამოიწვევს ამ ვიკის სხვა მომხმარებელთა სამუშაო ინტერფეისის შეცვლასაც. \nიმისათვის, რომ დაამატოთ ან შეცვალოთ თარგმანები ყველა ვიკიში, გთხოვთ, გამოიყენოთ მედიავიკის ლოკალიზაციის პროექტი [https://translatewiki.net/ translatewiki.net].",
-       "translateinterface": "თარგმანების ყველა ვიკიში დასამატებლად ან შესაცვლელად, გთხოვთ გამოიყენოთ მედიავიკებისლოკალიზაციის პროექტი [https://translatewiki.net/ translatewiki.net].",
+       "translateinterface": "თარგმანების ყველა ვიკიში დასამატებლად ან შესაცვლელად, გთხოვთ გამოიყენოთ მედიავიკების ლოკალიზაციის პროექტი [https://translatewiki.net/ translatewiki.net].",
        "cascadeprotected": "ეს გვერდი რედაქტირებისგან დაცულია, რადგან იგი ჩართულია შემდეგ {{PLURAL:$1|გვერდში, რომლის|გვერდებში, რომელთა}} დასაცავადაც ჩართულია პარამეტრი \"იერარქიული\":\n$2",
        "namespaceprotected": "თქვენ არ გაქვთ '''$1''' სახელთა სივრცეში გვერდების რედაქტირების უფლება.",
        "customcssprotected": "თქვენ არ გაქვთ ამ CSS გვერდის რედაქტირების უფლება, ვინაიდან ის სხვა მომხმარებლის პირად კონფიგურაციას შეიცავს.",
index 89564eb..2b3ef5a 100644 (file)
@@ -16,7 +16,8 @@
                        "វ័ណថារិទ្ធ",
                        "아라",
                        "Macofe",
-                       "Dcljr"
+                       "Dcljr",
+                       "Aefgh39622"
                ]
        },
        "tog-underline": "គូសបន្ទាត់ក្រោម​តំណភ្ជាប់៖",
@@ -43,7 +44,7 @@
        "tog-enotifminoredits": "ផ្ញើអ៊ីមែល​មកខ្ញុំពេលមានបន្លាស់ប្ដូរតិចតួច​លើទំព័រឬឯកសារផងដែរ​",
        "tog-enotifrevealaddr": "បង្ហាញ​អាសយដ្ឋានអ៊ីមែល​របស់ខ្ញុំ​ក្នុង​​អ៊ីមែល​ក្រើនរំលឹក​",
        "tog-shownumberswatching": "បង្ហាញ​ចំនួនអ្នកប្រើប្រាស់​ដែលតាមដាន​ទំព័រនេះ",
-       "tog-oldsig": "ហត្ថលេខាមានហើយ៖",
+       "tog-oldsig": "á\9e á\9e\8fá\9f\92á\9e\90á\9e\9bá\9f\81á\9e\81á\9e¶á\9e\8aá\9f\82á\9e\9bá\9e¢á\9f\92á\9e\93á\9e\80á\9e\98á\9e¶á\9e\93á\9e á\9e¾á\9e\99á\9f\96",
        "tog-fancysig": "ចុះហត្ថលេខា​ជា​អត្ថបទវិគី​ (ដោយ​គ្មានតំណភ្ជាប់​ស្វ័យប្រវត្តិ)",
        "tog-uselivepreview": "ប្រើប្រាស់​ការមើលមុនរហ័ស",
        "tog-forceeditsummary": "សូមរំលឹកខ្ញុំ​កាលបើខ្ញុំទុកប្រអប់ចំណារពន្យល់ឱ្យនៅទំនេរ",
@@ -59,7 +60,7 @@
        "tog-showhiddencats": "បង្ហាញចំណាត់ថ្នាក់ក្រុមដែលត្រូវបានលាក់",
        "tog-norollbackdiff": "បំភ្លេច​ភាព​ខុស​គ្នា​បន្ទាប់​ពី​អនុវត្តការ​ស្ដារវិញ",
        "tog-useeditwarning": "សូមព្រមាន​ខ្ញុំ​ ពេលដែលខ្ញុំ​ចាកចេញ​ពី​ទំព័រ​កែប្រែដោយមិន​បានរក្សា​ទុកបន្លាស់ប្ដូរ​នានា​",
-       "tog-prefershttps": "ប្រើប្រាស់ការតភ្ជាប់មានសុវត្ថិភាពជានិច្ចពេលកត់ឈ្មោះចូល",
+       "tog-prefershttps": "á\9e\94á\9f\92á\9e\9aá\9e¾á\9e\94á\9f\92á\9e\9aá\9e¶á\9e\9fá\9f\8bá\9e\80á\9e¶á\9e\9aá\9e\8fá\9e\97á\9f\92á\9e\87á\9e¶á\9e\94á\9f\8bá\9e\8aá\9f\82á\9e\9bá\9e\98á\9e¶á\9e\93á\9e\9fá\9e»á\9e\9cá\9e\8fá\9f\92á\9e\90á\9e·á\9e\97á\9e¶á\9e\96á\9e\87á\9e¶á\9e\93á\9e·á\9e\85á\9f\92á\9e\85á\9e\96á\9f\81á\9e\9bá\9e\80á\9e\8fá\9f\8bá\9e\88á\9f\92á\9e\98á\9f\84á\9f\87á\9e\85á\9e¼á\9e\9b",
        "underline-always": "ជានិច្ច",
        "underline-never": "កុំឲ្យសោះ",
        "underline-default": "តាមលំនាំដើមនៃ​កម្មវិធី​រុករក​",
        "morenotlisted": "បញ្ជីនេះមិនទាន់ពេញលេញទេ។",
        "mypage": "ទំព័រ​",
        "mytalk": "ការពិភាក្សា​",
-       "anontalk": "á\9e\91á\9f\86á\9e\96á\9f\90á\9e\9aá\9e\96á\9e·á\9e\97á\9e¶á\9e\80á\9f\92á\9e\9fá\9e¶á\9e\9fá\9f\86á\9e\9aá\9e¶á\9e\94á\9f\8b IP á\9e\93á\9f\81á\9f\87",
+       "anontalk": "á\9e\80á\9e¶á\9e\9aâ\80\8bá\9e\96á\9e·á\9e\97á\9e¶á\9e\80á\9f\92á\9e\9fá\9e",
        "navigation": "ការណែនាំ",
        "and": "&#32;និង",
        "qbfind": "ស្វែងរក",
        "nocookieslogin": "{{SITENAME}}ប្រើខូឃីដើម្បីកត់ឈ្មោះចូល។\n\nអ្នកបានជ្រើសមិនប្រើខូឃី។​\n\nសូមជ្រើសប្រើខូឃីវិញ រួចព្យាយាមម្តងទៀត។",
        "nocookiesforlogin": "{{int:nocookieslogin}}",
        "noname": "អ្នកមិនបានផ្ដល់អត្តនាមត្រឹមត្រូវទេ។",
-       "loginsuccesstitle": "á\9e\80á\9e\8fá\9f\8bá\9e\88á\9f\92á\9e\98á\9f\84á\9f\87á\9e\85á\9e¼á\9e\9bá\9e\94á\9e¶á\9e\93á\9e\9fá\9e\98á\9f\92á\9e\9aá\9f\81á\9e\85",
+       "loginsuccesstitle": "á\9e\94á\9e¶á\9e\93á\9e\80á\9e\8fá\9f\8bá\9e\88á\9f\92á\9e\98á\9f\84á\9f\87á\9e\85á\9e¼á\9e\9bá\9e á\9e¾á\9e\99",
        "loginsuccess": "'''ពេលនេះអ្នកបានកត់ឈ្មោះចូល{{SITENAME}}ដោយប្រើឈ្មោះ \"$1\"ហើយ។'''",
        "nosuchuser": "មិនមានអ្នកប្រើដែលមានឈ្មោះ \"$1\" ទេ។\n\nសូម​ពិនិត្យ​ក្រែង​លោ​មានកំហុស​អក្ខរាវិរុទ្ធឬ [[Special:CreateAccount|បង្កើត​គណនី​ថ្មី]]។",
        "nosuchusershort": "គ្មានអ្នកប្រើដែលមានឈ្មោះ $1\" ទេ។\n\nសូម​ពិនិត្យ​​អក្ខរាវិរុទ្ធ​របស់អ្នក ។",
        "newpassword": "ពាក្យសម្ងាត់ថ្មី៖",
        "retypenew": "សូមវាយពាក្យសម្ងាត់ថ្មី​ម្តងទៀត៖",
        "resetpass_submit": "ដាក់ប្រើពាក្យសម្ងាត់និង​កត់ឈ្មោះចូល",
-       "changepassword-success": "á\9e\96á\9e¶á\9e\80á\9f\92á\9e\99á\9e\9fá\9e\98á\9f\92á\9e\84á\9e¶á\9e\8fá\9f\8bá\9e\9aá\9e\94á\9e\9fá\9f\8bá\9e¢á\9f\92á\9e\93á\9e\80á\9e\8fá\9f\92á\9e\9aá\9e¼á\9e\9cá\9e\94á\9e¶á\9e\93á\9e\95á\9f\92á\9e\9bá\9e¶á\9e\9fá\9f\8bá\9e\94á\9f\92á\9e\8fá\9e¼á\9e\9aá\9e\94á\9e¶á\9e\93á\9e\9fá\9f\86á\9e\9aá\9f\81á\9e\85á\9e á\9e¾á\9e\99!",
+       "changepassword-success": "ពាក្យសម្ងាត់របស់អ្នកត្រូវបានផ្លាស់ប្តូរហើយ!",
        "changepassword-throttled": "អ្នកបានព្យាយាមកត់ឈ្មោះចូលជាប់ៗគ្នាច្រើនដងពេកហើយ។​\nសូមរង់ចាំរយៈពេល$1 មុនពេលសាកល្បងម្ដងទៀត។",
        "resetpass_forbidden": "ពាក្យសម្ងាត់មិនអាចផ្លាស់ប្តូរបានទេ",
        "resetpass-no-info": "អ្នក​ចាំបាច់​ត្រូវតែ​កត់ឈ្មោះចូល ដើម្បី​ចូលទៅកាន់​ទំព័រ​នេះ​ដោយផ្ទាល់​។",
        "passwordreset-emaildisabled": "មុខងារអ៊ីមែលត្រូវបានបិទមិនអោយប្រើនៅលើវិគីនេះ។",
        "passwordreset-username": "អត្តនាម៖",
        "passwordreset-domain": "ដូម៉ែន៖",
-       "passwordreset-capture": "មើលអ៊ីមែលលទ្ធផល?",
-       "passwordreset-capture-help": "ប្រសិនបើអ្នកគូសធីកប្រអប់នេះ អ៊ីមែល (ដែលមានពាក្យសម្ងាត់បណ្ដោះអាសន្ន) មិនត្រូវបានបង្ហាញដូចគ្នានឹងអ៊ីមែលដែលនឹងត្រូវផ្ញើទៅទៅកាន់អ្នកប្រើប្រាស់ដែរ។",
        "passwordreset-email": "អាសយដ្ឋានអ៊ីមែល៖",
        "passwordreset-emailtitle": "ព័ត៌មានលំអិតពីគណនីនៅលើ {{SITENAME}}",
        "passwordreset-emailtext-ip": "មាននរណាម្នាក់ (ប្រហែលជាខ្លួនអ្នកផ្ទាល់, មកពីអាស័យដ្ឋាន IP $1) បានស្នើសុំស្ដារពាក្យសម្ងាត់របស់អ្នកសម្រាប់ {{SITENAME}} ($4)។ {{PLURAL:$3|គណនី|គណនី}}អ្នកប្រើប្រាស់ដូចតទៅនេះ\nមានជាប់ទាក់ទិននឹងអាសយដ្ឋានអ៊ីមែលនេះ៖\n\n$2\n\n{{PLURAL:$3|ពាក្យសម្ងាត់បណ្ដោះអាសន្ននេះ|ពាក្យសម្ងាត់បណ្ដោះអាសន្នទាំងនេះ}} និងហួសសុពលភាពក្នុងរយៈពេល {{PLURAL:$5|មួយថ្ងៃ|$5 ថ្ងៃ}}។\nយកល្អអ្នកគួរតែកត់ឈ្មោះចូលរួចជ្រើសរើសពាក្យសម្ងាត់ថ្មីមួយ។ ប្រសិនបើមាននរណាម្នាក់ផ្សេងធ្វើការស្នើសុំនេះ \nឬប្រសិនបើអ្នកនឹកឃើញពាក្យសម្ងាត់ដើមរបស់អ្នក ហើយអ្នកមិនប្រាថ្នាផ្លាស់ប្ដូរវាទៀតទេនោះ អ្នកគ្រាន់តែ\nបំភ្លេចអំពីសារមួយនេះ ហើយបន្តប្រើប្រាស់ពាក្យសម្ងាត់ចាស់របស់អ្នកទៅបានហើយ។",
        "saveprefs": "រក្សាទុក",
        "restoreprefs": "ស្ដារ​ការកំណត់​ទាំងអស់​ទៅ​លំនាំដើម (គ្រប់ផ្នែកទាំងអស់)",
        "prefs-editing": "កំណែប្រែ",
-       "rows": "ជួរដេក៖",
-       "columns": "ជួរឈរ៖",
        "searchresultshead": "ស្វែងរក",
        "stub-threshold": "ទំហំអប្បបរមាសម្រាប់ដាក់ជាទម្រង់ទំព័រកំប៉ិចកំប៉ុក($1)៖",
        "stub-threshold-sample-link": "គំរូ",
        "userrights-reason": "មូលហេតុ៖",
        "userrights-no-interwiki": "អ្នកគ្មានការអនុញ្ញាតកែប្រែសិទ្ធិរបស់អ្នកប្រើប្រាស់លើវិគីផ្សេងទេ។",
        "userrights-nodatabase": "មូលដ្ឋានទិន្នន័យ $1 មិនមាន ឬ ស្ថិតនៅខាងក្រៅ។",
-       "userrights-nologin": "អ្នកត្រូវតែ [[Special:UserLogin|កត់ឈ្មោះចូល]]ដោយប្រើគណនីអ្នកអភិបាលដើម្បីផ្ដល់សិទ្ធិឱ្យអ្នកប្រើប្រាស់​។",
-       "userrights-notallowed": "លោកអ្នកគ្មានការអនុញ្ញាតដើម្បីបន្ថែមឬដកសិទ្ធិរបស់អ្នកប្រើប្រាស់ដទៃទេ។",
        "userrights-changeable-col": "ក្រុមនានាដែលអ្នកអាចផ្លាស់ប្ដូរបាន",
        "userrights-unchangeable-col": "ក្រុមនានាដែលអ្នកមិនអាចផ្លាស់ប្ដូរបាន",
        "userrights-conflict": "មានទំនាស់អំពីការកែប្រែសិទ្ធិអ្នកប្រើប្រាស់! សូមត្រួតពិនិត្យឡើងវិញរួចអះអាងពីការកែប្រែរបស់អ្នក។",
-       "userrights-removed-self": "អ្នកបានដកសិទ្ធិខ្លួនឯងបានសម្រេចហើយ។ ហេតុនេះ អ្នកមិនអាចចូលមើលទំព័រនេះតទៅទៀតទេ។",
        "group": "ក្រុម៖",
        "group-user": "អ្នកប្រើប្រាស់",
        "group-autoconfirmed": "អ្នកប្រើប្រាស់ទទួលស្គាល់ដោយស្វ័យប្រវត្តិ",
        "right-siteadmin": "ចាក់សោនិងបើកសោមូលដ្ឋានទិន្នន័យ",
        "right-override-export-depth": "នាំចេញទំព័ររួមទាំងទំព័រដែលមានភ្ជាប់តំណភ្ជាប់​រហូតដល់លំដាប់ទី៥",
        "right-sendemail": "ផ្ញើអ៊ីមែលទៅកាន់អ្នកប្រើដទៃ",
-       "right-passwordreset": "មើលអ៊ីមែលសំរាប់កំណត់ពាក្យសម្ងាត់ឡើងវិញ",
        "newuserlogpage": "កំណត់ហេតុនៃការបង្កើតគណនី",
        "newuserlogpagetext": "នេះជាកំណត់ហេតុនៃការបង្កើតអ្នកប្រើប្រាស់។",
        "rightslog": "កំណត់ហេតុនៃការប្តូរសិទ្ធិអ្នកប្រើប្រាស់",
        "rightslogtext": "នេះ​ជា​កំណត់ហេតុនៃបំលាស់ប្ដូរចំពោះកាប្ដូរក្រុមសមាជិកភាព​របស់​អ្នកប្រើប្រាស់។",
        "action-read": "អានទំព័រនេះ",
        "action-edit": "កែប្រែទំព័រនេះ",
-       "action-createpage": "á\9e\94á\9e\84á\9f\92á\9e\80á\9e¾á\9e\8fá\9e\91á\9f\86á\9e\96á\9f\90á\9e\9aá\9e\93á\9e¶á\9e\93á\9e",
-       "action-createtalk": "á\9e\94á\9e\84á\9f\92á\9e\80á\9e¾á\9e\8fá\9e\91á\9f\86á\9e\96á\9f\90á\9e\9aá\9e\96á\9e·á\9e\97á\9e¶á\9e\80á\9f\92á\9e\9fá\9e¶á\9e\93á\9e¶á\9e\93á\9e",
+       "action-createpage": "á\9e\94á\9e\84á\9f\92á\9e\80á\9e¾á\9e\8fá\9e\91á\9f\86á\9e\96á\9f\90á\9e\9aá\9e\93á\9f\81á\9f\87",
+       "action-createtalk": "á\9e\94á\9e\84á\9f\92á\9e\80á\9e¾á\9e\8fá\9e\91á\9f\86á\9e\96á\9f\90á\9e\9aá\9e\96á\9e·á\9e\97á\9e¶á\9e\80á\9f\92á\9e\9fá\9e¶á\9e\93á\9f\81á\9f\87",
        "action-createaccount": "បង្កើតគណនីអ្នកប្រើប្រាស់នេះ",
        "action-history": "មើលប្រវត្តិទំព័រនេះ",
        "action-minoredit": "ចំណាំកំណែប្រែនេះថាជាកំណែប្រែតិចតួច",
        "feedback-thanks-title": "សូមអរគុណ!",
        "searchsuggest-search": "ស្វែងរក​",
        "searchsuggest-containing": "ដែលមានពាក្យ...",
-       "api-error-badaccess-groups": "អ្នកគ្មានការអនុញ្ញាតអោយផ្ទុកឯកសារឡើងទៅក្នុងវិគីនេះទេ។",
-       "api-error-empty-file": "ឯកសារដែលអ្នកបានដាក់ស្នើគឺទទេ។",
        "api-error-emptypage": "ការអនុញ្ញាតអោយបង្កើតទំព័រថ្មីដែលគ្មានសរសេរអ្វីទេ",
-       "api-error-fileexists-forbidden": "ឯកសារដែលមានឈ្មោះ \"$1\" មានរួចហើយ ហើយមិនអាចសរសេរជាន់ពីលើបានទេ។",
-       "api-error-fileexists-shared-forbidden": "ឯកសារដែលមានឈ្មោះ \"$1\" មានរួចហើយនៅក្នុងថតឯកសាររួម ហើយមិនអាចសរសេរជាន់ពីលើបានទេ។",
-       "api-error-file-too-large": "ឯកសារដែលអ្នកបានដាក់ស្នើធំពេកហើយ។",
-       "api-error-filename-tooshort": "ឈ្មោះឯកសារខ្លីពេកហើយ។",
-       "api-error-filetype-banned": "ឯកសារប្រភេទនេះត្រូវបានហាមប្រាម។",
-       "api-error-filetype-banned-type": "$1 {{PLURAL:$4|មិនមែនជា​ប្រភេទ​ឯកសារ​ដែល​ត្រូវ​បាន​គេ​អនុញ្ញាត​ទេ|មិនមែនជា​ប្រភេទ​ឯកសារ​ដែល​ត្រូវ​បាន​គេ​អនុញ្ញាត​ទេ​}}។\n{{PLURAL:$3|ប្រភេទឯកសារ​|ប្រភេទឯកសារ​}}ដែល​ត្រូវ​បាន​គេ​អនុញ្ញាត​គឺ $2 ។",
-       "api-error-filetype-missing": "ឈ្មោះឯកសារបាត់កន្ទុយ។",
-       "api-error-http": "បញ្ហាខាងក្នុង៖ មិនអាចភ្ជាប់ទោកាន់ម៉ាស៊ីនបំរើការ។",
-       "api-error-illegal-filename": "មិនអនុញ្ញាតអោយប្រើឈ្មោះឯកសារនេះ។",
-       "api-error-internal-error": "បញ្ហាខាងក្នុង៖ មានបញ្ហាណាមួយកើតឡើងពេលកំពុងដំណើរការផ្ទុកឯកសារអ្នកឡើងទៅក្នុងវិគី។",
-       "api-error-missingresult": "បញ្ហាខាងក្នុង៖ មិនអាចកំណត់បានថាការថតចំលងបានសំរេចទេ។",
-       "api-error-mustbeloggedin": "អ្នកត្រូវតែកត់ឈ្មោះចូលដើម្បីផ្ទុកឯកសារឡើង។",
-       "api-error-ok-but-empty": "បញ្ហាខាងក្នុង៖ គ្មានចម្លើយពីម៉ាស៊ីនបម្រើការ។",
-       "api-error-overwrite": "មិនអនុញ្ញាតអោយសរសេរជាន់ពីលើឯកសារដែលមានស្រាប់ហើយ។",
-       "api-error-timeout": "ម៉ាស៊ីនបំរើការមិនបានឆ្លើយតបក្នុងរយៈពេលដែលយើងរំពឹងទុក។",
-       "api-error-unclassified": "បញ្ហាមិនស្គាល់មួយបានកើតឡើង។",
-       "api-error-unknown-code": "បញ្ហាមិនស្គាល់៖ \"$1\" ។",
-       "api-error-unknown-error": "បញ្ហាខាងក្នុង៖ មានបញ្ហាមិនស្រួលពេលកំពុងព្យាយាមផ្ទុកឯកសាររបស់អ្នកឡើង។",
        "api-error-unknown-warning": "ការព្រមានមិនស្គាល់៖ \"$1 ។",
        "api-error-unknownerror": "បញ្ហាមិនស្គាល់៖ \"$1\" ។",
-       "api-error-uploaddisabled": "ការផ្ទុកឡើងត្រូវបានបិទមិនអោយប្រើនៅលើវិគីនេះទេ។",
-       "api-error-verification-error": "ឯកសារនេះប្រហែលជាខូច ឯមានកន្ទុយមិនត្រឹមត្រូវ។",
        "duration-seconds": "$1 {{PLURAL:$1|វិនាទី|វិនាទី}}",
        "duration-minutes": "$1 {{PLURAL:$1|នាទី|នាទី}}",
        "duration-hours": "$1 {{PLURAL:$1|ម៉ោង|ម៉ោង}}",
index 52ff8e6..8660847 100644 (file)
        "rcfilters-invalid-filter": "유효하지 않은 필터",
        "rcfilters-empty-filter": "활성화된 필터가 없습니다. 모든 기여가 표시됩니다.",
        "rcfilters-filterlist-title": "필터",
+       "rcfilters-filterlist-feedbacklink": "새로운 (베타) 필터에 대한 의견을 주세요",
+       "rcfilters-highlightbutton-title": "결과 강조",
+       "rcfilters-highlightmenu-title": "색 선택",
        "rcfilters-filterlist-noresults": "필터를 찾을 수 없습니다",
        "rcfilters-filtergroup-registration": "사용자 등록",
        "rcfilters-filter-registered-label": "등록됨",
        "rcfilters-filter-bots-label": "봇",
        "rcfilters-filter-bots-description": "자동 도구를 이용한 편집.",
        "rcfilters-filter-humans-label": "사람 (봇이 아님)",
-       "rcfilters-filter-humans-description": "ì\88\98ë\8f\99ì\9c¼ë¡\9c 한 편집.",
+       "rcfilters-filter-humans-description": "ì\82¬ë\9e\8cì\9d´ 한 편집.",
        "rcfilters-filtergroup-significance": "의미",
        "rcfilters-filter-minor-label": "사소한 편집",
        "rcfilters-filter-major-label": "사소하지 않은 편집",
        "rcfilters-filter-newpages-description": "새 문서를 만드는 편집.",
        "rcfilters-filter-categorization-label": "분류 차이",
        "rcfilters-filter-categorization-description": "분류에서 추가되거나 제거되는 페이지의 기록.",
+       "rcfilters-filter-logactions-description": "관리적 조치, 계정 만들기, 페이지 삭제, 업로드...",
        "rcnotefrom": "아래는 <strong>$3, $4</strong>부터 시작하는 {{PLURAL:$5|바뀜이 있습니다}}. (최대 <strong>$1</strong>개가 표시됨)",
        "rclistfrom": "$3 $2부터 시작하는 새로 바뀐 문서 보기",
        "rcshowhideminor": "사소한 편집 $1",
        "uncategorizedcategories": "분류되지 않은 분류 목록",
        "uncategorizedimages": "분류되지 않은 파일 목록",
        "uncategorizedtemplates": "분류되지 않은 틀 목록",
+       "uncategorized-categories-exceptionlist": "# \"특수:분류안된분류\"에 언급되지 않은 분류의 목록을 포함합니다. 한 줄에 하나씩 \"*\"로 시작합니다. 다른 문자(공백 포함)로 시작하는 줄들은 무시됩니다. 주석의 경우 \"#\"를 사용하십시오.",
        "unusedcategories": "사용하지 않는 분류 목록",
        "unusedimages": "사용하지 않는 파일 목록",
        "wantedcategories": "필요한 분류 목록",
        "apisandbox-alert-field": "이 필드의 값이 유효하지 않습니다.",
        "apisandbox-continue": "계속",
        "apisandbox-continue-clear": "지우기",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}}은 마지막 요청을 [https://www.mediawiki.org/wiki/API:Query#Continuing_queries 계속]합니다. {{int:apisandbox-continue-clear}}는 계속 관련 변수들을 삭제합니다.",
        "apisandbox-param-limit": "최대 한계치를 사용하려면 <kbd>max</kbd>를 입력하십시오.",
        "apisandbox-multivalue-all-namespaces": "$1 (모든 이름공간)",
        "apisandbox-multivalue-all-values": "$1 (모든 값)",
        "emailccsubject": "$1에게 보낸 메시지의 복사본: $2",
        "emailsent": "이메일 보냄",
        "emailsenttext": "이메일을 보냈습니다.",
-       "emailuserfooter": "이 이메일은 {{SITENAME}}의 $1님이 $2님에게 \"{{int:emailuser}}\" 기능을 통해 보냈습니다. 만약, {{GENDER:$2|당신}}이 이 이메일을 답장하면, {{GENDER:$2|당신}}의 이메일은 {{GENDER:$1|원래 사용자}}에게 {{GENDER:$2|당신}}의 이메일 주소가  {{GENDER:$1|원래 사용자}}에게 공개되면서 보내집니다.",
+       "emailuserfooter": "이 이메일은 {{SITENAME}}의 $1님이 $2님에게 \"{{int:emailuser}}\" 기능을 통해 보냈습니다. 이 이메일에 답장을 보내게 되면 원래 이메일을 보낸 사용자에게 직접 답장을 보내게 되며, 따라서 귀하의 이메일 주소를 보낸 사용자에게 공개하게 됩니다.",
        "usermessage-summary": "시스템 메시지 남기기",
        "usermessage-editor": "시스템 메신저",
        "usermessage-template": "MediaWiki:UserMessage",
        "editcomment": "편집 요약: <em>$1</em>",
        "revertpage": "[[Special:Contributions/$2|$2]]([[User talk:$2|토론]])의 편집을 [[User:$1|$1]]의 마지막 판으로 되돌림",
        "revertpage-nouser": "숨긴 사용자의 편집을 {{GENDER:$1|[[User:$1|$1]]}}의 마지막 판으로 되돌림",
-       "rollback-success": "$1의 편집을 되돌렸습니다.\n$2의 마지막 판으로 바뀌었습니다.",
+       "rollback-success": "{{GENDER:$3|$1}}의 편집을 되돌렸습니다.\n{{GENDER:$4|$2}}의 마지막 판으로 바뀌었습니다.",
        "rollback-success-notify": "$1의 편집을 되돌렸습니다.\n$2의 마지막 판으로 바뀌었습니다. [$3 차이 보기]",
        "sessionfailure-title": "세션 실패",
        "sessionfailure": "로그인 세션에 문제가 발생한 것 같습니다.\n세션 하이재킹을 막기 위해 동작이 취소되었습니다.\n브라우저의 뒤로 버튼을 누르고 문서를 새로 고침한 후에 다시 시도해 주세요.",
        "imagenocrossnamespace": "파일을 파일이 아닌 이름공간으로 이동할 수 없습니다.",
        "nonfile-cannot-move-to-file": "파일이 아닌 문서를 파일 이름공간으로 이동할 수 없습니다.",
        "imagetypemismatch": "새 파일의 확장자가 원래의 확장자와 일치하지 않습니다.",
-       "imageinvalidfilename": " 파일 이름이 잘못되었습니다.",
+       "imageinvalidfilename": "대상 파일 이름이 잘못되었습니다.",
        "fix-double-redirects": "원래 제목을 가리키는 넘겨주기를 새로 고침",
        "move-leave-redirect": "이동한 뒤 넘겨주기를 남기기",
        "protectedpagemovewarning": "<strong>경고:</strong> 이 문서는 관리자만 이동할 수 있도록 보호되어 있습니다.\n최근 기록을 참조를 위해 아래에 제공합니다:",
        "htmlform-date-invalid": "지정한 값은 인식할 수 있는 날짜가 아닙니다. YYYY-MM-DD 형식을 사용하세요.",
        "htmlform-time-invalid": "지정한 값은 인식할 수 있는 시간이 아닙니다. HH:MM:SS 형식을 사용하세요.",
        "htmlform-datetime-invalid": "지정한 값은 인식할 수 있는 날짜 및 시간이 아닙니다. YYYY-MM-DD HH:MM:SS 형식을 사용하세요.",
+       "htmlform-date-toolow": "지정된 값은 최소로 허용된 날짜 $1 보다 이전입니다.",
+       "htmlform-date-toohigh": "지정된 값은 최대로 허용된 날짜 $1 보다 이후입니다.",
+       "htmlform-time-toolow": "지정된 값은 최소로 허용된 시간 $1 보다 이전입니다.",
+       "htmlform-time-toohigh": "지정된 값은 최대로 허용된 시간 $1 보다 이후입니다.",
+       "htmlform-datetime-toolow": "지정된 값은 최소로 허용된 시간 $1 보다 이전입니다.",
+       "htmlform-datetime-toohigh": "지정된 값은 최대로 허용된 시간 $1 보다 이후입니다.",
        "htmlform-title-badnamespace": "[[:$1]] 문서는 \"{{ns:$2}}\" 이름공간에 없습니다.",
        "htmlform-title-not-creatable": "\"$1\"은 만들 수 없는 문서 제목입니다.",
        "htmlform-title-not-exists": "$1 문서는 존재하지 않습니다.",
index afd8cc5..06998ae 100644 (file)
        "wantedfiletext-nocat-noforeign": "I seguenti file son in doeuvia, ma no existan.",
        "wantedtemplates": "Template domandæ",
        "mostlinked": "Paggine ciû collegæ",
-       "mostlinkedcategories": "Categorîe ciû collegæ",
+       "mostlinkedcategories": "Categorie ciu conligæ",
        "mostlinkedtemplates": "Paggine ciu incluse",
        "mostcategories": "Voxe con ciû categorîe",
        "mostimages": "Immaggini con ciû collegamenti",
        "protectedtitles-summary": "Questa pagina a l'elenca i titoli che son attualmente protetti da-a creaçion. Pe 'n elenco de pagine existente che son protette, amia [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Tittoli protezui con sti parammetri pe-o momento no ghe n'è.",
        "protectedtitles-submit": "Mostra tittoli",
-       "listusers": "Lista dtenti",
+       "listusers": "Lista di utenti",
        "listusers-editsonly": "Mostra solo i utenti con di contributi",
        "listusers-creationsort": "Ordina pe dæta de creaçion",
        "listusers-desc": "Ordina in senso decrescente",
index 9d4c115..195699d 100644 (file)
        "rcfilters-clear-all-filters": "Valyti visus filtrus",
        "rcfilters-invalid-filter": "Negalimas filtras",
        "rcfilters-filterlist-title": "Filtrai",
+       "rcfilters-highlightmenu-title": "Pasirinkti spalvą",
        "rcfilters-filterlist-noresults": "Nerastas toks filtras",
        "rcfilters-filtergroup-registration": "Vartotojo registracija",
        "rcfilters-filter-registered-label": "Registruoti",
index aa8101a..c0035b9 100644 (file)
        "newarticletext": "Šajā projektā vēl nav lapas ar šādu nosaukumu.\nLai izveidotu lapu, sāc rakstīt teksta logā apakšā (par teksta formatēšanu un sīkākai informācija skatīt [$1 palīdzības lapu]).\nJa tu šeit nonāci kļūdas pēc, vienkārši uzspied <strong>back</strong> pogu pārlūkprogrammā.",
        "anontalkpagetext": "----''Šī ir diskusiju lapa anonīmam dalībniekam, kurš vēl nav kļuvis par reģistrētu dalībnieku vai arī neizmanto savu dalībnieka vārdu. Tādēļ mums ir jāizmanto skaitliskā IP adrese, lai viņu identificētu.\nŠāda IP adrese var būt vairākiem dalībniekiem.\nJa tu esi anonīms dalībnieks un uzskati, ka tev ir adresēti neatbilstoši komentāri, lūdzu, [[Special:CreateAccount|kļūsti par dalībnieku]] vai arī [[Special:UserLogin|izmanto jau izveidotu dalībnieka vārdu]], lai izvairītos no turpmākām neskaidrībām un tu netiktu sajaukts ar citiem anonīmiem dalībniekiem.''",
        "noarticletext": "Šajā lapā šobrīd nav nekāda teksta, tu vari [[Special:Search/{{PAGENAME}}|meklēt citās lapās pēc šīs lapas nosaukuma]], <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} meklēt saistītos reģistru ierakstos] vai arī [{{fullurl:{{FULLPAGENAME}}|action=edit}} sākt rediģēt šo lapu]</span>.",
-       "noarticletext-nopermission": "Šajā lapā pašlaik nav nekāda teksta.\nTu vari [[Special:Search/{{PAGENAME}}|meklēt šīs lapas nosaukumu]] citās lapās,\nvai <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} meklēt saistītus reģistru ierakstus]</span>, bet jums nav atļauja izveidot si lapu.",
+       "noarticletext-nopermission": "Šajā lapā pašlaik nav nekāda teksta.\nTu vari [[Special:Search/{{PAGENAME}}|meklēt šīs lapas nosaukumu]] citās lapās,\nvai <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} meklēt saistītus reģistru ierakstus]</span>, bet jums nav atļauja izveidot šo lapu.",
        "userpage-userdoesnotexist": "Lietotājs \"<nowiki>$1</nowiki>\" nav reģistrēts.\nLūdzu, pārliecinies vai vēlies izveidot/izmainīt šo lapu.",
        "userpage-userdoesnotexist-view": "Dalībnieks \"$1\" nav reģistrēts.",
        "blocked-notice-logextract": "Šis dalībnieks pašlaik ir nobloķēts.\n\nPēdējais bloķēšanas reģistra ieraksts ir apskatāms zemāk:",
index a908160..5f512ff 100644 (file)
        "missingarticle-rev": "(famerenana faha : $1)",
        "missingarticle-diff": "(diff : $1 ; $2)",
        "readonly_lag": "\nMihidy ho azy aloha ny banky angona mandra-pahatratran'ny serveur andevo ny tompony",
+       "nonwrite-api-promise-error": "Ny loha HTTP \"<code>Promise-Non-Write-API-Action:</code>\" dia nalefa fa tsy natao tany amina module fanoratana API ny hataka",
        "internalerror": "Tsy fetezana anatin'ny rindrankajy",
        "internalerror_info": "Tsy fetezana ety anatiny : $1",
        "internalerror-fatal-exception": "Karazana-kadisoana nampijanona \"$1\"",
        "passwordreset-emailsentemail": "Lasa ny mailaka famerenana tenimiafina.",
        "passwordreset-nocaller": "Mila manitsy mpiantso",
        "passwordreset-nosuchcaller": "Tsy misy ilay mpiantso: $1",
-       "changeemail": "Hanova ny adiresy imailaka",
-       "changeemail-header": "Hanova ny adiresy imailak'ilay kaonty",
+       "passwordreset-invalidemail": "Adiresy mailaka tsy azo raisina",
+       "passwordreset-nodata": "Tsy nanome anaram-pikambana na adiresy mailaka",
+       "changeemail": "Hanova na hanala adiresy mailaka",
+       "changeemail-header": "Fenoy ity fôrmiolera ity ahafahanao manova ny adiresy mailakao. Raha tianao ho esorina ny fifandraisan'ity mailaka ity amin'ny kaontinao dia avelao ho fotsy ny saha rehefa mandefa fôrmiolera.",
        "changeemail-no-info": "Mila tafiditra ianao vao avaka mijery ity pejy ity.",
        "changeemail-oldemail": "Adiresy imailaka ankehitriny :",
        "changeemail-newemail": "Adiresy imailaka vaovao :",
        "search-external": "Hikaroka any ivelany",
        "searchdisabled": "Tsy nalefa ny karoka eto amin'i {{SITENAME}}. Afaka mampiasa an'i Google aloha ianao mandra-paha. Nefa fantaro fa mety ho efa lany daty ny valiny omeny.",
        "search-error": "Hadisoana nitranga tam-pikarohana: $1",
+       "search-warning": "Fampitandremana nitranga teo am-pikarohana: $1",
        "preferences": "Ny momba anao",
        "mypreferences": "Safidy",
        "prefs-edits": "isa ny fanovàna :",
        "rcfilters-filter-major-description": "Fiovana tsy natao ho madinika.",
        "rcfilters-filtergroup-changetype": "Karazam-piovana",
        "rcfilters-filter-pageedits-label": "Fiovam-pejy",
+       "rcfilters-filter-newpages-label": "Famoronam-pejy",
+       "rcfilters-filter-newpages-description": "Fiovana nahatonga famoronam-pejy.",
+       "rcfilters-filter-categorization-label": "Fiovana amin'ny sokajy",
+       "rcfilters-filter-categorization-description": "Fandraiketana an'ireo pejy ampiana na esorina amin'ny sokajy.",
+       "rcfilters-filter-logactions-label": "Asa voalaogy",
        "rcnotefrom": "Eo ambany dia ahitana ireo fiovana{{PLURAL:$5}} hatry ny <strong>$3, $4</strong> (naseho hatramin'ny <strong>$1</strong>).",
        "rclistfrom": "Asehoy izay vao niova manomboka ny $3 $2",
        "rcshowhideminor": "$1 ny fanovàna kely",
        "upload-copy-upload-invalid-domain": "Tsy misy eto amin'ity dômenina ity ny tahaky ny upload.",
        "upload-dialog-title": "Hanafatra rakitra",
        "upload-dialog-button-cancel": "Aoka",
+       "upload-dialog-button-back": "Hiverina",
        "upload-dialog-button-done": "Vita",
        "upload-dialog-button-save": "Tehirizina",
        "upload-dialog-button-upload": "Mampiditra",
        "special-characters-group-khmer": "kimera",
        "special-characters-title-endash": "tsipika anglisy",
        "special-characters-title-emdash": "tsipika em",
-       "special-characters-title-minus": "marika mainosy"
+       "special-characters-title-minus": "marika mainosy",
+       "sessionmanager-tie": "Tsy afaka mampikambana karazan-kataka fampamantarana maromaro: $1.",
+       "authmanager-authn-not-in-progress": "Tsy andalam-panaovana ny fampamantarana, na very ny angon'ny sesiôna. Avereno hatramin'ny voalohany azafady.",
+       "authmanager-authplugin-setpass-failed-title": "Tsy nahomby ny fanovana tenimiafina",
+       "authmanager-authplugin-setpass-failed-message": "Nandà ny fanovana tenimiafina ny plugin fampamantarana.",
+       "authmanager-authplugin-create-fail": "Nandà ny famoronan-kaonty ny plugin fampamantarana.",
+       "authmanager-authplugin-setpass-denied": "Tsy ahafahana manova tenimiafina ny plugin fampamantarana.",
+       "authmanager-userlogin-remembermypassword-help": "Milaza raha tsy maintsy tadidiana mihoatra ny halafan'ny fotoam-pitsidihana ny tenimiafina.",
+       "authmanager-username-help": "Anaram-pikambana ho an'ny fampamantarana.S",
+       "authmanager-password-help": "Tenimiafina ho an'ny fampamantarana.",
+       "authmanager-retype-help": "tenimiafina indray hanamarinana.",
+       "authmanager-provider-password": "Fampamamtarana mifototra amin'ny tenimiafina",
+       "authmanager-provider-password-domain": "Fampamantarana mifototra amin'ny tenimiafina ary vala",
+       "authmanager-provider-temporarypassword": "Tenimiafina vonjimaika",
+       "authprovider-resetpass-skip-help": "Handingana ny famerenam-tenimiafina.",
+       "authform-nosession-login": "nahomby ny fidirana, fa tsy mahatadidy anao tafiditra ny mpitety tranonkalanao."
 }
index 7021f60..629386b 100644 (file)
        "minoredit": "Тиде изи вашталтыш",
        "watchthis": "Тиде лаштыкым эскераш",
        "savearticle": "Лаштыкым аралаш",
+       "savechanges": "Лаштыкым аралаш",
+       "publishchanges": "Лаштыкым аралаш",
        "preview": "Ончылгоч ончымаш",
        "showpreview": "Ончылгоч ончымаш",
        "showdiff": "Тӧрлатымашым ончыкташ",
        "summary-preview": "Тӧрлатымаш нерген ончылгоч ончымаш:",
        "accmailtitle": "Шолыпмут колтымо.",
        "newarticle": "(У)",
-       "newarticletext": "Тыгай лӱман лаштык уке.\nЛаштыкым ышташлан ӱлнӧ возаш тӱҥал (сайынрак палашлан [$1 полшыкым] ончал).\nТый тышке йонгылыш логалынат гын, браузерыште '''шенгек''' полдышым темдал.",
+       "newarticletext": "Тыгай лӱман лаштык уке.\nЛаштыкым ышташлан ӱлнӧ возаш тӱҥал (сайынрак палашлан [$1 полшыкым] ончал).\nТый тышке йоҥылыш логалынат гын, браузерыште '''шенгек''' полдышым темдал.",
        "noarticletext": "Кызытсе жаплан тиде лаштыкыште нимом возымо огыл.\nТый тиде лаштыкын лӱмжым вес лаштык-влакыште [[Special:Search/{{PAGENAME}}|кычалын]] кертат, але <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} журнал-влакыште кычалын] кертат, але [{{fullurl:{{FULLPAGENAME}}|action=edit}} тыгай лӱман лаштыкым ыштен] кертат</span>.",
        "clearyourcache": "'''Замечание.''' Возможно, после сохранения вам придётся очистить кэш своего браузера, чтобы увидеть изменения.\n* '''Firefox / Safari:''' Удерживая клавишу ''Shift'', нажмите на панели инструментов ''Обновить'' либо нажмите ''Ctrl-F5'' или ''Ctrl-R'' (''⌘-R'' на Mac)\n* '''Google Chrome:''' Нажмите ''Ctrl-Shift-R'' (''⌘-Shift-R'' на Mac)\n* '''Internet Explorer:''' Удерживая ''Ctrl'', нажмите ''Обновить'' либо нажмите ''Ctrl-F5''\n* '''Opera:''' Выберите очистку кэша в меню ''Инструменты → Настройки''",
        "previewnote": "'''Тиде ончылгоч ончымаш гына;\nвашталтыш-влакым эше аралыме огыл!'''",
        "group-bot-member": "бот",
        "grouppage-bot": "{{ns:project}}:Бот-влак",
        "grouppage-sysop": "{{ns:project}}:Сайтвиктарыше-влак",
+       "right-writeapi": "Возымашлан API-ым кучылтмаш",
        "newuserlogpage": "У пайдаланыше регистрацийым эртарыме журнал",
        "rightslog": "Участникын праваже-влакым ончыктышо журнал",
        "action-edit": "тиде лаштыкым тӧрлаташ",
        "minoreditletter": "и",
        "newpageletter": "У",
        "boteditletter": "б",
+       "rc-change-size-new": "Вашталтымаш деч вара $1 {{PLURAL:$1|байт}} лийын",
        "rc-enhanced-expand": "Тичмашын ончыкташ",
        "rc-enhanced-hide": "Рашлык-влакым шылташ",
        "recentchangeslinked": "Ваш кылдалтше тӧрлатымаш-влак",
        "uploadlogpage": "Оптымаш-влак журнал",
        "filedesc": "Файл нерген кӱчыкын увертараш",
        "fileuploadsummary": "Тидын нерген кӱчыкын:",
+       "savefile": "Файлым арален кодаш",
        "watchthisupload": "Тиде файлым эскераш",
        "license-header": "Лицензирований",
        "imgfile": "файл",
        "file-nohires": "Кугурак чаплык уке.",
        "svg-long-desc": "SVG файл, шкенжын кугытшо: $1 × $2 пиксел, файлын кугытшо: $3",
        "show-big-image": "Тӱҥалтыш файл",
+       "show-big-image-preview": "Ончылгоч ончымо годым кугыт: $1",
        "show-big-image-size": "$1 × $2 пиксел",
        "newimages-legend": "Фильтр",
        "ilsubmit": "Кычал",
        "specialpages-group-pagetools": "Лаштык ӱзгар-влак",
        "specialpages-group-redirects": "Вес вере колтышо спецлаштык-влак",
        "external_image_whitelist": " #Оставьте эту строчку такой, как она есть<pre>\n#Разместите здесь фрагменты регулярных выражений (ту часть, что находится между //)\n#они будут соотнесены с URL внешних изображений.\n#Подходящие будут показаны как изображения, остальные будут показаны как ссылки на изображения.\n#Строки, начинающиеся с # считаются комментариями.\n#Строки не чувствительны к регистру\n\n#Размещайте фрагменты регулярных выражений над этой строчкой. Оставьте эту строчку такой, как она есть.</pre>",
+       "tag-filter": "[[Special:Tags|Метке]] фильтр:",
        "logentry-delete-delete": "$1 {{GENDER:$2|шӧрен|шӧрен}} лаштыкым $3",
+       "logentry-newusers-create": "Пайдаланыше {{GENDER:$2}} $1 лаштыкым ыштен.",
        "revdelete-summary": "тӧрлатымаш-влакым возен ончыктымаш",
-       "searchsuggest-search": "{{SITENAME}} сайтым кычалаш",
+       "searchsuggest-search": "{{SITENAME}} сайтыште кычалаш",
        "expand_templates_ok": "Йӧра",
        "expand_templates_preview": "Ончылгоч ончымаш"
 }
index dd0f45a..4872f4a 100644 (file)
@@ -19,7 +19,8 @@
                        "Macofe",
                        "Nemo bis",
                        "Matma Rex",
-                       "Kaldari"
+                       "Kaldari",
+                       "Xð"
                ]
        },
        "tog-underline": "Потцртување на врски:",
        "unprotectthispage": "Измена на заштитата на страницава",
        "newpage": "Нова страница",
        "talkpage": "Разговор",
-       "talkpagelinktext": "Разговор",
+       "talkpagelinktext": "разговор",
        "specialpage": "Службена страница",
        "personaltools": "Лични алатки",
        "articlepage": "Преглед на содржината",
        "eauthentsent": "На назначената адреса е испратена потврдна порака.\nПред да се испрати друга порака на корисничката сметка, ќе морате да ги проследите напатствијата во пораката, за да потврдите дека таа корисничка сметка е навистина ваша.",
        "throttled-mailpassword": "Веќе е испратена порака за измена на лозинката во {{PLURAL:$1|изминатиов час|изминативе $1 часа}}.\nЗа да се спречи злоупотреба, само едно потсетување може да се праќа на {{PLURAL:$1|секој час|секои $1 часа}}.",
        "mailerror": "Грешка при испраќање на е-поштата: $1",
-       "acct_creation_throttle_hit": "Посетители на ова вики користејќи ја вашата IP-адреса создале {{PLURAL:$1|1 сметка|$1 сметки}} во последниве $2, при што е достигнат најголемиот допуштен број на кориснички сметки предвиден и овозможен за овој период.\nКако резултат на ова, посетителите кои ја користат оваа IP-адреса во моментов нема да можат да создаваат нови сметки.",
+       "acct_creation_throttle_hit": "Посетители на ова вики користејќи ја вашата IP-адреса создале {{PLURAL:$1|1 сметка|$1 сметки}} во последниве $2, при што е достигнат најголемиот допуштен број на кориснички сметки предвиден и овозможен за овој период.\nКако последица на ова, посетителите кои ја користат оваа IP-адреса во моментов нема да можат да создаваат нови сметки.",
        "emailauthenticated": "Вашата е-пошта адреса е потврдена на $2 во $3 ч.",
        "emailnotauthenticated": "Вашата е-поштенска адреса сè уште не е потврдена.\nНема да биде испратена е-пошта во ниту еден од следниве случаи.",
        "noemailprefs": "Наведете е-поштенска адреса за да функционираат следниве својства.",
        "nextn": "{{PLURAL:следна $1|следни $1}}",
        "prev-page": "претходна страница",
        "next-page": "следна страница",
-       "prevn-title": "{{PLURAL:$1|Ð\9fÑ\80еÑ\82Ñ\85оден|Ð\9fÑ\80еÑ\82Ñ\85одни}} $1 {{PLURAL:$1|Ñ\80езÑ\83лÑ\82аÑ\82\80езÑ\83лÑ\82аÑ\82и}}",
-       "nextn-title": "{{PLURAL:$1|Следен|Следни}} $1 {{PLURAL:$1|Ñ\80езÑ\83лÑ\82аÑ\82\80езÑ\83лÑ\82аÑ\82и}}",
-       "shown-title": "Ð\9fÑ\80икажи $1 {{PLURAL:$1|Ñ\80езÑ\83лÑ\82аÑ\82\80езÑ\83лÑ\82аÑ\82и}} Ð½Ð° страница",
+       "prevn-title": "{{PLURAL:$1|Ð\9fÑ\80еÑ\82Ñ\85одна|Ð\9fÑ\80еÑ\82Ñ\85одни}} $1 {{PLURAL:$1|Ñ\81Ñ\82авка|Ñ\81Ñ\82авки}}",
+       "nextn-title": "{{PLURAL:$1|Следна|Следни}} $1 {{PLURAL:$1|Ñ\81Ñ\82авка|Ñ\81Ñ\82авки}}",
+       "shown-title": "Ð\9fÑ\80икажи $1 {{PLURAL:$1|Ñ\81Ñ\82авка|Ñ\81Ñ\82авки}} Ð¿Ð¾ страница",
        "viewprevnext": "Погледајте ($1 {{int:pipe-separator}} $2) ($3).",
        "searchmenu-exists": "'''На ова вики има страница со наслов „[[:$1]]“'''",
        "searchmenu-new": "<strong>Создајте ја страницата „[[:$1]]“ на ова вики!</strong> {{PLURAL:$2|0=|Погледајте ја и страницата најдена со пребарувањето.|Погледајте го и најденото од пребарувањето.}}",
        "search-relatedarticle": "Поврзано",
        "searchrelated": "поврзано",
        "searchall": "сè",
-       "showingresults": "Подолу {{PLURAL:$1|е прикажан '''1''' резултат|се прикажани '''$1''' резултати}} почнувајќи од бр. '''$2'''.",
-       "showingresultsinrange": "Ð\94олÑ\83 {{PLURAL:$1|е Ð¿Ñ\80икажан Ð´Ð¾ <strong>еден</strong> Ñ\80езÑ\83лÑ\82аÑ\82\81е Ð¿Ñ\80икажани Ð´Ð¾ <strong>$1</strong> Ñ\80езÑ\83лÑ\82аÑ\82и}} во опсег од <strong>$2</strong> до <strong>$3</strong>.",
-       "search-showingresults": "{{PLURAL:$4|РезÑ\83лÑ\82аÑ\82 <strong>$1</strong> Ð¾Ð´ <strong>$3</strong>|РезÑ\83лÑ\82аÑ\82и <strong>$1 - $2</strong> од <strong>$3</strong>}}",
-       "search-nonefound": "Нема резултати што одговараат на бараното.",
-       "search-nonefound-thiswiki": "Ð\9dема Ñ\80езÑ\83лÑ\82аÑ\82и што одговараат на бараното на ова мрежно место.",
+       "showingresults": "Подолу {{PLURAL:$1|е прикажана <strong>1</strong> ставка|се прикажани <strong>$1</strong> ставки}} почнувајќи од бр. <strong>$2</strong>.",
+       "showingresultsinrange": "Ð\9fодолÑ\83 {{PLURAL:$1|е Ð¿Ñ\80икажана Ð´Ð¾ <strong>една</strong> Ñ\81Ñ\82авка|Ñ\81е Ð¿Ñ\80икажани Ð´Ð¾ <strong>$1</strong> Ñ\81Ñ\82авки}} во опсег од <strong>$2</strong> до <strong>$3</strong>.",
+       "search-showingresults": "{{PLURAL:$4|СÑ\82авка <strong>$1</strong> Ð¾Ð´ <strong>$3</strong>|СÑ\82авки <strong>$1 - $2</strong> од <strong>$3</strong>}}",
+       "search-nonefound": "Нема исходни ставки што одговараат на бараното.",
+       "search-nonefound-thiswiki": "Ð\9dема Ñ\81Ñ\82авки што одговараат на бараното на ова мрежно место.",
        "powersearch-legend": "Напредно пребарување",
        "powersearch-ns": "Пребарај во следниве именски простори:",
        "powersearch-togglelabel": "Избор:",
        "rcfilters-invalid-filter": "Неважечки филтер",
        "rcfilters-empty-filter": "Нема активни филтри. Прикажани се сите придонеси.",
        "rcfilters-filterlist-title": "Филтри",
+       "rcfilters-filterlist-feedbacklink": "Дајте мислење за новите (бета) филтри",
        "rcfilters-highlightbutton-title": "Истакнување на исход",
        "rcfilters-highlightmenu-title": "Изберете боја",
        "rcfilters-filterlist-noresults": "Не пронајдов ниеден филтер",
        "wantedcategories": "Потребни категории",
        "wantedpages": "Потребни страници",
        "wantedpages-summary": "Список на непостоечки страници со највеќе врски што водат до нив, исклучувајќи страниците до кои водат само пренасочувања. Список на непостоечки страници до кои водат пренасочувања ќе најдете на [[{{#special:BrokenRedirects}}|списокот на прекинати пренасочувања]].",
-       "wantedpages-badtitle": "Ð\9dевалиден Ð½Ð°Ñ\81лов Ð²Ð¾ Ñ\80езÑ\83лÑ\82аÑ\82ите: $1",
+       "wantedpages-badtitle": "Ð\9dеважеÑ\87ки Ð½Ð°Ñ\81лов Ð²Ð¾ Ñ\81Ñ\82авките: $1",
        "wantedfiles": "Потребни податотеки",
        "wantedfiletext-cat": "Следниве податотеки се користат, но не постојат. Податотеките од други складишта може да се наведени дури и ако постојат. Таквите ќе бидат <del>поништени</del> од списокот. Покрај ова, страниците што содржат податотеки кои не постојат се наведени на [[:$1]].",
        "wantedfiletext-cat-noforeign": "Следниве податотеки се користат, но не постојат. Покрај ова, страниците што ги содржат непостоечките податотеки се наведени во [[:$1]].",
        "feedback-external-bug-report-button": "Поднеси техничка задача",
        "feedback-dialog-title": "Поднеси мислење",
        "feedback-dialog-intro": "Послужете се со едноставниот образец подолу за да го поднесете вашето мислење. Коментарот ќе ви биде додаден на страницата „$1“, заедно со вашето корисничко име.",
-       "feedback-error1": "Грешка: Непрепознаен резултат од извршникот",
+       "feedback-error1": "Грешка: Непрепознаен исход од извршникот",
        "feedback-error2": "Грешка: Уредувањето не успеа",
        "feedback-error3": "Грешка: Извршникот не одговара",
        "feedback-error4": "Грешка: Не можам да објавам под дадениот наслов",
        "expand_templates_html_output": "Сиров HTML-извод",
        "expand_templates_ok": "ОК",
        "expand_templates_remove_comments": "Отстрани коментари",
-       "expand_templates_remove_nowiki": "Притаи <nowiki> ознаки во резултатот",
+       "expand_templates_remove_nowiki": "Притаи <nowiki> ознаки во исходот",
        "expand_templates_generate_xml": "Прикажи XML-дрво на расчленувањето",
        "expand_templates_generate_rawhtml": "Прикажувај сиров HTML",
        "expand_templates_preview": "Преглед",
index 15125c6..445a36e 100644 (file)
        "rcfilters-invalid-filter": "Ugyldig filter",
        "rcfilters-empty-filter": "Ingen aktive filtre. Alle bidrag vises.",
        "rcfilters-filterlist-title": "Filtre",
+       "rcfilters-filterlist-feedbacklink": "Gi tilbakemelding på de nye (beta)filtrene",
+       "rcfilters-highlightbutton-title": "Marker resultater",
+       "rcfilters-highlightmenu-title": "Velg en farge",
        "rcfilters-filterlist-noresults": "Ingen filtre funnet",
        "rcfilters-filtergroup-registration": "Brukerregistrering",
        "rcfilters-filter-registered-label": "Registrerte",
        "editcomment": "Redigeringskommentaren var: <em>$1</em>",
        "revertpage": "Tilbakestilte endringer av [[Special:Contributions/$2|$2]] ([[User talk:$2|brukerdiskusjon]]) til siste versjon av [[User:$1|$1]]",
        "revertpage-nouser": "Tilbakestilt endringer av skjult bruker til siste versjon av\n{{GENDER:$1|[[User:$1|$1]]}}",
-       "rollback-success": "Tilbakestilte endringer av $1; endret til siste versjon av $2.",
+       "rollback-success": "Tilbakestilte endringer av {{GENDER:$3|$1}}; endret til siste versjon av {{GENDER:$4|$2}}.",
        "rollback-success-notify": "Tilbakestilte endringer av $1;\nendret tilbake til siste revisjon av $2. [$3 Vis endringer]",
        "sessionfailure-title": "Sesjonsfeil",
        "sessionfailure": "Det ser ut til å være et problem med innloggingen din, og den ble avbrutt av sikkerhetshensyn. Trykk ''Tilbake'' i nettleseren din, oppdater siden og prøv igjen.",
index fd5ac54..ea443c5 100644 (file)
        "rcfilters-invalid-filter": "Ongeldig filter",
        "rcfilters-empty-filter": "Geen actieve filters. Alle bijdragen worden weergeven.",
        "rcfilters-filterlist-title": "Filters",
+       "rcfilters-filterlist-feedbacklink": "Geef feedback op de nieuwe (beta) filters",
        "rcfilters-highlightbutton-title": "Resultaten markeren",
        "rcfilters-highlightmenu-title": "Kies een kleur",
        "rcfilters-filterlist-noresults": "Geen filters gevonden",
index bfba48c..2f90dc6 100644 (file)
        "lineno": "Line $1:",
        "compareselectedversions": "Samanlikn valde versjonar",
        "showhideselectedversions": "Vis/løyn valde versjonar",
-       "editundo": "angre",
+       "editundo": "fjern endringa",
        "diff-empty": "(Ingen skilnad)",
        "diff-multi-sameuser": "({{PLURAL:$1|Éin mellomversjon|$1 mellomversjonar}} av den same brukaren er ikkje {{PLURAL:$1|vist|viste}})",
        "diff-multi-otherusers": "({{PLURAL:$1|Éin mellomliggjande versjon|$1 mellomliggjande versjonar}} av {{PLURAL:$2|éin annan brukar|$2 brukarar}} er ikkje {{PLURAL:$1|vist|viste}})",
        "listfiles-delete": "slett",
        "listfiles-summary": "Spesialsida viser alle opplasta filer.\nNår ho er filtrert etter brukar, vert berre filene der brukaren lasta opp den siste versjonen viste.",
        "listfiles_search_for": "Søk etter filnamn:",
+       "listfiles-userdoesnotexist": "Brukarkontoen «$1» er ikkje oppretta.",
        "imgfile": "fil",
        "listfiles": "Filliste",
        "listfiles_thumb": "Miniatyrbilete",
        "mycontris": "Bidrag",
        "anoncontribs": "Bidrag",
        "contribsub2": "For {{GENDER:$3|$1}} ($2)",
+       "contributions-userdoesnotexist": "Brukarkontoen «$1» er ikkje oppretta.",
        "nocontribs": "Det vart ikkje funne nokon endringar gjorde av denne brukaren.",
        "uctop": "(gjeldande)",
        "month": "Månad:",
        "mw-widgets-titleinput-description-new-page": "sida finst ikkje enno",
        "mw-widgets-titleinput-description-redirect": "omdiriger til $1",
        "randomrootpage": "Tilfeldig rotsida",
+       "authmanager-userdoesnotexist": "Brukarkontoen «$1» er ikkje oppretta.",
        "userjsispublic": "Merk: JavaScript-undersider bør ikkje innehalda konfidensielle data sidan dei er synlege for andre brukarar.",
        "usercssispublic": "Merk: CSS-undersider bør ikkje innehalda konfidensielle data sidan dei er synlege for andre brukarar."
 }
index 3cfbe34..1c27d45 100644 (file)
        "undo-failure": "Aquesta modificacion a pas pogut èsser desfaita a causa de conflictes amb de modificacions intermediàrias.",
        "undo-norev": "La modificacion a pas pogut èsser desfaita perque siá es inexistenta siá es estada suprimida.",
        "undo-nochange": "Sembla que la modificacion es ja estada anullada.",
-       "undo-summary": "Anullacion de las modificacions $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|discutir]] | [[Special:Contributions/$2|{{MediaWiki:Contribslink}}]])",
+       "undo-summary": "Anullacion de las modificacions $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|discussion]])",
        "undo-summary-username-hidden": "Anullar la revision $1 per un utilizaire amagat",
        "cantcreateaccount-text": "La creacion de compte dempuèi aquesta adreça IP ('''$1''') es estada blocada per [[User:$3|$3]].\n\nLa rason balhada per $3 èra ''$2''.",
        "cantcreateaccount-range-text": "La creacion de compte dempuèi las adreças IP dins la plaja <strong>$1</strong>, que compren vòstra agreça IP (<strong>$4</strong>) son estadas blocadas per [[User:$3|$3]].\n\nLo motiu provesit per $3 es <em>$2</em>",
index ef7be20..9d164db 100644 (file)
        "rcfilters-invalid-filter": "Nieprawidłowy filtr",
        "rcfilters-empty-filter": "Brak aktywnych filtrów. Wyświetlane są wszystkie zmiany.",
        "rcfilters-filterlist-title": "Filtry",
+       "rcfilters-filterlist-feedbacklink": "Podziel się swoją opinią na temat tych nowych (beta) filtrów",
+       "rcfilters-highlightbutton-title": "Podświetl wyniki",
        "rcfilters-highlightmenu-title": "Wybierz kolor",
        "rcfilters-filterlist-noresults": "Nie znaleziono filtrów",
        "rcfilters-filtergroup-registration": "Rejestracja użytkownika",
-       "rcfilters-filter-registered-label": "Zarejestrowany",
+       "rcfilters-filter-registered-label": "Zarejestrowani",
        "rcfilters-filter-registered-description": "Zalogowani edytorzy.",
-       "rcfilters-filter-unregistered-label": "Niezarejestrowany",
+       "rcfilters-filter-unregistered-label": "Niezarejestrowani",
        "rcfilters-filter-unregistered-description": "Niezalogowani",
        "rcfilters-filtergroup-authorship": "Autorstwo edycji",
        "rcfilters-filter-editsbyself-label": "Moje edycje",
        "rcfilters-filter-pageedits-label": "Edycje strony",
        "rcfilters-filter-pageedits-description": "Edycje treści, stron dyskusji, opisów kategorii...",
        "rcfilters-filter-newpages-label": "Tworzenie stron",
-       "rcfilters-filter-newpages-description": "Zmiany, prowadzące do utworzenia nowych stron.",
+       "rcfilters-filter-newpages-description": "Zmiany prowadzące do utworzenia nowych stron.",
        "rcfilters-filter-categorization-label": "Zmiany kategorii",
        "rcfilters-filter-categorization-description": "Dodanie lub usunięcie strony z kategorii",
        "rcfilters-filter-logactions-label": "Działania rejestrowane",
index 69f8df1..2250b88 100644 (file)
        "selfredirect": "<strong>Aviso:</strong> Você esta redirecionando esta pagina para ela mesmo. Você pode ter especificado o caminho errado para redirecionar, ou você pode estar editando a pagina errada. Se você clicar \"{{int:savearticle}}\" novamente, o redirecionamento será criado de qualquer modo.",
        "missingcommenttext": "Por favor, introduzida um comentário abaixo.",
        "missingcommentheader": "'''Lembrete:''' Você não introduziu um assunto/título para este comentário.\nSe você clicar novamente \"{{int:savearticle}}\", a sua edição será salva sem um assunto/título.",
-       "summary-preview": "Previsão do resumo:",
+       "summary-preview": "Previsão do resumo de edição:",
        "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",
        "rcfilters-invalid-filter": "Filtro inválido",
        "rcfilters-empty-filter": "Nenhum filtro ativo. Todas as contribuições são mostradas.",
        "rcfilters-filterlist-title": "Filtros",
+       "rcfilters-filterlist-feedbacklink": "Forneça feedback sobre os novos filtros (beta)",
+       "rcfilters-highlightbutton-title": "Realçar os resultados",
+       "rcfilters-highlightmenu-title": "Selecione uma cor",
        "rcfilters-filterlist-noresults": "Nenhum filtro encontrado",
        "rcfilters-filtergroup-registration": "Registro de usuário",
        "rcfilters-filter-registered-label": "Registrado",
index 0ed8589..1a87f50 100644 (file)
        "rcfilters-invalid-filter": "Filtro inválido",
        "rcfilters-empty-filter": "Não há filtros ativos. São mostradas todas as contribuições.",
        "rcfilters-filterlist-title": "Filtros",
+       "rcfilters-filterlist-feedbacklink": "Dê-nos a sua opinião sobre os novos filtros (beta)",
+       "rcfilters-highlightbutton-title": "Realçar resultados",
+       "rcfilters-highlightmenu-title": "Selecionar uma cor",
        "rcfilters-filterlist-noresults": "Não foram encontrados filtros",
        "rcfilters-filtergroup-registration": "Registo de utilizador",
        "rcfilters-filter-registered-label": "Registado",
        "editcomment": "O resumo da edição era: <em$1</em>.",
        "revertpage": "Foram revertidas as edições de [[Special:Contributions/$2|$2]] ([[User talk:$2|disc]]) para a última revisão de [[User:$1|$1]]",
        "revertpage-nouser": "Foram revertidas as edições de um utilizador oculto para a última revisão de {{GENDER:$1|[[User:$1|$1]]}}",
-       "rollback-success": "Foram revertidas as edições de $1, com o conteúdo passando a estar como na última edição de $2.",
+       "rollback-success": "Foram revertidas as edições de {{GENDER:$3|$1}}; reposta a última edição de {{GENDER:$4|$2}}.",
        "rollback-success-notify": "Revertidas as edições de $1;\nMudança para a última revisão de $2. [$3 Mostrar alterações]",
        "sessionfailure-title": "Erro de sessão",
        "sessionfailure": "Foram detectados problemas com a sua sessão;\na operação foi cancelada como medida de proteção contra a interceptação de sessões.\nVolte à página anterior, recarregue-a e tente novamente.",
index 7665f80..a3e2a8c 100644 (file)
                        "Chaduvari",
                        "MarcoAurelio",
                        "Joao Xavier",
-                       "Winstonyin"
+                       "Winstonyin",
+                       "Jhertel"
                ]
        },
        "sidebar": "{{notranslate}}",
        "search": "{{doc-special|Search}}\nNoun. Text of menu section shown on every page of the wiki above the search form.\n\nSee also:\n* {{msg-mw|Search}}\n* {{msg-mw|Accesskey-search}}\n* {{msg-mw|Tooltip-search}}\n{{Identical|Search}}",
        "search-ignored-headings": "Headings that will be ignored by search. You can translate the text, including \"Leave this line exactly as it is\". Some lines of this messages have one (1) leading space.",
        "searchbutton": "The button you can see in the sidebar, below the search input box. The \"Go\" button is {{msg-mw|Searcharticle}}.\n{{Identical|Search}}",
-       "go": "See also:\n* {{msg-mw|Go}}\n* {{msg-mw|Accesskey-search-go}}\n* {{msg-mw|Tooltip-search-go}}\n{{Identical|Go}}",
+       "go": "Appears next to the search button. Goes directly to the page with that name, if it exists.\n\nSee also:\n* {{msg-mw|Go}}\n* {{msg-mw|Accesskey-search-go}}\n* {{msg-mw|Tooltip-search-go}}\n{{Identical|Go}}",
        "searcharticle": "Button description in the search menu displayed on every page. The \"Search\" button is {{msg-mw|Searchbutton}}.\n{{Identical|Go}}",
        "history": "{{Identical|Page history}}",
        "history_short": "Text used on the history tab.\n\n{{Identical|History}}",
        "databaseerror-query": "Identifies, in the list of technical details, the [[wikipedia:SQL|SQL]] statement that failed.\nParameters:\n* $1 - SQL statement (shown within a box)\n{{Identical|Query}}",
        "databaseerror-function": "Identifies, in the list of technical details, the function that tried to execute the database query.\nParameters:\n* $1 - Name of function\n{{Identical|Function}}",
        "databaseerror-error": "Identifies, in the list of technical details, the error message the database server returned.\nParameters:\n* $1 - Error message from the database server, probably in English\n{{Identical|Error}}",
-       "transaction-duration-limit-exceeded": "Plain text error shown when DB updates take too long. Parameters:\n* $1 - time spent in database updates\n* $2 - maximum time allowed in database updates",
+       "transaction-duration-limit-exceeded": "Plain text error shown when DB updates take too long. Parameters:\n* $1 - time spent in database updates\n* $2 - maximum number of seconds allowed in database updates",
        "laggedslavemode": "Used as warning when getting the timestamp of the latest version, if in LaggedSlaveMode.",
        "readonly": "Used as title of error message when database is locked.",
        "enterlockreason": "For developers when locking the database",
        "rcfilters-invalid-filter": "A label for an invalid filter.",
        "rcfilters-empty-filter": "Placeholder for the filter list when no filters were chosen.",
        "rcfilters-filterlist-title": "Title for the filters list.\n{{Identical|Filter}}",
+       "rcfilters-filterlist-feedbacklink": "Caption for the link to the feedback page about the filters beta feature.",
        "rcfilters-highlightbutton-title": "Title for the highlight button used to toggle the highlight feature on and off.",
        "rcfilters-highlightmenu-title": "Title for the highlight menu used to select the highlight color for an individual filter.",
+       "rcfilters-highlightmenu-help": "Tooltip for the highlight menu for individual filters.",
        "rcfilters-filterlist-noresults": "Message showing no results found for searching a filter.",
        "rcfilters-filtergroup-registration": "Title for the filter group for editor registration type.",
        "rcfilters-filter-registered-label": "Label for the filter for showing edits made by logged-in users.\n{{Identical|Registered}}",
index bfb370f..46805f8 100644 (file)
                        "Аль-Гимравий",
                        "Gamliel Fishkin",
                        "Ping08",
-                       "Yuryleb"
+                       "Yuryleb",
+                       "Redredsonia"
                ]
        },
        "tog-underline": "Подчёркивание ссылок:",
        "broken-file-category": "Страницы с неработающими файловыми ссылками",
        "about": "Описание",
        "article": "Статья",
-       "newwindow": "&nbsp;(в новом окне)",
+       "newwindow": "(в новом окне)",
        "cancel": "Отменить",
        "moredotdotdot": "Далее…",
        "morenotlisted": "Этот список может быть неполным.",
        "missing-revision": "Версия $1 страницы «{{FULLPAGENAME}}» не существует.\n\nЭто обычно бывает, если последовать по устаревшей ссылке на страницу, которая была удалена.\nПодробности могут быть в [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} журнале удалений].",
        "userpage-userdoesnotexist": "Учётной записи «<nowiki>$1</nowiki>» не существует. Убедитесь, что вы действительно желаете создать или изменить эту страницу.",
        "userpage-userdoesnotexist-view": "Не зарегистрировано учётной записи «$1».",
-       "blocked-notice-logextract": "Этот участник в данный момент заблокирован.\nНиже приведена последняя запись из журнала блокировок:",
+       "blocked-notice-logextract": "{{GENDER:$1|Этот участник|Эта участница}} в данный момент {{GENDER:$1|заблокирован|заблокирована}}.\nНиже приведена последняя запись из журнала блокировок:",
        "clearyourcache": "<strong>Замечание.</strong> Возможно, после сохранения вам придётся очистить кэш своего браузера, чтобы увидеть изменения.\n* <strong>Firefox / Safari:</strong> Удерживая клавишу <em>Shift</em>, нажмите на панели инструментов <em>Обновить</em> либо нажмите <em>Ctrl-F5</em> или <em>Ctrl-R</em> (<em>⌘-R</em> на Mac)\n* <strong>Google Chrome:</strong> Нажмите <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> на Mac)\n* <strong>Internet Explorer:</strong> Удерживая <em>Ctrl</em>, нажмите <em>Обновить</em> либо нажмите <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Перейдите в <em>Menu → Настройки</em> (<em>Opera → Настройки</em> на Mac), а затем <em>Безопасность → Очистить историю посещений → Кэшированные изображения и файлы</em>",
        "usercssyoucanpreview": "'''Подсказка.''' Нажмите кнопку «{{int:showpreview}}», чтобы проверить свой новый CSS-файл перед сохранением.",
        "userjsyoucanpreview": "'''Подсказка.''' Нажмите кнопку «{{int:showpreview}}», чтобы проверить свой новый JS-файл перед сохранением.",
        "saveusergroups": "Сохранить группы {{GENDER:$1|участника|участницы}}",
        "userrights-groupsmember": "Состоит в группах:",
        "userrights-groupsmember-auto": "Неявно состоит в группах:",
-       "userrights-groups-help": "Вы можете изменить группы, в которые входит этот участник.\n* Если около названия группы стоит отметка — участник входит в эту группу.\n* Если отметка не стоит — участник не входит в эту группу.\n* Символ * указывает на то, что вы не сможете удалить участника из группы, если добавите его в неё (или наоборот).\n* Символ # указывает на то, что вы можете только отложить время истечения этой группы, вы не можете перенести его на более ранний срок.",
+       "userrights-groups-help": "Вы можете изменить группы, в которые входит {{GENDER:$1|этот участник|эта участница}}.\n* Если около названия группы стоит отметка — {{GENDER:$1|участник|участница}} входит в эту группу.\n* Если отметка не стоит — {{GENDER:$1|участник|участница}} не входит в эту группу.\n* Символ * указывает на то, что вы не сможете удалить {{GENDER:$1|участника|участницу}} из группы, если добавите {{GENDER:$1|его|её}} в неё (или наоборот).\n* Символ # указывает на то, что вы можете только отложить время истечения этой группы, вы не можете перенести его на более ранний срок.",
        "userrights-reason": "Причина:",
        "userrights-no-interwiki": "У вас нет разрешения изменять права участников в других вики.",
        "userrights-nodatabase": "База данных $1 не существует или расположена не локально.",
        "rcfilters-invalid-filter": "Недопустимый фильтр",
        "rcfilters-empty-filter": "Нет активных фильтров. Показываются все правки.",
        "rcfilters-filterlist-title": "Фильтры",
+       "rcfilters-filterlist-feedbacklink": "Оставить отзыв о новых (бета) фильтрах",
        "rcfilters-highlightbutton-title": "Выделить результаты",
        "rcfilters-highlightmenu-title": "Выберите цвет",
        "rcfilters-filterlist-noresults": "Фильтры не найдены",
index 24f7622..7c1f625 100644 (file)
        "feedback-subject": "Предмет:",
        "feedback-submit": "Одослати",
        "feedback-thanks": "Дякуєме! Ваш коментарь быв приданый на сторінку „[$2 $1]“.",
-       "searchsuggest-search": "Глядати",
+       "searchsuggest-search": "Глядати {{SITENAME}}",
        "searchsuggest-containing": "обсягуючій...",
        "api-error-badtoken": "Внутрїшня хыба: планый знак.",
        "api-error-emptypage": "Створїня новых, порожнїх сторінк неслободно.",
index 233839f..eea4a6a 100644 (file)
@@ -12,7 +12,8 @@
                        "KWiki",
                        "Matma Rex",
                        "Srdjan m",
-                       "Conquistador"
+                       "Conquistador",
+                       "Xð"
                ]
        },
        "tog-underline": "Podvuci linkove:",
        "unprotectthispage": "Promijeni zaštitu za ovu stranicu",
        "newpage": "Nova stranica / Нова страница",
        "talkpage": "Razgovaraj o ovoj stranici - Разговарај о овој страници",
-       "talkpagelinktext": "Razgovor",
+       "talkpagelinktext": "razgovor",
        "specialpage": "Posebna stranica",
        "personaltools": "Lični alati",
        "articlepage": "Vidi stranicu sadržaja",
        "internalerror_info": "Interna greška: $1",
        "internalerror-fatal-exception": "Fatalna greška tipa \"$1\"",
        "filecopyerror": "Ne može se kopirati \"$1\" na \"$2\".",
-       "filerenameerror": "Ne može se promjeniti ime datoteke \"$1\" u \"$2\".",
+       "filerenameerror": "Ne mogu preimenovati datoteku \"$1\" u \"$2\".",
        "filedeleteerror": "Ne može se izbrisati datoteka \"$1\".",
        "directorycreateerror": "Nije moguće napraviti direktorijum \"$1\".",
        "directoryreadonlyerror": "Direktorij \"$1\" je samo za čitanje.",
index c54d38e..13fa595 100644 (file)
        "sp-contributions-search": "දායකත්ව පිළිබඳ ගවේෂණය කරන්න",
        "sp-contributions-username": "පරිශීලක නාමය හෝ IP ලිපිනය:",
        "sp-contributions-toponly": "නවතම අනුවාදයන් වන සංස්කරණයන් පමණක් පෙන්වයි",
+       "sp-contributions-newonly": "පිටු නිර්මාණය කිරීම් වන සංස්කරණ පමණක් පෙන්වන්න",
        "sp-contributions-submit": "සොයන්න",
        "whatlinkshere": "මෙතනට සබැඳෙන්නේ කුමක්ද",
        "whatlinkshere-title": "\"$1\" වෙත සබැ‍ඳෙන පිටු",
index c8103b6..e16e746 100644 (file)
@@ -34,7 +34,8 @@
                        "Mikulas1",
                        "Hromoslav",
                        "Matma Rex",
-                       "LacoR"
+                       "LacoR",
+                       "Xð"
                ]
        },
        "tog-underline": "Podčiarkovať odkazy:",
        "unprotectthispage": "Zmeniť stav ochrany tejto stránky",
        "newpage": "Nová stránka",
        "talkpage": "Diskusia k stránke",
-       "talkpagelinktext": "Diskusia",
+       "talkpagelinktext": "diskusia",
        "specialpage": "Špeciálna stránka",
        "personaltools": "Osobné nástroje",
        "articlepage": "Zobraziť stránku",
        "saveprefs": "Uložiť nastavenia",
        "restoreprefs": "Obnoviť všetky predvolené nastavenia (vo všetkých sekciách)",
        "prefs-editing": "Úpravy",
-       "rows": "Riadky:",
-       "columns": "Stĺpce:",
        "searchresultshead": "Vyhľadávanie",
        "stub-threshold": "Prah formátovania odkazu ako výhonok ($1):",
        "stub-threshold-sample-link": "príklad",
        "feedback-useragent": "Prehliadač:",
        "searchsuggest-search": "Hľadať",
        "searchsuggest-containing": "obsahuje...",
-       "api-error-autoblocked": "Vaše IP adresa bola automaticky zablokovaná, pretože ju používal zablokovaný používateľ.",
-       "api-error-badaccess-groups": "Nemáte oprávnenie nahrávať súbory na tejto wiki.",
        "api-error-badtoken": "Vnútorná chyba: Zlý token.",
-       "api-error-blocked": "Možnosť editovať vám bola zablokovaná.",
-       "api-error-copyuploaddisabled": "Nahrávanie z URL je na tomto serveri zakázané.",
-       "api-error-duplicate": "{{PLURAL:$1|ďalší súbor|ďalšie súbory}} s rovnakým obsahom už na tejto wiki existujú",
-       "api-error-duplicate-archive": "{{PLURAL:$1|ďalší súbor|ďalšie súbory}} s rovnakým obsahom už na tejto wiki existoval, ale {{PLURAL:$1|bol zmazaný|boli zmazané}}.",
-       "api-error-empty-file": "Súbor, ktorý ste poslali bol prázdny.",
        "api-error-emptypage": "Vytváranie nových, prázdnych stránok nie je dovolené.",
-       "api-error-fetchfileerror": "Vnútorná chyba: Niečo pokazilo počas sťahovania súboru.",
-       "api-error-fileexists-forbidden": "Súbor s názvom „$1“ už existuje a nie je možné prepísať ho.",
-       "api-error-fileexists-shared-forbidden": "Súbor s názvom „$1“ už neexistuje v repozitári zdieľaných súborov a nie je možné prepísať ho.",
-       "api-error-file-too-large": "Súbor, ktorý ste poslali bol príliš veľký.",
-       "api-error-filename-tooshort": "Názov súboru je príliš krátky.",
-       "api-error-filetype-banned": "Tento typ súboru je zakázaný.",
-       "api-error-filetype-banned-type": "$1 {{PLURAL:$4|nie je povolený typ súboru|nie sú povolené typy súboru}}. {{PLURAL:$3|Povolený typ súborov je|Povolené typy súborov sú}} $2.",
-       "api-error-filetype-missing": "Súboru chýba prípona.",
-       "api-error-hookaborted": "Zmena, ktorú ste sa pokúsili vykonať bola zrušená prípojným bodom rozšírenia.",
-       "api-error-http": "Vnútorná chyba: Nepodarilo sa pripojiť k serveru.",
-       "api-error-illegal-filename": "Názov súboru nie je povolený.",
-       "api-error-internal-error": "Vnútorná chyba: Niečo pokazilo pri spracovaní súboru, ktorý ste nahrávali na wiki.",
-       "api-error-invalid-file-key": "Vnútorná chyba: Súbor sa nenašiel v dočasnom úložisku.",
-       "api-error-missingparam": "Vnútorná chyba: Chýbajú parametre požiadavky.",
-       "api-error-missingresult": "Vnútorná chyba: Nepodarilo sa určiť, či kopírovanie prebehlo úspešne.",
-       "api-error-mustbeloggedin": "Aby ste mohli nahrávať súbory, musíte sa prihlásiť",
-       "api-error-mustbeposted": "Vnútorná chyba: Požiadavka vyžaduje HTTP POST.",
-       "api-error-noimageinfo": "Nahranie sa podarilo, ale server nám nedal žiadne informácie o súbore.",
-       "api-error-nomodule": "Vnútorná chyba: Nebol nastavený žiaden nahrávací modul.",
-       "api-error-ok-but-empty": "Vnútorná chyba: Žiadna odpoveď zo servera.",
-       "api-error-overwrite": "Prepísanie existujúceho súboru nie je povolené.",
-       "api-error-stashfailed": "Vnútorná chyba: Serveru sa nepodarilo uložiť dočasný súbor.",
        "api-error-publishfailed": "Vnútorná chyba: Serveru sa nepodarilo publikovať dočasný súbor.",
-       "api-error-timeout": "Server neodpovedal v očakávanom čase.",
-       "api-error-unclassified": "Vyskytla sa neznáma chyba.",
-       "api-error-unknown-code": "Neznáma chyba: „$1“",
-       "api-error-unknown-error": "Vnútorná chyba: Niečo pokazilo pri pokuse nahrať váš súbor.",
+       "api-error-stashfailed": "Vnútorná chyba: Serveru sa nepodarilo uložiť dočasný súbor.",
        "api-error-unknown-warning": "Neznáme upozornenie: $1",
        "api-error-unknownerror": "Neznáma chyba: „$1“",
-       "api-error-uploaddisabled": "Nahrávanie je na tejto wiki zakázané.",
-       "api-error-verification-error": "Tento súbor môže byť poškodený, alebo má zlú príponu.",
        "duration-seconds": "$1 {{PLURAL:$1|sekunda|sekundy|sekúnd}}",
        "duration-minutes": "$1 {{PLURAL:$1|minúta|minúty|minút}}",
        "duration-hours": "$1 {{PLURAL:$1|hodina|hodiny|hodín}}",
index 0718281..09e34ab 100644 (file)
@@ -13,7 +13,8 @@
                        "Skalcaa",
                        "Janezdrilc",
                        "Matma Rex",
-                       "NegativeTwelveDollars"
+                       "NegativeTwelveDollars",
+                       "Xð"
                ]
        },
        "tog-underline": "Podčrtavanje povezav:",
        "unprotectthispage": "Spremeni zaščito strani",
        "newpage": "Nova stran",
        "talkpage": "Pogovorite se o strani",
-       "talkpagelinktext": "Pogovor",
+       "talkpagelinktext": "pogovor",
        "specialpage": "Posebna stran",
        "personaltools": "Osebna orodja",
        "articlepage": "Prikaže članek",
        "rcfilters-invalid-filter": "Neveljaven filter",
        "rcfilters-empty-filter": "Ni dejavnih filtrov. Prikazani so vsi prispevki.",
        "rcfilters-filterlist-title": "Filtri",
+       "rcfilters-filterlist-feedbacklink": "Podajte povratne informacije o novih (preizkusnih) filtrih",
        "rcfilters-highlightbutton-title": "Označi rezultate",
        "rcfilters-highlightmenu-title": "Izberite barvo",
        "rcfilters-filterlist-noresults": "Nismo našli nobenega filtra",
index 12fc4fa..9078ecf 100644 (file)
        "virus-scanfailed": "неуспешно скенирање (код $1)",
        "virus-unknownscanner": "непознати антивирус:",
        "logouttext": "<strong>Одјављени сте.</strong>\n\nИмајте на уму да неке странице могу наставити да се приказују као да сте још пријављени, све док не очистите привремену меморију свог прегледача.",
+       "cannotlogoutnow-title": "Одјава тренутно није могућа",
+       "cannotlogoutnow-text": "Одјава није могућа током употребе $1.",
        "welcomeuser": "Добро дошли, $1!",
        "welcomecreation-msg": "Ваш налог је отворен.\nНе заборавите да промените своја [[Special:Preferences|подешавања]].",
        "yourname": "Корисничко име:",
        "changepassword-success": "Ваша лозинка је успешно промењена!",
        "changepassword-throttled": "Превише пута сте покушали да се пријавите.\nМолимо вас да сачекате $1 пре него што покушате поново.",
        "botpasswords": "Лозинке ботова",
+       "botpasswords-disabled": "Лозинке ботова су онемогућене.",
        "botpasswords-label-appid": "Име бота:",
        "botpasswords-label-create": "Направи",
        "botpasswords-label-update": "Ажурирај",
        "hr_tip": "Водоравна линија (користити ретко)",
        "summary": "Опис измене:",
        "subject": "Тема:",
-       "minoredit": "мања измена",
-       "watchthis": "надгледај ову страницу",
+       "minoredit": "Ð\9eво Ñ\98е Ð¼Ð°Ñ\9aа Ð¸Ð·Ð¼ÐµÐ½Ð°",
+       "watchthis": "Ð\9dадгледај ову страницу",
        "savearticle": "Сачувај страницу",
        "savechanges": "Сачувај измене",
        "publishpage": "Објави страницу",
        "difference-multipage": "(разлике између страница)",
        "lineno": "Ред $1:",
        "compareselectedversions": "Упореди изабране измене",
-       "showhideselectedversions": "Ð\9fÑ\80икажи/Ñ\81акÑ\80иÑ\98 Ð¸Ð·Ð°Ð±Ñ\80ане Ð¸Ð·Ð¼ÐµÐ½Ðµ",
+       "showhideselectedversions": "Ð\9fÑ\80омени Ð²Ð¸Ð´Ñ\99ивоÑ\81Ñ\82 Ð¸Ð·Ð°Ð±Ñ\80аниÑ\85 Ð¸Ð·Ð¼ÐµÐ½Ð°",
        "editundo": "поништи",
        "diff-empty": "(Нема разлике)",
        "diff-multi-sameuser": "({{PLURAL:$1|Једна међуизмена истог корисника није приказана|$1 међуизмене истог корисника није приказано|$1 међуизмена истог корисника није приказано}})",
        "powersearch-legend": "Напредна претрага",
        "powersearch-ns": "Тражи у следећим именским просторима:",
        "powersearch-togglelabel": "Изабери:",
-       "powersearch-toggleall": "све",
-       "powersearch-togglenone": "ништа",
+       "powersearch-toggleall": "Све",
+       "powersearch-togglenone": "Ð\9dишта",
        "powersearch-remember": "Запамти мој избор за будуће претраге",
        "search-external": "Спољна претрага",
        "searchdisabled": "Претрага је онемогућена.\nУ међувремену можете тражити преко Гугла.\nУпамтите да његови пописи овог викија могу бити застарели.",
        "saveusergroups": "Сачувај {{GENDER:$1|корисничке}} групе",
        "userrights-groupsmember": "Члан:",
        "userrights-groupsmember-auto": "Подразумевано члан и:",
-       "userrights-groups-help": "Можете променити групе којима овај корисник припада.\n* Означен квадратић означава да се корисник налази у тој групи.\n* Неозначен квадратић означава да се корисник не налази у тој групи.\n* Звездица означава да не можете уклонити групу ако је додате и обратно.",
+       "userrights-groups-help": "Можете променити групе којима овај корисник припада.\n* Означен квадратић означава да се корисник налази у тој групи.\n* Неозначен квадратић означава да се корисник не налази у тој групи.\n* Звездица (*) означава да не можете уклонити групу ако је додате и обратно.\n* Тараба (#) означава да једино можете одложити време истека ове групе; не можете га убрзати.",
        "userrights-reason": "Разлог:",
        "userrights-no-interwiki": "Немате овлашћења да мењате корисничка права на другим викијима.",
        "userrights-nodatabase": "База података $1 не постоји или није локална.",
        "recentchangeslinked-page": "Назив странице:",
        "recentchangeslinked-to": "Прикажи измене страница које су повезане с датом страницом",
        "recentchanges-page-added-to-category": "[[:$1]] је додата у категорију",
-       "recentchanges-page-added-to-category-bundled": "[[:$1]] и још [[Special:WhatLinksHere/$1|{{PLURAL:$2|једна страница|$2 странице}}]] су додате у категорију",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] је додана у категорију, [[Special:WhatLinksHere/$1|ова страница је повезана са другим страницама]]",
        "recentchanges-page-removed-from-category": "[[:$1]] је уклоњена из категорије",
-       "recentchanges-page-removed-from-category-bundled": "[[:$1]] и још [[Special:WhatLinksHere/$1|{{PLURAL:$2|једна страница|$2 странице}}]] су уклоњене из категорије",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] је уклоњена из категорије, [[Special:WhatLinksHere/$1|ова страница је повезана са другим страницама]]",
        "autochange-username": "Медијавики аутоматска измена",
        "upload": "Отпреми датотеку",
        "uploadbtn": "Отпреми датотеку",
        "showhideselectedlogentries": "Прикажи/сакриј изабране догађаје",
        "log-edit-tags": "Уреди ознаке изабраних уноса у дневницима",
        "checkbox-select": "Изабери: $1",
-       "checkbox-all": "све",
-       "checkbox-none": "ништа",
-       "checkbox-invert": "обрни",
+       "checkbox-all": "Све",
+       "checkbox-none": "Ð\9dишта",
+       "checkbox-invert": "Ð\9eбрни",
        "allpages": "Све странице",
        "nextpage": "Следећа страница ($1)",
        "prevpage": "Претходна страница ($1)",
        "emailccsubject": "Копија ваше поруке кориснику $1: $2",
        "emailsent": "Имејл је послат",
        "emailsenttext": "Ваша имејл порука је послата.",
-       "emailuserfooter": "Овај имејл је {{GENDER:$1|послао|послала}} $1 {{GENDER:$2|кориснику|корисници}} $2 помоћу „{{int:emailuser}}“ с викија {{SITENAME}}.",
+       "emailuserfooter": "Овај имејл је {{GENDER:$1|послао|послала}} $1 {{GENDER:$2|кориснику|корисници}} $2 помоћу „{{int:emailuser}}“ с викија {{SITENAME}}. Ако одговорите на овај имејл, {{GENDER:$2|Ваш}} имејл ће бити непосредно прослеђен ка {{GENDER:$1|првобитном пошиљаоцу}}, чиме ће те {{GENDER:$2|му|јој}} открити {{GENDER:$2|Вашу}} имејл адресу.",
        "usermessage-summary": "Слање системске поруке.",
        "usermessage-editor": "Уређивач системских порука",
        "usermessage-template": "MediaWiki:UserMessage",
        "editcomment": "Опис измене: <em>$1</em>.",
        "revertpage": "Враћене измене [[Special:Contribs/$2|$2]] ([[User talk:$2|разговор]]) на последњу измену корисника [[User:$1|$1]]",
        "revertpage-nouser": "Враћене су измене скривеног корисника на последњу измену {{GENDER:$1|корисника|кориснице}} [[User:$1|$1]]",
-       "rollback-success": "Враћене су измене {{GENDER:$1|корисника|кориснице}} $1\nна последњу измену {{GENDER:$2|корисника|кориснице}} $2.",
+       "rollback-success": "Враћене су измене {{GENDER:$1|корисника|кориснице}} {{GENDER:$3|$1}}\nна последњу измену {{GENDER:$2|корисника|кориснице}} {{GENDER:$4|$2}}.",
        "sessionfailure-title": "Сесија је окончана",
        "sessionfailure": "Изгледа да постоји проблем с вашом сесијом;\nова радња је отказана да би се избегла злоупотреба.\nВратите се на претходну страницу, поново је учитајте и покушајте поново.",
        "changecontentmodel": "Промени модел садржаја странице",
        "allmessages-filter-legend": "Филтер",
        "allmessages-filter": "Филтрирај по стању:",
        "allmessages-filter-unmodified": "неизмењене",
-       "allmessages-filter-all": "све",
+       "allmessages-filter-all": "Све",
        "allmessages-filter-modified": "измењене",
        "allmessages-prefix": "Филтрирај по префиксу:",
        "allmessages-language": "Језик:",
        "watchlistedit-clear-removed": "{{PLURAL:$1|1 наслов је уклоњен|$1 наслова су уклоњена|$1 наслова је уклоњено}}:",
        "watchlistedit-too-many": "Има превише страница за приказ овде.",
        "watchlisttools-clear": "испразни списак надгледања",
-       "watchlisttools-view": "прикажи сродне измене",
+       "watchlisttools-view": "Ð\9fрикажи сродне измене",
        "watchlisttools-edit": "прикажи и уреди списак надгледања",
        "watchlisttools-raw": "измени сиров списак надгледања",
        "iranian-calendar-m1": "Фарвардин",
        "htmlform-user-not-exists": "<strong>$1</strong> не постоји.",
        "htmlform-user-not-valid": "<strong>$1</strong> није исправно корисничко име.",
        "logentry-delete-delete": "$1 је {{GENDER:$2|обрисао|обрисала}} страницу $3",
-       "logentry-delete-delete_redir": "$1 је {{GENDER:$2|обрисао|обрисала}} преусмерење $3 преснимавањем",
+       "logentry-delete-delete_redir": "$1 је {{GENDER:$2|обрисао|обрисала}} преусмерење $3 преписивањем",
        "logentry-delete-restore": "$1 је {{GENDER:$2|вратио|вратила}} страницу $3",
        "logentry-delete-event": "$1 је {{GENDER:$2|променио|променила}} видљивост {{PLURAL:$5|1=догађаја|$5 догађаја}} у дневнику $3: $4",
        "logentry-delete-revision": "$1 је {{GENDER:$2|променио|променила}} видљивост {{PLURAL:$5|1=једне измене|$5 измене|$5 измена}} на страници $3: $4",
        "json-error-syntax": "Грешка у синтакси",
        "headline-anchor-title": "Веза до овог одељка",
        "special-characters-group-latin": "Латиница",
-       "special-characters-group-latinextended": "проширена латиница",
+       "special-characters-group-latinextended": "Ð\9fроширена латиница",
        "special-characters-group-ipa": "ИПА",
-       "special-characters-group-symbols": "симболи",
-       "special-characters-group-greek": "грчки",
-       "special-characters-group-cyrillic": "ћирилица",
-       "special-characters-group-arabic": "арапски",
-       "special-characters-group-arabicextended": "проширени арапски",
+       "special-characters-group-symbols": "Симболи",
+       "special-characters-group-greek": "Грчки",
+       "special-characters-group-greekextended": "Проширени грчки",
+       "special-characters-group-cyrillic": "Ћирилица",
+       "special-characters-group-arabic": "Арапски",
+       "special-characters-group-arabicextended": "Проширени арапски",
        "special-characters-group-persian": "персијски",
-       "special-characters-group-hebrew": "хебрејски",
-       "special-characters-group-bangla": "бенгалски",
-       "special-characters-group-tamil": "тамилски",
-       "special-characters-group-telugu": "телугу",
-       "special-characters-group-sinhala": "синхалски",
-       "special-characters-group-gujarati": "гуџарати",
-       "special-characters-group-devanagari": "деванагари",
-       "special-characters-group-thai": "тајландски",
-       "special-characters-group-lao": "лаоски",
-       "special-characters-group-khmer": "кмерски",
+       "special-characters-group-hebrew": "Хебрејски",
+       "special-characters-group-bangla": "Ð\91енгалски",
+       "special-characters-group-tamil": "Тамилски",
+       "special-characters-group-telugu": "Телугу",
+       "special-characters-group-sinhala": "Синхалски",
+       "special-characters-group-gujarati": "Ð\93уџарати",
+       "special-characters-group-devanagari": "Ð\94еванагари",
+       "special-characters-group-thai": "Тајландски",
+       "special-characters-group-lao": "Ð\9bаоски",
+       "special-characters-group-khmer": "Ð\9aмерски",
        "mw-widgets-dateinput-no-date": "Датум није изабран",
        "mw-widgets-dateinput-placeholder-day": "ГГГГ-ММ-ДД",
        "mw-widgets-dateinput-placeholder-month": "ГГГГ-ММ",
        "log-action-filter-protect": "Тип закључавања:",
        "log-action-filter-rights": "Тип промене корисничких права:",
        "log-action-filter-upload": "Тип отпремања:",
-       "log-action-filter-all": "све",
+       "log-action-filter-all": "Све",
        "log-action-filter-block-block": "блокирање",
        "log-action-filter-block-reblock": "измена блокирања",
        "log-action-filter-block-unblock": "деблокирање",
        "log-action-filter-managetags-activate": "активирање ознаке",
        "log-action-filter-managetags-deactivate": "деактивирање ознаке",
        "log-action-filter-move-move": "премештање без преснимавања преусмерења",
-       "log-action-filter-move-move_redir": "пÑ\80емеÑ\88Ñ\82аÑ\9aе Ñ\81а Ð¿Ñ\80еÑ\81нимавањем преусмерења",
+       "log-action-filter-move-move_redir": "Ð\9fÑ\80емеÑ\88Ñ\82аÑ\9aе Ñ\81а Ð¿Ñ\80епиÑ\81ивањем преусмерења",
        "log-action-filter-newusers-create": "отворио анониман корисник",
        "log-action-filter-newusers-create2": "отворио регистрован корисник",
        "log-action-filter-newusers-autocreate": "аутоматски отворен",
index 45a83ca..d1a3a20 100644 (file)
@@ -40,6 +40,7 @@
        "tog-watchdefault": "Dodaj stranice i datoteke koje izmenim u spisak nadgledanja",
        "tog-watchmoves": "Dodaj stranice i datoteke koje premestim u spisak nadgledanja",
        "tog-watchdeletion": "Dodaj stranice i datoteke koje obrišem u spisak nadgledanja",
+       "tog-watchuploads": "Dodaj datoteke koje otpremim u spisak nadgledanja",
        "tog-watchrollback": "Dodaj stranice na kojima sam vratio izmene u spisak nadgledanja",
        "tog-minordefault": "Označavaj sve izmene kao manje",
        "tog-previewontop": "Prikaži pregled pre okvira za uređivanje",
@@ -51,7 +52,7 @@
        "tog-shownumberswatching": "Prikaži broj korisnika koji nadgledaju",
        "tog-oldsig": "Tekući potpis:",
        "tog-fancysig": "Smatraj potpis kao vikitekst (bez samopovezivanja)",
-       "tog-uselivepreview": "Koristi trenutan pregled",
+       "tog-uselivepreview": "Koristi trenutni pregled",
        "tog-forceeditsummary": "Upozori me kada ne unesem opis izmene",
        "tog-watchlisthideown": "Sakrij moje izmene sa spiska nadgledanja",
        "tog-watchlisthidebots": "Sakrij izmene botova sa spiska nadgledanja",
@@ -64,7 +65,7 @@
        "tog-ccmeonemails": "Pošalji mi kopije imejlova koje pošaljem drugim korisnicima",
        "tog-diffonly": "Ne prikazuj sadržaj stranice ispod razlika",
        "tog-showhiddencats": "Prikaži skrivene kategorije",
-       "tog-norollbackdiff": "Izostavi razliku nakon izvršenog vraćanja",
+       "tog-norollbackdiff": "Ne prikazuj razliku nakon izvršenog vraćanja",
        "tog-useeditwarning": "Upozori me kada napuštam stranicu sa nesačuvanim promenama",
        "tog-prefershttps": "Uvek koristi sigurnu konekciju kada sam prijavljen.",
        "underline-always": "uvek podvlači",
        "hr_tip": "Vodoravna linija (koristiti retko)",
        "summary": "Opis izmene:",
        "subject": "Tema:",
-       "minoredit": "manja izmena",
-       "watchthis": "nadgledaj ovu stranicu",
+       "minoredit": "Ovo je manja izmena",
+       "watchthis": "Nadgledaj ovu stranicu",
        "savearticle": "Sačuvaj stranicu",
        "savechanges": "Sačuvaj izmene",
        "publishpage": "Objavi stranicu",
        "difference-multipage": "(razlike između stranica)",
        "lineno": "Red $1:",
        "compareselectedversions": "Uporedi izabrane izmene",
-       "showhideselectedversions": "Prikaži/sakrij izabrane izmene",
+       "showhideselectedversions": "Promeni vidljivost izabranih izmena",
        "editundo": "poništi",
        "diff-empty": "(Nema razlike)",
        "diff-multi-sameuser": "({{PLURAL:$1|Jedna međuizmena istog korisnika nije prikazana|$1 međuizmene istog korisnika nije prikazano|$1 međuizmena istog korisnika nije prikazano}})",
        "powersearch-legend": "Napredna pretraga",
        "powersearch-ns": "Traži u sledećim imenskim prostorima:",
        "powersearch-togglelabel": "Izaberi:",
-       "powersearch-toggleall": "sve",
-       "powersearch-togglenone": "ništa",
+       "powersearch-toggleall": "Sve",
+       "powersearch-togglenone": "Ništa",
        "powersearch-remember": "Zapamti moj izbor za buduće pretrage",
        "search-external": "Spoljna pretraga",
        "searchdisabled": "Pretraga je onemogućena.\nU međuvremenu možete tražiti preko Gugla.\nUpamtite da njegovi popisi ovog vikija mogu biti zastareli.",
        "username": "{{GENDER:$1|Korisničko ime}}:",
        "prefs-memberingroups": "{{PLURAL:$1|Grupa|Grupe}}:",
        "prefs-memberingroups-type": "$1",
-       "prefs-registration": "Vreme upisa:",
+       "prefs-registration": "Vreme registracije:",
        "prefs-registration-date-time": "$1",
        "yourrealname": "Pravo ime:",
        "yourlanguage": "Jezik:",
        "showhideselectedlogentries": "Prikaži/sakrij izabrane događaje",
        "log-edit-tags": "Uredi oznake izabranih unosa u dnevnicima",
        "checkbox-select": "Izaberi: $1",
-       "checkbox-all": "sve",
-       "checkbox-none": "ništa",
-       "checkbox-invert": "obrni",
+       "checkbox-all": "Sve",
+       "checkbox-none": "Ništa",
+       "checkbox-invert": "Obrni",
        "allpages": "Sve stranice",
        "nextpage": "Sledeća stranica ($1)",
        "prevpage": "Prethodna stranica ($1)",
        "allmessages-filter-legend": "Filter",
        "allmessages-filter": "Filtriraj po stanju:",
        "allmessages-filter-unmodified": "neizmenjene",
-       "allmessages-filter-all": "sve",
+       "allmessages-filter-all": "Sve",
        "allmessages-filter-modified": "izmenjene",
        "allmessages-prefix": "Filtriraj po prefiksu:",
        "allmessages-language": "Jezik:",
        "tooltip-watchlistedit-raw-submit": "Ažuriraj spisak",
        "tooltip-recreate": "Ponovo napravite stranicu iako je obrisana",
        "tooltip-upload": "Započnite otpremanje",
-       "tooltip-rollback": "Opcija „Vrati“ vraća izmene poslednjeg korisnika",
+       "tooltip-rollback": "„Vrati“ vraća izmene poslednjeg korisnika jednim klikom",
        "tooltip-undo": "Poništava ovu izmenu i otvara obrazac za uređivanje.",
        "tooltip-preferences-save": "Sačuvaj postavke",
        "tooltip-summary": "Unesite kratak opis",
        "watchlistedit-clear-removed": "{{PLURAL:$1|1 naslov je uklonjen|$1 naslova su uklonjena|$1 naslova je uklonjeno}}:",
        "watchlistedit-too-many": "Ima previše stranica za prikaz ovde.",
        "watchlisttools-clear": "isprazni spisak nadgledanja",
-       "watchlisttools-view": "prikaži srodne izmene",
+       "watchlisttools-view": "Prikaži srodne izmene",
        "watchlisttools-edit": "prikaži i uredi spisak nadgledanja",
        "watchlisttools-raw": "izmeni sirov spisak nadgledanja",
        "iranian-calendar-m1": "Farvardin",
        "htmlform-user-not-exists": "<strong>$1</strong> ne postoji.",
        "htmlform-user-not-valid": "<strong>$1</strong> nije ispravno korisničko ime.",
        "logentry-delete-delete": "$1 je {{GENDER:$2|obrisao|obrisala}} stranicu $3",
+       "logentry-delete-delete_redir": "$1 je {{GENDER:$2|obrisao|obrisala}} preusmerenje $3 prepisivanjem",
        "logentry-delete-restore": "$1 je {{GENDER:$2|vratio|vratila}} stranicu $3",
        "logentry-delete-event": "$1 je {{GENDER:$2|promenio|promenila}} vidljivost {{PLURAL:$5|1=događaja|$5 događaja}} u dnevniku $3: $4",
        "logentry-delete-revision": "$1 je {{GENDER:$2|promenio|promenila}} vidljivost {{PLURAL:$5|1=jedne izmene|$5 izmene|$5 izmena}} na stranici $3: $4",
        "json-error-syntax": "Greška u sintaksi",
        "headline-anchor-title": "Veza do ovog odeljka",
        "special-characters-group-latin": "Latinica",
-       "special-characters-group-latinextended": "proširena latinica",
+       "special-characters-group-latinextended": "Proširena latinica",
        "special-characters-group-ipa": "IPA",
        "special-characters-group-symbols": "Simboli",
-       "special-characters-group-greek": "grčki",
-       "special-characters-group-cyrillic": "ćirilica",
-       "special-characters-group-arabic": "arapski",
-       "special-characters-group-arabicextended": "prošireni arapski",
+       "special-characters-group-greek": "Grčki",
+       "special-characters-group-greekextended": "Prošireni grčki",
+       "special-characters-group-cyrillic": "Ćirilica",
+       "special-characters-group-arabic": "Arapski",
+       "special-characters-group-arabicextended": "Prošireni arapski",
        "special-characters-group-persian": "persijski",
-       "special-characters-group-hebrew": "jevrejsko",
-       "special-characters-group-bangla": "Bangla",
-       "special-characters-group-tamil": "tamilski",
-       "special-characters-group-telugu": "telugu",
-       "special-characters-group-sinhala": "sinhalski",
+       "special-characters-group-hebrew": "Hebrejski",
+       "special-characters-group-bangla": "Bengalski",
+       "special-characters-group-tamil": "Tamilski",
+       "special-characters-group-telugu": "Telugu",
+       "special-characters-group-sinhala": "Sinhalski",
        "special-characters-group-gujarati": "Gudžarati",
-       "special-characters-group-devanagari": "devanagari",
-       "special-characters-group-thai": "tajlandski",
-       "special-characters-group-lao": "laoski",
-       "special-characters-group-khmer": "kmerski",
+       "special-characters-group-devanagari": "Devanagari",
+       "special-characters-group-thai": "Tajlandski",
+       "special-characters-group-lao": "Laoski",
+       "special-characters-group-khmer": "Kmerski",
        "mw-widgets-dateinput-no-date": "Datum nije izabran",
        "mw-widgets-dateinput-placeholder-day": "GGGG-MM-DD",
        "mw-widgets-dateinput-placeholder-month": "GGGG-MM",
        "mw-widgets-titleinput-description-new-page": "stranica još uvek ne postoji",
        "mw-widgets-titleinput-description-redirect": "preusmerava na $1",
        "randomrootpage": "Slučajna korenska stranica",
+       "log-action-filter-all": "Sve",
+       "log-action-filter-move-move_redir": "Premeštanje sa prepisivanjem preusmerenja",
        "log-action-filter-upload-upload": "Novo otpremanje",
        "authmanager-email-label": "Imejl",
        "authmanager-email-help": "Imejl adresa",
index 868b7b3..b9ae2be 100644 (file)
        "rcfilters-invalid-filter": "Ogiltigt filter",
        "rcfilters-empty-filter": "Inga aktiva filter. Alla bidrag visas.",
        "rcfilters-filterlist-title": "Filter",
+       "rcfilters-filterlist-feedbacklink": "Ge återkoppling på nya (beta)filter",
        "rcfilters-highlightbutton-title": "Markera resultat",
        "rcfilters-highlightmenu-title": "Välj en färg",
        "rcfilters-filterlist-noresults": "Inga filter hittades",
index 9fcaacf..3776c86 100644 (file)
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|కొత్త పేజీల జాబితా]]ను కూడా చూడండి)",
        "recentchanges-submit": "చూపించు",
        "rcfilters-filterlist-title": "వడపోతలు",
+       "rcfilters-highlightmenu-title": "ఒక రంగును ఎంచుకోండి",
        "rcfilters-filtergroup-registration": "వాడుకరి నమోదు",
        "rcfilters-filter-editsbyself-label": "మీ స్వంత దిద్దుబాట్లు",
        "rcfilters-filter-editsbyself-description": "మీ దిద్దుబాట్లు.",
index 1b2cb44..a9a2760 100644 (file)
        "feedback-thanks": "Teşekkürler! Görüşleriniz \"[$2 $1]\" sayfasında paylaşılmıştır.",
        "feedback-thanks-title": "Teşekkürler!",
        "feedback-useragent": "Kullanıcı temsilcisi",
-       "searchsuggest-search": "Ara",
+       "searchsuggest-search": "{{SITENAME}} üzerinde ara",
        "searchsuggest-containing": "içeren...",
        "api-error-badtoken": "İç hata: Bozuk anahtar.",
        "api-error-emptypage": "Yeni, boş bir sayfa oluşturmaya izin verilmez.",
index bac27db..c357658 100644 (file)
        "saveprefs": "Шыгжаары",
        "restoreprefs": "Шупту баштайгы ниити шилилгелерни restore",
        "prefs-editing": "Өскертир",
-       "rows": "Одуруглар:",
-       "columns": "Баганалар:",
        "searchresultshead": "Дилээр",
        "timezoneuseserverdefault": "Викиниң ниити шилилгезин ажыглаары ($1)",
        "servertime": "Серверниң шагы:",
        "hours": "{{PLURAL:$1|1=$1 шак|$1 шак}}",
        "days": "{{PLURAL:$1|1=$1 хүн|$1 хүн}}",
        "ago": "$1 бурунгаар",
-       "bad_image_list": "ФоÑ\80мадÑ\8b Ð¼Ñ\8bндÑ\8bг Ð±Ð¾Ð¾Ñ\80 Ñ\83жÑ\83Ñ\80лÑ\83г:\n\nЧүгле Ð´Ð°Ò£Ð·Ñ\8bнÑ\8bÒ£ Ð¸Ð´ÐµÐ³ÐµÑ\82Ñ\82еÑ\80и (Ñ\8dлеменÑ\82илеÑ\80и) Ñ\81анаÑ\82Ñ\8bнаÑ\80 Ð±Ð¾Ð¾Ñ\80 (* Ð´ÐµÐ¿ Ð´ÐµÐ¼Ð´ÐµÐºÑ\82ен Ñ\8dгелÑ\8dÑ\8dн Ð¾Ð´Ñ\83Ñ\80Ñ\83глаÑ\80).\nÐ\9eдÑ\83Ñ\80Ñ\83гнÑ\83Ò£ Ð±Ð¸Ñ\80ги Ñ\88өлүдүү Ñ\81алдÑ\8bнмаÑ\81 Ñ\87Ñ\83Ñ\80Ñ\83малÑ\87е Ñ\88өлүдүг Ð±Ð¾Ð»Ñ\83Ñ\80Ñ\83 Ð°Ð»Ð±Ð°Ð½.\nÐ\9eл-ла Ð¾Ð´Ñ\83Ñ\80Ñ\83гнÑ\83Ò£ Ð°Ñ\80Ñ\82кан Ñ\88өлүдүглеÑ\80и Ð¾Ð½Ð·Ð°Ð³Ð°Ð¹ ÐºÑ\8bлдÑ\8bÑ\80 Ð°Ð·Ñ\8b Ñ\87Ñ\83Ñ\80Ñ\83мал ÐºÐ°Ð¿Ñ\81Ñ\8bÑ\80Ñ\8bп Ð±Ð¾Ð»Ñ\83Ñ\80 Ñ\87үүлдеÑ\80 ÐºÑ\8bлдÑ\8bÑ\80 Ñ\81анаÑ\82Ñ\82Ñ\8bнар.",
+       "bad_image_list": "ФоÑ\80мадÑ\8b Ð¼Ñ\8bндÑ\8bг Ð±Ð¾Ð»Ñ\83Ñ\80 Ñ\83жÑ\83Ñ\80лÑ\83г:\n\nÐ\94аңзÑ\8bда Ñ\87үгле Ñ\8dлеменÑ\82илеÑ\80 Ñ\81анаÑ\82Ñ\8bнаÑ\80 (* Ð´ÐµÐ¿ Ð´ÐµÐ¼Ð´ÐµÐºÑ\82ен Ñ\8dгелÑ\8dÑ\8dн Ð¾Ð´Ñ\83Ñ\80Ñ\83глаÑ\80).\nÐ\9eдÑ\83Ñ\80Ñ\83гда Ð±Ð¸Ñ\80 Ð´Ñ\83гааÑ\80 Ð°Ð¹Ñ\82Ñ\8bг Ð±Ð¾Ð»Ð·Ð° ÐºÐ¸Ð¸Ñ\80 Ð±Ð¸Ð¶Ð¸Ñ\82Ñ\82инмеÑ\81 Ñ\87Ñ\83Ñ\80Ñ\83кÑ\87е Ð°Ð¹Ñ\82Ñ\8bÑ\80 Ñ\83жÑ\83Ñ\80лÑ\83г.\nÐ\9eл-ла Ð¾Ð´Ñ\83Ñ\80Ñ\83гнÑ\83Ò£ Ó©Ñ\81ке Ð°Ð¹Ñ\82Ñ\8bглаÑ\80Ñ\8b, Ñ\87Ñ\83Ñ\80Ñ\83кÑ\82аÑ\80нÑ\8b ÐºÐ¸Ð¸Ñ\80 Ð±Ð¸Ð¶Ð¸Ð´Ð¸Ð¿ Ð±Ð¾Ð»Ñ\83Ñ\80 Ð°Ñ\80Ñ\8bннаÑ\80же Ð°Ð¹Ñ\82Ñ\8bп Ñ\82Ñ\83Ñ\80ар.",
        "metadata": "Чурумал дугайында медээлер",
        "metadata-help": "Бо файлда цифралыг камераларның болгаш сканерлерниң немеп каары немелде медээлер бар. Файлды кылган соонда эдип турган болза, ооң чамдык параметрлери ооң амгы чуруунга дүүшпес бооп болур.",
        "metadata-fields": "Бо даңзыда айыткан чурумалдар метаданныйларның кезектери чурумалдың арынынга көстүп кээр, метаданныйлар таблицазын дүрүп каан болур. \nАрткан кезектер аайлаан ёзугаар чажыт көстүр.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
index a976001..7d515d6 100644 (file)
        "missing-revision": "Версія #$1 сторінки «{{FULLPAGENAME}}» не існує.\n\nІмовірно, Ви перейшли за застарілим посиланням на вилучену сторінку.\nПодробиці можна дізнатися з [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} журналу вилучень].",
        "userpage-userdoesnotexist": "Користувач під назвою \"<nowiki>$1</nowiki>\" не зареєстрований. Переконайтеся, що ви хочете створити/редагувати цю сторінку.",
        "userpage-userdoesnotexist-view": "Обліковий запис користувача «$1» не зареєстровано.",
-       "blocked-notice-logextract": "Цей користувач наразі заблокований.\nОстанній запис у журналі блокувань такий:",
+       "blocked-notice-logextract": "{{GENDER:$1|Цей користувач|Ця користувачка}} наразі {{GENDER:$1|заблокований|заблокована}}.\nОстанній запис у журналі блокувань такий:",
        "clearyourcache": "<strong>Увага:</strong> Після збереження слід очистити кеш оглядача, щоб побачити зміни.\n* <strong>Firefox / Safari:</strong> тримайте <em>Shift</em>, коли натискаєте <em>Оновити</em>, або натисніть <em>Ctrl-F5</em> чи <em>Ctrl-Shift-R</em> (<em>⌘-R</em> на Apple Mac)\n* <strong>Google Chrome:</strong> натисніть <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> на Apple Mac)\n* <strong>Internet Explorer:</strong> тримайте <em>Ctrl</em>, коли натискаєте <em>Оновити</em>, або натисніть <em>Ctrl-F5</em>\n* <strong>Opera:</strong> очистіть кеш за допомогою <em>Інструменти → Налаштування</em> (<em>Opera → Побажання</em> на Apple Mac) та перейдіть на <em>Приватність & безпека → очистити дані браузера → кеш</em>",
        "usercssyoucanpreview": "'''Підказка:''' використовуйте кнопку «{{int:showpreview}}», щоб протестувати ваш новий css-файл перед збереженням.",
        "userjsyoucanpreview": "'''Підказка:''' використовуйте кнопку «{{int:showpreview}}», щоб протестувати ваш новий код JavaScript перед збереженням.",
        "saveusergroups": "Зберегти групи {{GENDER:$1|користувачів}}",
        "userrights-groupsmember": "Член груп:",
        "userrights-groupsmember-auto": "Неявний член:",
-       "userrights-groups-help": "Ви можете змінити групи, до яких належить цей користувач:\n* Якщо біля назви групи стоїть позначка, то користувач належить до цієї групи.\n* Якщо позначка не стоїть — користувач не належить до відповідної групи.\n* Зірочка «*» означає, що ви не можете вилучити користувача з групи, якщо додасте його до неї, і навпаки.\n* Ґратка «#» означає, що ви можете зменшити строк членства в групі, але не збільшити.",
+       "userrights-groups-help": "Ви можете змінити групи, до яких належить {{GENDER:$1|цей користувач|ця користувачка}}:\n* Якщо біля назви групи стоїть позначка, то {{GENDER:$1|користувач|користувачка}} належить до цієї групи.\n* Якщо позначка не стоїть — {{GENDER:$1|користувач|користувачка}} не належить до відповідної групи.\n* Зірочка «*» означає, що Ви не можете вилучити {{GENDER:$1|користувача|користувачку}} з групи, якщо додасте {{GENDER:$1|його|її}} до неї, і навпаки.\n* Решітка «#» означає, що Ви можете зменшити строк членства в групі, але не збільшити.",
        "userrights-reason": "Причина:",
        "userrights-no-interwiki": "У вас нема дозволу змінювати права користувачів на інших вікі.",
        "userrights-nodatabase": "База даних $1 не існує або не є локальною.",
        "svg-long-error": "неправильний SVG-файл: $1",
        "show-big-image": "Повна роздільність",
        "show-big-image-preview": "Розмір при попередньому перегляді: $1.",
-       "show-big-image-preview-differ": "Розмір цього $3-превью для вихідного $2-файлу: $1.",
+       "show-big-image-preview-differ": "Розмір цього попереднього перегляду $3 для вихідного $2-файлу: $1.",
        "show-big-image-other": "{{PLURAL:$2|1=Інша роздільність|Інші роздільності}}: $1.",
        "show-big-image-size": "$1 × $2 пікселів",
        "file-info-gif-looped": "кільцеве",
index 6b8e5a5..8093c68 100644 (file)
@@ -16,7 +16,8 @@
                        "Silovan",
                        "David1010",
                        "Macofe",
-                       "Nemo bis"
+                       "Nemo bis",
+                       "Otogi"
                ]
        },
        "tog-underline": "რცხუეფიშ ათოღაზუა:",
        "viewyourtext": "თქვა შეილებუნა ქოძირათ '''თქვანი რედაქტირაფეფიშ''' დაჭყაფური ტექსტი თე ხასჷლას დო გეჭოფათ თიშ ანგი.",
        "protectedinterface": "ეს გვერდი წარმოადგენს ტექსტურ ინტერფეისს პროგრამული უზრუნველყოფისათვის და დაცულია ვანდალიზმის აღკვეთის მიზნით.",
        "editinginterface": "<strong>ყურადღება:</strong> თქვენ არედაქტირებთ გვერდს, რომელიც პროგრამის ინტერფეისის ტექსტს შეიცავს. \nამ გვერდზე განხორციელებული რედაქტირება გამოიწვევს ამ ვიკის სხვა მომხმარებელთა სამუშაო ინტერფეისის შეცვლასაც.",
-       "translateinterface": "თარგმანების ყველა ვიკიში დასამატებლად ან შესაცვლელად, გთხოვთ გამოიყენოთ მედიავიკებისლოკალიზაციის პროექტი [https://translatewiki.net/ translatewiki.net].",
+       "translateinterface": "თარგმანების ყველა ვიკიში დასამატებლად ან შესაცვლელად, გთხოვთ გამოიყენოთ მედიავიკების ლოკალიზაციის პროექტი [https://translatewiki.net/ translatewiki.net].",
        "cascadeprotected": "ეს გვერდი რედაქტირებისგან დაცულია, რადგან იგი ჩართულია შემდეგ {{PLURAL:$1|გვერდში, რომლის |გვერდებში, რომელთა}} დასაცავადაც ჩართულია პარამეტრი \"იერარქიული\":\n$2",
        "namespaceprotected": "თქვენ არ გაქვთ '''$1''' სახელთა სივრცეში გვერდების რედაქტირების უფლება.",
        "customcssprotected": "თქვენ არ გაქვთ ამ CSS გვერდის რედაქტირების უფლება, ვინაიდან ის სხვა მომხმარებლის პირად კონფიგურაციას შეიცავს.",
index f57c71b..19f211a 100644 (file)
        "virus-unknownscanner": "未知嘅防病毒:",
        "logouttext": "<strong>你而家已經簽退咗。</strong>\n\n但係留意某啲頁面可能會繼續話你未登入,除非等你清除瀏覽器嘅快取儲存。",
        "cannotlogoutnow-title": "而家簽走唔到",
+       "cannotlogoutnow-text": "用緊$1嗰陣唔可以簽走。",
        "welcomeuser": "歡迎,$1!",
        "welcomecreation-msg": "你個戶口已經起好。\n唔好唔記得去改改你嘅{{SITENAME}}[[Special:Preferences|喜好設定]]喎。",
        "yourname": "用戶名:",
        "cannotlogin-title": "簽到唔到",
        "cannotlogin-text": "冇可能簽到",
        "cannotloginnow-title": "而家簽到唔到",
+       "cannotloginnow-text": "用緊$1嗰陣唔可以簽到。",
        "cannotcreateaccount-title": "開唔到新戶口",
        "cannotcreateaccount-text": "呢個維基唔准直接開戶",
        "yourdomainname": "你嘅網域:",
        "createacct-benefit-body1": "{{PLURAL:$1|次編輯|次編輯}}",
        "createacct-benefit-body2": "{{PLURAL:$1|版|版}}",
        "createacct-benefit-body3": "最近{{PLURAL:$1|貢獻者|貢獻者}}",
-       "badretype": "ä½ å\85¥å\98\85å¯\86碼å\94\94ä¸\80è\87´。",
+       "badretype": "ä½ å\85¥å\98\85å¯\86碼å\89\8då¾\8cä¸\8dä¸\80。",
        "usernameinprogress": "呢個名嘅戶口已經開緊。\n請等等。",
        "userexists": "你入嘅用戶名已經有人用咗。\n唔該揀過個名啦。",
        "loginerror": "登入錯誤",
        "editusergroup": "編輯用戶組",
        "editinguser": "改緊<strong>[[User:$1|$1]]</strong>嘅用戶權限 $2",
        "userrights-editusergroup": "編輯用戶組",
-       "saveusergroups": "儲存用戶組",
+       "saveusergroups": "儲存{{GENDER:$1|用戶}}組",
        "userrights-groupsmember": "屬於:",
        "userrights-groupsmember-auto": "固有屬於:",
-       "userrights-groups-help": "你可以改呢位用戶所屬嘅組:\n* 剔咗嘅盒代表個用戶係屬於嗰組。\n* 未剔嘅盒代表個用戶唔係屬於嗰組。\n* 一個 * 表示你加入咗佢之後唔可以拎走,反之亦然。",
+       "userrights-groups-help": "你可以改呢位用戶所屬嘅組:\n* 剔咗嘅盒代表個用戶係屬於嗰組。\n* 未剔嘅盒代表個用戶唔係屬於嗰組。\n* 一個 * 表示你加入咗佢之後唔可以拎走,反之亦然。\n* 一個 # 表示你只可以推遲嗰組嘅失效日期,唔可以提早。",
        "userrights-reason": "原因:",
        "userrights-no-interwiki": "你並無權限去編輯響其它wiki嘅用戶權限。",
        "userrights-nodatabase": "資料庫$1唔存在或者唔係本地嘅。",
        "userrights-changeable-col": "你可以改嘅組",
        "userrights-unchangeable-col": "你唔可以改嘅組",
+       "userrights-expiry-current": "$1 到期",
+       "userrights-expiry-none": "唔會到期",
+       "userrights-expiry": "到期:",
+       "userrights-expiry-existing": "現時到期嘅時間: $2 $3",
+       "userrights-expiry-othertime": "其它時間:",
        "userrights-conflict": "用戶權限更改有衝突!請再睇過同確認你嘅改動。",
        "group": "組:",
        "group-user": "用戶",
        "rightslogtext": "呢個係用戶權力嘅修改日誌。",
        "action-read": "讀呢版",
        "action-edit": "編輯呢版",
-       "action-createpage": "開版",
+       "action-createpage": "建立呢頁",
        "action-createtalk": "開討論版",
        "action-createaccount": "開呢個用戶戶口",
        "action-history": "睇呢頁嘅歷史",
        "action-suppressionlog": "睇呢個私有日誌",
        "action-block": "封鎖呢位用戶嘅編輯",
        "action-protect": "改呢版嘅保護等級",
+       "action-rollback": "速還原某版最後修改人之修改",
        "action-import": "由其它wiki度倒入版",
        "action-importupload": "由檔案上載度倒入版",
        "action-patrol": "標示其它嘅編輯做已巡查嘅",
        "action-userrights": "編輯全部嘅權限",
        "action-userrights-interwiki": "編輯響其它wiki用戶嘅權限",
        "action-siteadmin": "鎖同解鎖資料庫",
-       "action-sendemail": "電郵",
+       "action-sendemail": "電郵",
        "action-editmywatchlist": "改監視清單",
        "action-viewmywatchlist": "睇監視清單",
        "action-viewmyprivateinfo": "睇你嘅私人資料",
        "recentchanges-legend-heading": "<strong>標記:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (睇埋[[Special:NewPages|新開版]])",
        "recentchanges-submit": "顯示",
+       "rcfilters-filter-editsbyself-description": "你改嘅嘢。",
+       "rcfilters-filter-editsbyother-label": "其他人改嘅嘢",
+       "rcfilters-filter-editsbyother-description": "其他人(唔係你)改嘅嘢",
+       "rcfilters-filtergroup-userExpLevel": "經驗級別(只限簽咗到嘅用戶)",
+       "rcfilters-filter-userExpLevel-newcomer-label": "新手",
+       "rcfilters-filter-userExpLevel-newcomer-description": "少過4日、10次編輯",
+       "rcfilters-filter-userExpLevel-learner-label": "學徒",
+       "rcfilters-filter-userExpLevel-learner-description": "編輯數同經驗多過「新手」但少過「老手」。",
+       "rcfilters-filter-userExpLevel-experienced-label": "老手",
+       "rcfilters-filter-userExpLevel-experienced-description": "超過30日同埋500次編輯",
+       "rcfilters-filtergroup-automated": "自動貢獻",
+       "rcfilters-filter-bots-label": "機械人",
+       "rcfilters-filter-bots-description": "用自動工具做嘅貢獻",
+       "rcfilters-filter-humans-label": "人類(唔係機械人)",
+       "rcfilters-filter-humans-description": "真人做嘅編輯",
+       "rcfilters-filtergroup-significance": "顯著度",
+       "rcfilters-filter-minor-label": "細編輯",
+       "rcfilters-filter-minor-description": "作者話程度細嘅修改。",
+       "rcfilters-filter-major-label": "唔細嘅編輯",
+       "rcfilters-filter-major-description": "作者冇話程度細嘅修改。",
+       "rcfilters-filtergroup-changetype": "修改類別",
        "rcnotefrom": "下面嘅{{PLURAL:$5|改動}}由 <strong>$3 $4</strong> 開始(顯示到'''$1''')。",
        "rclistfrom": "顯示由$3 $2嘅新更改",
        "rcshowhideminor": "$1小編輯",
        "allpagesbadtitle": "提供嘅頁面名無效,又或者有一個跨語言或跨wiki嘅字頭。佢可能包括一個或多個字係唔可以用響標題度嘅。",
        "allpages-bad-ns": "{{SITENAME}}係無一個空間名叫做\"$1\"。",
        "allpages-hide-redirects": "收埋跳轉",
+       "cachedspecial-viewing-cached-ttl": "以下資料,來自暫存,上次更新係$1之前嘅事。",
        "cachedspecial-refresh-now": "睇最新。",
        "categories": "類",
        "categoriespagetext": "下面嘅{{PLURAL:$1|類}}有版或媒體。\n[[Special:UnusedCategories|未用類]]唔會響呢度列示。\n請同時參閱[[Special:WantedCategories|需要嘅分類]]。",
        "delete-legend": "刪除",
        "historywarning": "<strong>警告:</strong>你要刪除嘅頁面有大約$1次嘅修訂:",
        "confirmdeletetext": "你準備刪除一個頁面或者圖像,包括佢嘅所有歷史版本。\n請確認你打算噉做,而且你知道後果係點,加上確認你噉做冇違反到[[{{MediaWiki:Policy-url}}]]。",
-       "actioncomplete": "æ\93\8dä½\9cå®\8cæ\88\90",
-       "actionfailed": "æ\93\8dä½\9c失æ\95\97",
+       "actioncomplete": "æ\90\9eæ\8e\82",
+       "actionfailed": "æ\90\9eå\94\94æ\8e\82",
        "deletedtext": "\"$1\"已經刪除。最近嘅刪除記錄請睇$2。",
        "dellogpage": "刪除日誌",
        "dellogpagetext": "以下係最近嘅刪除清單。",
index 1837c4b..1e61710 100644 (file)
        "resettokens": "重置密钥",
        "resettokens-text": "您可以在这里重置允许访问与您的账户有关的特定私人数据的密钥。\n\n如果您意外将它们分享给他人,或是您的账户已经被入侵,您应该重置它们。",
        "resettokens-no-tokens": "没有可以重置的密钥。",
-       "resettokens-tokens": "密钥:",
+       "resettokens-tokens": "令牌:",
        "resettokens-token-label": "$1(当前值:$2)",
        "resettokens-watchlist-token": "[[Special:Watchlist|对你的监视列表中的页面的更改]]的网页feed(Atom/RSS)的密钥",
        "resettokens-done": "密钥已重置。",
        "prefs-advancedwatchlist": "高级选项",
        "prefs-displayrc": "显示",
        "prefs-displaywatchlist": "显示",
-       "prefs-tokenwatchlist": "密钥",
+       "prefs-tokenwatchlist": "令牌",
        "prefs-diffs": "差异对比",
        "prefs-help-prefershttps": "该设置将在下次登录时生效。",
        "prefswarning-warning": "您对您的参数设置的更改尚未保存。如果您不点击“$1”就离开,您的设置就不会更新。",
        "rcfilters-invalid-filter": "无效过滤器",
        "rcfilters-empty-filter": "没有活跃的过滤器。已显示所有贡献。",
        "rcfilters-filterlist-title": "过滤器",
+       "rcfilters-filterlist-feedbacklink": "在新(测试版)过滤器中提供反馈",
        "rcfilters-highlightbutton-title": "高亮结果",
        "rcfilters-highlightmenu-title": "选择颜色",
        "rcfilters-filterlist-noresults": "找不到过滤器",
index e39cb1c..ac9b60e 100644 (file)
@@ -81,7 +81,8 @@
                        "Knch903",
                        "Winstonyin",
                        "Wmr",
-                       "烈羽"
+                       "烈羽",
+                       "和平奮鬥救地球"
                ]
        },
        "tog-underline": "底線標示連結:",
        "editusergroup": "載入使用者群組",
        "editinguser": "變更{{GENDER:$1|使用者}} <strong>[[User:$1|$1]]</strong> 的使用者權限 $2",
        "viewinguserrights": "檢視{{GENDER:$1|使用者}}<strong>[[User:$1|$1]]</strong>的使用者權限 $2",
-       "userrights-editusergroup": "編輯使用者群組",
+       "userrights-editusergroup": "編輯{{GENDER:$1|使用者}}群組",
        "userrights-viewusergroup": "檢視{{GENDER:$1|使用者}}群組",
        "saveusergroups": "儲存{{GENDER:$1|使用者}}群組",
        "userrights-groupsmember": "所屬群組:",
        "userrights-nodatabase": "資料庫 $1 不存在或不在本地主機的。",
        "userrights-changeable-col": "您可變更的群組",
        "userrights-unchangeable-col": "您不可變更的群組",
+       "userrights-expiry": "期限:",
        "userrights-expiry-othertime": "其他時間:",
        "userrights-conflict": "使用者權限變更發生衝突!請檢閱並確認你的變更。",
        "group": "群組:",
        "rcfilters-search-placeholder": "過濾最近變更(瀏覽或開始輸入)",
        "rcfilters-invalid-filter": "過濾規則無效",
        "rcfilters-filterlist-title": "篩選器",
+       "rcfilters-filterlist-feedbacklink": "在新(測試版)過濾器中提供反饋",
        "rcfilters-highlightmenu-title": "選擇顏色",
        "rcfilters-filterlist-noresults": "找不到過濾規則",
+       "rcfilters-filter-registered-label": "已註冊",
+       "rcfilters-filter-unregistered-label": "未註冊",
        "rcfilters-filtergroup-authorship": "編輯者",
        "rcfilters-filter-editsbyself-label": "您自己的編輯",
        "rcfilters-filter-editsbyself-description": "您的編輯。",
        "rcfilters-filter-userExpLevel-learner-description": "活躍的天數以及編輯數比「新手」多,但比「有經驗的使用者」少。",
        "rcfilters-filter-userExpLevel-experienced-label": "有經驗的使用者",
        "rcfilters-filter-userExpLevel-experienced-description": "活躍超過 30 天,編輯超過 500 次。",
+       "rcfilters-filter-bots-label": "機器人",
+       "rcfilters-filter-humans-label": "人類(非機器人)",
+       "rcfilters-filter-humans-description": "由人類編者做出的編輯",
+       "rcfilters-filter-minor-label": "小修改",
+       "rcfilters-filter-major-label": "非小編輯",
+       "rcfilters-filter-major-description": "未標記小修改的編輯。",
+       "rcfilters-filter-pageedits-label": "頁面編輯",
+       "rcfilters-filter-newpages-label": "頁面創建",
+       "rcfilters-filter-newpages-description": "創立新頁面的編緝。",
+       "rcfilters-filter-categorization-label": "分類變更",
        "rcnotefrom": "以下{{PLURAL:$5|為}}自 <strong>$3 $4</strong> 以來的變更 (最多顯示 <strong>$1</strong> 筆)。",
        "rclistfrom": "顯示自 $3 $2 以來的新變更",
        "rcshowhideminor": "$1 小修訂",
        "editcomment": "編輯摘要為:<em>$1</em>。",
        "revertpage": "已還原 [[Special:Contributions/$2|$2]] ([[User talk:$2|對話]]) 的編輯為最後由 [[User:$1|$1]] 所修訂的版本",
        "revertpage-nouser": "已還隱藏使用者的編輯為最後 {{GENDER:$1|[[User:$1|$1]]}} 修訂的版本",
-       "rollback-success": "已還原 $1 所做的編輯;\n變更回由 $2 修訂的最後一個版本。",
+       "rollback-success": "已還原 {{GENDER:$3|$1}} 所做的編輯;\n變更回由 {{GENDER:$4|$2}} 修訂的最後一個版本。",
        "rollback-success-notify": "已還原 $1 所做的編輯;\n變更回由 $2 修訂的最後一個版本。[$3 顯示變更]",
        "sessionfailure-title": "連線階段失敗",
        "sessionfailure": "您的登入連線階段似乎有問題,\n為了預防連線階段受到劫持攻擊,此動作已經被取消。\n請返回上一頁,重新讀取該頁面再試一次。",
        "mw-widgets-titleinput-description-new-page": "頁面不存在",
        "mw-widgets-titleinput-description-redirect": "重新導向至 $1",
        "mw-widgets-categoryselector-add-category-placeholder": "加入分類...",
+       "mw-widgets-usersmultiselect-placeholder": "添加更多...",
        "sessionmanager-tie": "無法合併多個請求認証類型:$1。",
        "sessionprovider-generic": "$1 連線階段",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "以 cookie 為基礎的連線階段",
index d99a721..8a43998 100644 (file)
@@ -317,7 +317,7 @@ $magicWords = [
        'pagesincategory_files'     => [ '0', 'فايلات', 'ملفات', 'files' ],
 ];
 
-// (bug 16469) Override Eastern Arabic numberals, use Western
+// (T18469) Override Eastern Arabic numberals, use Western
 $digitTransformTable = [
        '0' => '0',
        '1' => '1',
index 90f1128..94b0a34 100644 (file)
@@ -106,10 +106,10 @@ $specialPageAliases = [
        'Mostlinkedtemplates'       => [ 'Nejpoužívanější_šablony', 'Nejpouzivanejsi_sablony' ],
        'Mostrevisions'             => [ 'Stránky_s_nejvíce_editacemi', 'Stranky_s_nejvice_editacemi', 'Stránky_s_nejvyšším_počtem_editací' ],
        'Movepage'                  => [ 'Přesunout_stránku', 'Přejmenovat_stránku' ],
-       'Mycontributions'           => [ 'Mé_příspěvky', 'Me_prispevky' ],
+       'Mycontributions'           => [ 'Moje_příspěvky', 'Mé_příspěvky', 'Me_prispevky' ],
        'MyLanguage'                => [ 'V_mém_jazyce', 'Můj_jazyk' ],
-       'Mypage'                    => [ 'Moje_stránka', 'Moje_stranka' ],
-       'Mytalk'                    => [ 'Moje_diskuse' ],
+       'Mypage'                    => [ 'Moje_stránka', 'Moje_stranka', 'Má_stránka' ],
+       'Mytalk'                    => [ 'Moje_diskuse', 'Má_diskuse' ],
        'Myuploads'                 => [ 'Moje_soubory', 'Mé_soubory' ],
        'Newimages'                 => [ 'Nové_obrázky', 'Galerie_nových_obrázků', 'Nove_obrazky' ],
        'Newpages'                  => [ 'Nové_stránky', 'Nove_stranky', 'Nejnovější_stránky', 'Nejnovejsi_stranky' ],
index 689586b..b9280ea 100644 (file)
@@ -105,7 +105,7 @@ $namespaceAliases = [];
  * Example:
  * @code
  * $namespaceGenderAliases = [
- *     NS_USER => [ 'male' => 'Male_user', 'female' => 'Female_user' ],
+ *   NS_USER => [ 'male' => 'Male_user', 'female' => 'Female_user' ],
  * ];
  * @endcode
  */
index bf65812..c74d37b 100644 (file)
@@ -105,4 +105,4 @@ $magicWords = [
        'img_center'                => [ '1', 'erdian', 'center', 'centre' ],
 ];
 
-$separatorTransformTable = [ ',' => '.', '.' => ',' ]; /* Bug 15717 */
+$separatorTransformTable = [ ',' => '.', '.' => ',' ]; /* T17717 */
index 6281208..e034035 100644 (file)
@@ -28,5 +28,5 @@ $namespaceNames = [
        NS_CATEGORY_TALK    => 'Ñemohenda_myangekõi',
 ];
 
-// Remove Spanish gender aliases (bug 37090)
+// Remove Spanish gender aliases (T39090)
 $namespaceGenderAliases = [];
index 256abd7..d5f8f75 100644 (file)
@@ -8,7 +8,7 @@
  *
  */
 
-# $fallback = 'ru'; // bug 27785
+# $fallback = 'ru'; // T29785
 
 $namespaceNames = [
        NS_MEDIA            => 'Медиа',
index bb18959..f12be20 100644 (file)
@@ -70,7 +70,7 @@ $namespaceAliases = [
        'Diskusyón_de_Katēggoría'  => NS_CATEGORY_TALK,
 ];
 
-// Remove Spanish gender aliases (bug 37090)
+// Remove Spanish gender aliases (T39090)
 $namespaceGenderAliases = [];
 
 $specialPageAliases = [
index a44e0ac..6a71ca7 100644 (file)
@@ -18,5 +18,5 @@ $namespaceGenderAliases = [];
 
 $linkPrefixExtension = true;
 
-# Same as the French (bug 8485)
+# Same as the French (T10485)
 $separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
index 767a305..2aa25ad 100644 (file)
@@ -36,7 +36,7 @@ $namespaceNames = [
        NS_CATEGORY_TALK    => 'Neneuhcāyōtl_tēixnāmiquiliztli',
 ];
 
-// Remove Spanish gender aliases (bug 37090)
+// Remove Spanish gender aliases (T39090)
 $namespaceGenderAliases = [];
 
 $namespaceAliases = [
index d7b5bea..01a9d1a 100644 (file)
@@ -120,7 +120,7 @@ $dateFormats = [
 
 $fallback8bitEncoding = 'iso-8859-2';
 $separatorTransformTable = [
-       ',' => "\xc2\xa0", // @bug 2749
+       ',' => "\xc2\xa0", // T4749
        '.' => ','
 ];
 
index f020303..78503cc 100644 (file)
@@ -111,7 +111,7 @@ $dateFormats = [
 ];
 
 $separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
-$linkTrail = '/^([áâãàéêẽçíòóôõq̃úüűũa-z]+)(.*)$/sDu'; # Bug 21168, 27633
+$linkTrail = '/^([áâãàéêẽçíòóôõq̃úüűũa-z]+)(.*)$/sDu'; # T23168, T29633
 
 $specialPageAliases = [
        'Activeusers'               => [ 'Utilizadores_activos' ],
index d8282dc..8488159 100644 (file)
@@ -36,7 +36,7 @@ $namespaceNames = [
        NS_CATEGORY_TALK    => 'Katiguriya_rimanakuy',
 ];
 
-// Remove Spanish gender aliases (bug 37090)
+// Remove Spanish gender aliases (T39090)
 $namespaceGenderAliases = [];
 
 $specialPageAliases = [
index 523783e..e960abd 100644 (file)
@@ -32,5 +32,5 @@ $namespaceNames = [
        NS_CATEGORY_TALK    => 'Samiyachiy_rimanakuy',
 ];
 
-// Remove Spanish gender aliases (bug 37090)
+// Remove Spanish gender aliases (T39090)
 $namespaceGenderAliases = [];
index 01c33ee..d2ce357 100644 (file)
@@ -321,7 +321,7 @@ $magicWords = [
 
 $linkTrail = '/^([a-zåäöéÅÄÖÉ]+)(.*)$/sDu';
 $separatorTransformTable = [
-       ',' => "\xc2\xa0", // @bug 2749
+       ',' => "\xc2\xa0", // T4749
        '.' => ','
 ];
 
index 797e443..c30e963 100644 (file)
@@ -44,7 +44,7 @@ $namespaceNames = [
 ];
 
 $namespaceAliases = [
-       // Aliases for Polish namespaces (bug 34988).
+       // Aliases for Polish namespaces (T36988).
        'Specjalna'            => NS_SPECIAL,
        'Dyskusja'             => NS_TALK,
        'Użytkownik'           => NS_USER,
index 8e1020b..4f385cf 100644 (file)
@@ -50,7 +50,7 @@ $namespaceNames = [
 $namespaceAliases = [
        'సభ్యులు' => NS_USER,
        'సభ్యులపై_చర్చ' => NS_USER_TALK,
-       'సభ్యుడు' => NS_USER, # set for bug 11615
+       'సభ్యుడు' => NS_USER, # set for T13615
        'సభ్యునిపై_చర్చ' => NS_USER_TALK,
        'బొమ్మ' => NS_FILE,
        'బొమ్మపై_చర్చ' => NS_FILE_TALK,
index a7978be..f62614b 100644 (file)
@@ -20,7 +20,7 @@ $fallback = 'nl';
 
 /**
  * Namespace names
- * (bug 8708)
+ * (T10708)
  */
 $namespaceNames = [
        NS_MEDIA            => 'Media',
index ddd1d7b..08287cd 100644 (file)
@@ -1,7 +1,7 @@
 --
 -- patch-archive-ar_id.sql
 --
--- Bug 39675. Add archive.ar_id.
+-- T41675. Add archive.ar_id.
 
 ALTER TABLE /*$wgDBprefix*/archive
     ADD COLUMN ar_id int unsigned NOT NULL AUTO_INCREMENT FIRST,
index f5ff1f1..f8b6340 100644 (file)
@@ -1,11 +1,11 @@
 --
 -- patch-categorylinks-better-collation.sql
 --
--- Bugs 164, 1211, 23682.  This is the second version of this patch; the
+-- T2164, T3211, T25682.  This is the second version of this patch; the
 -- changes are also incorporated into patch-categorylinks-better-collation2.sql,
 -- for the benefit of trunk users who applied the original.
 --
--- Due to bug 25254, the length limit of 255 bytes for cl_sortkey_prefix
+-- Due to T27254, the length limit of 255 bytes for cl_sortkey_prefix
 -- is also enforced in php. If you change the length of that field, make
 -- sure to also change the check in LinksUpdate.php.
 ALTER TABLE /*$wgDBprefix*/categorylinks
index d4b51b5..ded8454 100644 (file)
@@ -1,7 +1,7 @@
 --
 -- patch-extenallinks-el_id.sql
 --
--- Bug 15441. Add externallinks.el_id.
+-- T17441. Add externallinks.el_id.
 
 ALTER TABLE /*$wgDBprefix*/externallinks
     ADD COLUMN el_id int unsigned NOT NULL AUTO_INCREMENT FIRST,
index 742841e..c516aaf 100644 (file)
@@ -1,4 +1,4 @@
--- Increase the length of up_property from 32 -> 255 bytes. Bug 19408
+-- Increase the length of up_property from 32 -> 255 bytes. T21408
 
 ALTER TABLE /*_*/user_properties
        MODIFY up_property varbinary(255);
index c92a720..b2f7e96 100644 (file)
@@ -41,7 +41,7 @@ class BenchUtf8TitleCheck extends Benchmarker {
                        "United States of America", // 7bit ASCII
                        "S%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e",
                        "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn",
-                       // This comes from bug 36839
+                       // This comes from T38839
                        "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn%7C"
                        . "Catherine%20Willows%7CDavid%20Hodges%7CDavid%20Phillips%7CGil%20Grissom%7CGreg%20Sanders%7CHodges%7C"
                        . "Internet%20Movie%20Database%7CJim%20Brass%7CLady%20Heather%7C"
index c8f393d..e0da027 100644 (file)
@@ -146,7 +146,7 @@ class ImageCleanup extends TableCleanup {
                 * if the target title exists in the image table, or if both the
                 * original and target titles exist in the page table, append
                 * increasing version numbers until the target title exists in
-                * neither.  (See also bug 16916.)
+                * neither.  (See also T18916.)
                 */
                $version = 0;
                $final = $new;
index 863d74a..83ab35c 100644 (file)
@@ -38,31 +38,43 @@ class CleanupRemovedModules extends Maintenance {
                parent::__construct();
                $this->addDescription(
                        'Remove cache entries for removed ResourceLoader modules from the database' );
-               $this->addOption( 'batchsize', 'Delete rows in batches of this size. Default: 500', false, true );
+               $this->setBatchSize( 500 );
        }
 
        public function execute() {
+               $this->output( "Cleaning up module_deps table...\n" );
+
                $dbw = $this->getDB( DB_MASTER );
                $rl = new ResourceLoader( MediaWikiServices::getInstance()->getMainConfig() );
                $moduleNames = $rl->getModuleNames();
-               $moduleList = implode( ', ', array_map( [ $dbw, 'addQuotes' ], $moduleNames ) );
-               $limit = max( 1, intval( $this->getOption( 'batchsize', 500 ) ) );
+               $res = $dbw->select( 'module_deps',
+                       [ 'md_module', 'md_skin' ],
+                       $moduleNames ? 'md_module NOT IN (' . $dbw->makeList( $moduleNames ) . ')' : '1=1',
+                       __METHOD__
+               );
+               $rows = iterator_to_array( $res, false );
 
-               $this->output( "Cleaning up module_deps table...\n" );
-               $i = 1;
                $modDeps = $dbw->tableName( 'module_deps' );
-               do {
-                       // $dbw->delete() doesn't support LIMIT :(
-                       $where = $moduleList ? "md_module NOT IN ($moduleList)" : '1=1';
-                       $dbw->query( "DELETE FROM $modDeps WHERE $where LIMIT $limit", __METHOD__ );
+               $i = 1;
+               foreach ( array_chunk( $rows, $this->mBatchSize ) as $chunk ) {
+                       // WHERE ( mod=A AND skin=A ) OR ( mod=A AND skin=B) ..
+                       $conds = array_map( function ( stdClass $row ) use ( $dbw ) {
+                               return $dbw->makeList( (array)$row, IDatabase::LIST_AND );
+                       }, $chunk );
+                       $conds = $dbw->makeList( $conds, IDatabase::LIST_OR );
+
+                       $this->beginTransaction( $dbw, __METHOD__ );
+                       $dbw->query( "DELETE FROM $modDeps WHERE $conds", __METHOD__ );
                        $numRows = $dbw->affectedRows();
                        $this->output( "Batch $i: $numRows rows\n" );
+                       $this->commitTransaction( $dbw, __METHOD__ );
+
                        $i++;
-                       wfWaitForSlaves();
-               } while ( $numRows > 0 );
-               $this->output( "done\n" );
+               }
+
+               $this->output( "Done\n" );
        }
 }
 
-$maintClass = "CleanupRemovedModules";
+$maintClass = 'CleanupRemovedModules';
 require_once RUN_MAINTENANCE_IF_MAIN;
index 650fae0..ccc6406 100644 (file)
@@ -138,14 +138,14 @@ class TitleCleanup extends TableCleanup {
                                $prior = $title->getDBkey();
                        }
 
-                       # Old cleanupTitles could move articles there. See bug 23147.
+                       # Old cleanupTitles could move articles there. See T25147.
                        $ns = $row->page_namespace;
                        if ( $ns < 0 ) {
                                $ns = 0;
                        }
 
                        # Namespace which no longer exists. Put the page in the main namespace
-                       # since we don't have any idea of the old namespace name. See bug 68501.
+                       # since we don't have any idea of the old namespace name. See T70501.
                        if ( !MWNamespace::exists( $ns ) ) {
                                $ns = 0;
                        }
index b8001a4..70f3654 100644 (file)
@@ -23,6 +23,8 @@
 
 require_once __DIR__ . '/Maintenance.php';
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * Maintenance script to convert user options to the new `user_properties` table.
  *
index 1d6f31d..79f75ef 100644 (file)
@@ -72,7 +72,7 @@ class FixDoubleRedirects extends Maintenance {
                        'rd_from = pa.page_id',
                        'rd_namespace = pb.page_namespace',
                        'rd_title = pb.page_title',
-                       'rd_interwiki IS NULL OR rd_interwiki = ' . $dbr->addQuotes( '' ), // bug 40352
+                       'rd_interwiki IS NULL OR rd_interwiki = ' . $dbr->addQuotes( '' ), // T42352
                        'pb.page_is_redirect' => 1,
                ];
 
index 87af5b8..fb00bed 100644 (file)
@@ -523,7 +523,7 @@ class GenerateSitemap extends Maintenance {
        function fileEntry( $url, $date, $priority ) {
                return
                        "\t<url>\n" .
-                       // bug 34666: $url may contain bad characters such as ampersands.
+                       // T36666: $url may contain bad characters such as ampersands.
                        "\t\t<loc>" . htmlspecialchars( $url ) . "</loc>\n" .
                        "\t\t<lastmod>$date</lastmod>\n" .
                        "\t\t<priority>$priority</priority>\n" .
@@ -545,7 +545,7 @@ class GenerateSitemap extends Maintenance {
         * @param int $namespace
         */
        function generateLimit( $namespace ) {
-               // bug 17961: make a title with the longest possible URL in this namespace
+               // T19961: make a title with the longest possible URL in this namespace
                $title = Title::makeTitle( $namespace, str_repeat( "\xf0\xa8\xae\x81", 63 ) . "\xe5\x96\x83" );
 
                $this->limit = [
index a0fe381..2a102b2 100644 (file)
@@ -106,7 +106,7 @@ class HHVMMakeRepo extends Maintenance {
                $cmd = wfEscapeShellArg(
                        $hhvm,
                        '--hphp',
-                   '--target', 'hhbc',
+                       '--target', 'hhbc',
                        '--format', 'binary',
                        '--force', '1',
                        '--keep-tempdir', '1',
index 4a3d2d6..23bdb3f 100644 (file)
@@ -497,7 +497,7 @@ class ImportImages extends Maintenance {
        # (preferably batching files too).
        private function getFileCommentFromSourceWiki( $wiki_host, $file ) {
                $url = $wiki_host . '/api.php?action=query&format=xml&titles=File:'
-                          . rawurlencode( $file ) . '&prop=imageinfo&&iiprop=comment';
+                       . rawurlencode( $file ) . '&prop=imageinfo&&iiprop=comment';
                $body = Http::get( $url, [], __METHOD__ );
                if ( preg_match( '#<ii comment="([^"]*)" />#', $body, $matches ) == 0 ) {
                        return false;
@@ -508,7 +508,7 @@ class ImportImages extends Maintenance {
 
        private function getFileUserFromSourceWiki( $wiki_host, $file ) {
                $url = $wiki_host . '/api.php?action=query&format=xml&titles=File:'
-                          . rawurlencode( $file ) . '&prop=imageinfo&&iiprop=user';
+                       . rawurlencode( $file ) . '&prop=imageinfo&&iiprop=user';
                $body = Http::get( $url, [], __METHOD__ );
                if ( preg_match( '#<ii user="([^"]*)" />#', $body, $matches ) == 0 ) {
                        return false;
diff --git a/maintenance/initUserPreference.php b/maintenance/initUserPreference.php
new file mode 100644 (file)
index 0000000..f4da570
--- /dev/null
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Initialize a user preference based on the value
+ * of another preference.
+ *
+ * @ingroup Maintenance
+ */
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Maintenance script that initializes a user preference
+ * based on the value of another preference.
+ *
+ * @ingroup Maintenance
+ */
+class InitUserPreference extends Maintenance {
+       public function __construct() {
+               parent::__construct();
+               $this->addOption(
+                       'target',
+                       'Name of the user preference to initialize',
+                       true,
+                       true,
+                       't'
+               );
+               $this->addOption(
+                       'source',
+                       'Name of the user preference to take the value from',
+                       true,
+                       true,
+                       's'
+               );
+               $this->setBatchSize( 300 );
+       }
+
+       public function execute() {
+               $target = $this->getOption( 'target' );
+               $source = $this->getOption( 'source' );
+               $this->output( "Initializing '$target' based on the value of '$source'\n" );
+
+               $dbr = $this->getDB( DB_REPLICA );
+               $dbw = $this->getDB( DB_MASTER );
+
+               $iterator = new BatchRowIterator(
+                       $dbr,
+                       'user_properties',
+                       [ 'up_user', 'up_property' ],
+                       $this->mBatchSize
+               );
+               $iterator->setFetchColumns( [ 'up_user', 'up_value' ] );
+               $iterator->addConditions( [
+                       'up_property' => $source,
+                       'up_value IS NOT NULL',
+                       'up_value != 0',
+               ] );
+
+               $processed = 0;
+               foreach ( $iterator as $batch ) {
+                       foreach ( $batch as $row ) {
+                               $values = [
+                                       'up_user' => $row->up_user,
+                                       'up_property' => $target,
+                                       'up_value' => $row->up_value,
+                               ];
+                               $dbw->upsert(
+                                       'user_properties',
+                                       $values,
+                                       [ 'up_user', 'up_property' ],
+                                       $values,
+                                       __METHOD__
+                               );
+
+                               $processed += $dbw->affectedRows();
+                       }
+               }
+
+               $this->output( "Processed $processed user(s)\n" );
+               $this->output( "Finished!\n" );
+       }
+}
+
+$maintClass = 'InitUserPreference'; // Tells it to run the class
+require_once RUN_MAINTENANCE_IF_MAIN;
index ed94fc8..6975e25 100644 (file)
 奈及利亞   尼日利亚
 尼日爾      尼日尔
 巴貝多      巴巴多斯
-巴布亞紐幾內亞  巴布亚新几内亚
 布吉納法索        布基纳法索
 蒲隆地      布隆迪
 帛琉 帕劳
 厄利垂亚   厄立特里亚
 亞歷山卓   亚历山大
 雅穆索戈   亚穆苏克罗
-畿內亞      几内亚
 索馬利蘭   索马里兰
 吉力馬札羅        乞力马扎罗
 索馬利亞   索马里
 千里達      特立尼达
 托巴哥      多巴哥
 多明尼加   多米尼加
+斯堪地那維亞     斯堪的纳维亚
 頻寬 带宽
 數位相機   数码相机
 數位照相機        数码照相机
index d21ba55..7a07259 100644 (file)
@@ -10,6 +10,7 @@
 計畫 計劃
 吧台 吧枱
 坐台 坐枱
+坐台铁      坐台鐵
 妆台 妝枱
 弹珠台      彈珠枱
 折台 摺枱
 占有五不   占有五不
 吞占 吞佔
 一地里      一地裏
-一年里      一年裏
 中文里      中文裏
 英文里      英文裏
 古文里      古文裏
 市里的      市裏的
 年代里      年代裏
 年里 年裏
+年里约      年里約 #里约奧運
 店里 店裏
 庙里 廟裏
 往里 往裏
 点里 點裏
 点里程      點里程
 鼓里 鼓裏
+殿里 殿裏
+队里 隊裏
 世纪里      世紀裏
 夜晚里      夜晚裏
 参数里      參數裏
 塞席爾      塞舌爾
 安地卡及巴布達  安提瓜和巴布達
 巴貝多      巴巴多斯
-巴布亞紐幾內亞  巴布亞新畿內亞
+紐幾內亞   新幾內亞
 布吉納法索        布基納法索
 蒲隆地      布隆迪
 帕劳 帛琉
 阿拉伯聯合大公國       阿拉伯聯合酋長國
 馬爾地夫   馬爾代夫
 馬利共和國        馬里共和國
+斯堪地那維亞     斯堪的納維亞
 台球 桌球
 撞球 桌球
 冰淇淋      雪糕
 亞斯文      阿斯旺
 奈及利亞   尼日利亞
 雅穆索戈   雅穆蘇克雷
-幾內亞      畿內亞
-几内亚      畿內亞
 衣索匹亞   埃塞俄比亚
 吉力馬札羅        乞力馬札羅
 厄利垂亚   厄立特里亞
index 4df3f02..6f3304f 100644 (file)
@@ -75,6 +75,7 @@
 於梨华      於梨华
 於潜 於潜
 於志贺      於志贺
+於戏 於戏
 憑藉 凭借
 藉端 借端
 藉故 借故
index bc99cfa..d983932 100644 (file)
 尼日尔      尼日
 尼日爾      尼日
 巴巴多斯   巴貝多
-巴布亚新几内亚  巴布亞紐幾內亞
-巴布亞新畿內亞  巴布亞紐幾內亞
 布基纳法索        布吉納法索
 布基納法索        布吉納法索
 布隆迪      蒲隆地
 波利尼西亚        玻里尼西亞
 波利尼西亞        玻里尼西亞
 新几内亚   紐幾內亞
+新幾內亞   紐幾內亞
 约翰斯顿岛        強斯頓環礁
 巴尔米拉环礁     帕邁拉環礁
 马恩岛      曼島
 阿斯旺      亞斯文
 雅穆苏克雷        雅穆索戈
 雅穆蘇克雷        雅穆索戈
-畿內亞      幾內亞
 索马里兰   索馬利蘭
 索馬里蘭   索馬利蘭
 乞力马扎罗        吉力馬札羅
 得克薩斯   德克薩斯
 蒙特利尔   蒙特婁
 蒙特利爾   蒙特婁
+斯堪的纳维亚     斯堪地那維亞
+斯堪的納維亞     斯堪地那維亞
 麦克尔      麥可
 迈克尔      麥可
 魯賓斯·巴里切羅        魯本·巴瑞切羅
index 21946a1..4effa8e 100644 (file)
 布穀鳥
 穀祿
 穀城縣
+穀氨
+穀胱
 颳雪
 广部
 亂鬨鬨
 喧鬨
 起鬨
 內鬨
-於後
 猜三划五
 划龍舟
 划龍船
 叶韻
 叶音
 叶恭弘
-置於
-散於
-播於
-國於
-敗於
-畢於
-畢業於
-寒於
-任於
-拘於
-插於
-中於
-敏於
-聽於
-短於
-成於
-樊於期
-淡於
-禍於
-格於
-猛於
-施於
-拒人於
-拒於
-潰於
-窮於
-相於
-形於
-半於
-詢於
-美於
-醜於
-好於
-坏於
-強於
-弱於
-差於
-劣於
-染指於
-存於
-隱於
-藏於
-嚴於
-寬於
-給於
-危於
-於徵
-離於
-麗於
-下於
-亞於
-同於
-屑於
-絕於
-致於
-遜於
-任教於
-教於
-自於
-來於
-附於
-阻於
-囿於
-直於
-建於
-都於
-役於
-助於
-害於
-損於
-益於
-從於
-隨於
-順於
-汲於
-溺於
-迷於
-醉於
-行於
-泥於
-身於
-足於
-溢於
-畏於
-視於
-衷於
-狃於
-疲於
-通於
-老於
-耿於
-服於
-臻於
-匿於
-因於
-似於
-遷於
-怒於
-心於
-集於
-容於
 新紮
 紙紮
 紮鐵
 影相弔
 哀弔
 唁弔
-安於
-迫於
-罷於
-蹪於
-甚於
-等於
-定於
-利於
-對於
-歸於
-難於
-移禍於
-生於
-立於
-多於
-勝於
-傳於
-流於
-過於
-關於
-毀於
-基於
-急於
-嫁禍於
-見於
-鑒於
-始於
-出於
-輕於
-幸於
-怠於
-止於
-至於
-拙於
-忠於
-終於
-重於
-垂於
-善於
-死於
-屬於
-浮於
-在於
-易於
-精於
-由於
-補於
-位於
-寓於
-源於
-且於
-長於
-現於
-較於
-分布於
-散於
-優於
-早於
-晚於
-感於
-用於
-處於
-助於
-便於
-戰於
-葬於
-困於
-適於
-苦於
-落於
-取決於
-着眼於
 鬼谷子
 谷子敬
 洪谷子
 瑞城里
 金城里
 西湖里
+坑口里
 子里甲
 水里商工
 車里雅賓斯克
 區裡有
 實驗裡
 註裡
+殿裡
+隊裡
 裏白 #植物常用名
 烏蘇里 #分詞用
 首發
 高后
 升高後
 提高後
-0年 # 協助分詞
-1年
-2年
-3年
-4年
-5年
-6年
-7年
-8年
-9年
-〇年
-零年
-一年
-兩年
-二年
-三年
-四年
-五年
-六年
-七年
-八年
-九年
-十年
-百年
-千年
-萬年
-億年
 周后
 0周後
 1周後
 伊達里子
 濱田里佳子
 王田里
+田里穗
 小井里
 西井里
 碧河里
 吧檯
 賭檯
 坐檯
+坐台鐵
 妝檯
 餐檯
 工作檯
index eda0939..e6aac9c 100644 (file)
 颳去
 刮去
 么
+換髮
+谷氨酸
+幸免於難
+勝于
+善于
+安于
+寓于
+對于
+屬于
+忠于
+急于
+歸于
+生于
+由于
+終于
+見于
+過于
+長于
+關于
+難于
index 396be1d..597a876 100644 (file)
@@ -79,7 +79,7 @@ class MigrateUserGroup extends Maintenance {
                        $affected += $dbw->affectedRows();
                        $this->commitTransaction( $dbw, __METHOD__ );
 
-                       // Clear cache for the affected users (bug 40340)
+                       // Clear cache for the affected users (T42340)
                        if ( $affected > 0 ) {
                                // XXX: This also invalidates cache of unaffected users that
                                // were in the new group and not in the group.
index 1c633be..78f0671 100644 (file)
@@ -301,7 +301,7 @@ CREATE TABLE /*_*/categorylinks (
   -- conversion algorithm is run.  We store this so that we can update
   -- collations without reparsing all pages.
   -- Note: If you change the length of this field, you also need to change
-  -- code in LinksUpdate.php. See bug 25254.
+  -- code in LinksUpdate.php. See T27254.
   cl_sortkey_prefix varbinary(255) NOT NULL default 0x,
 
   -- This isn't really used at present. Provided for an optional
@@ -528,7 +528,7 @@ CREATE TABLE /*_*/ipblocks (
   -- Size chosen to allow IPv6
   -- FIXME: these fields were originally blank for single-IP blocks,
   -- but now they are populated. No migration was ever done. They
-  -- should be fixed to be blank again for such blocks (bug 49504).
+  -- should be fixed to be blank again for such blocks (T51504).
   ipb_range_start varchar(255) NOT NULL,
   ipb_range_end varchar(255) NOT NULL,
 
index 522871d..80e8011 100644 (file)
@@ -26,6 +26,7 @@
 
 use MediaWiki\Linker\LinkTarget;
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\ResultWrapper;
 
 require_once __DIR__ . '/Maintenance.php';
 
@@ -571,7 +572,7 @@ class NamespaceConflictChecker extends Maintenance {
        /**
         * Merge page histories
         *
-        * @param integer $id The page_id
+        * @param stdClass $row Page row
         * @param Title $newTitle The new title
         * @return bool
         */
index 5e44faf..a9457c2 100644 (file)
@@ -136,7 +136,7 @@ class PopulateRevisionLength extends LoggedUpdateMaintenance {
 
                $content = $rev->getContent();
                if ( !$content ) {
-                       # This should not happen, but sometimes does (bug 20757)
+                       # This should not happen, but sometimes does (T22757)
                        $id = $row->$idCol;
                        $this->output( "Content of $table $id unavailable!\n" );
 
index 095c266..fb97e91 100644 (file)
@@ -156,10 +156,10 @@ class PopulateRevisionSha1 extends LoggedUpdateMaintenance {
                } catch ( Exception $e ) {
                        $this->output( "Data of revision with {$idCol}={$row->$idCol} unavailable!\n" );
 
-                       return false; // bug 22624?
+                       return false; // T24624?
                }
                if ( !is_string( $text ) ) {
-                       # This should not happen, but sometimes does (bug 20757)
+                       # This should not happen, but sometimes does (T22757)
                        $this->output( "Data of revision with {$idCol}={$row->$idCol} unavailable!\n" );
 
                        return false;
@@ -185,11 +185,11 @@ class PopulateRevisionSha1 extends LoggedUpdateMaintenance {
                } catch ( Exception $e ) {
                        $this->output( "Text of revision with timestamp {$row->ar_timestamp} unavailable!\n" );
 
-                       return false; // bug 22624?
+                       return false; // T24624?
                }
                $text = $rev->getSerializedData();
                if ( !is_string( $text ) ) {
-                       # This should not happen, but sometimes does (bug 20757)
+                       # This should not happen, but sometimes does (T22757)
                        $this->output( "Data of revision with timestamp {$row->ar_timestamp} unavailable!\n" );
 
                        return false;
index b354399..cf65c69 100644 (file)
@@ -23,6 +23,8 @@
 
 require_once __DIR__ . '/Maintenance.php';
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * Maintenance script that sends purge requests for pages edited in a date
  * range to squid/varnish.
diff --git a/maintenance/purgeModuleDeps.php b/maintenance/purgeModuleDeps.php
new file mode 100644 (file)
index 0000000..3088baa
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Remove all cache entries for ResourceLoader modules from the database.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Maintenance
+ * @author Timo Tijhof
+ */
+
+use MediaWiki\MediaWikiServices;
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Maintenance script to purge the module_deps database cache table.
+ *
+ * @ingroup Maintenance
+ */
+class PurgeModuleDeps extends Maintenance {
+       public function __construct() {
+               parent::__construct();
+               $this->addDescription(
+                       'Remove all cache entries for ResourceLoader modules from the database' );
+               $this->setBatchSize( 500 );
+       }
+
+       public function execute() {
+               $this->output( "Cleaning up module_deps table...\n" );
+
+               $dbw = $this->getDB( DB_MASTER );
+               $res = $dbw->select( 'module_deps', [ 'md_module', 'md_skin' ], [], __METHOD__ );
+               $rows = iterator_to_array( $res, false );
+
+               $modDeps = $dbw->tableName( 'module_deps' );
+               $i = 1;
+               foreach ( array_chunk( $rows, $this->mBatchSize ) as $chunk ) {
+                       // WHERE ( mod=A AND skin=A ) OR ( mod=A AND skin=B) ..
+                       $conds = array_map( function ( stdClass $row ) use ( $dbw ) {
+                               return $dbw->makeList( (array)$row, IDatabase::LIST_AND );
+                       }, $chunk );
+                       $conds = $dbw->makeList( $conds, IDatabase::LIST_OR );
+
+                       $this->beginTransaction( $dbw, __METHOD__ );
+                       $dbw->query( "DELETE FROM $modDeps WHERE $conds", __METHOD__ );
+                       $numRows = $dbw->affectedRows();
+                       $this->output( "Batch $i: $numRows rows\n" );
+                       $this->commitTransaction( $dbw, __METHOD__ );
+
+                       $i++;
+               }
+
+               $this->output( "Done\n" );
+       }
+}
+
+$maintClass = 'PurgeModuleDeps';
+require_once RUN_MAINTENANCE_IF_MAIN;
index d073282..3520279 100644 (file)
@@ -140,7 +140,7 @@ class RebuildFileCache extends Maintenance {
 
                                        MediaWiki\suppressWarnings(); // header notices
                                        // Cache ?action=view
-                                       $wgRequestTime = microtime( true ); # bug 22852
+                                       $wgRequestTime = microtime( true ); # T24852
                                        ob_start();
                                        $article->view();
                                        $context->getOutput()->output();
@@ -148,7 +148,7 @@ class RebuildFileCache extends Maintenance {
                                        $viewHtml = ob_get_clean();
                                        $viewCache->saveToFileCache( $viewHtml );
                                        // Cache ?action=history
-                                       $wgRequestTime = microtime( true ); # bug 22852
+                                       $wgRequestTime = microtime( true ); # T24852
                                        ob_start();
                                        Action::factory( 'history', $article, $context )->show();
                                        $context->getOutput()->output();
index fb24a1d..06fcbaf 100644 (file)
@@ -272,7 +272,9 @@ class RefreshLinks extends Maintenance {
                        return;
                }
 
-               foreach ( $content->getSecondaryDataUpdates( $page->getTitle() ) as $update ) {
+               $updates = $content->getSecondaryDataUpdates(
+                       $page->getTitle(), /* $old = */ null, /* $recursive = */ false );
+               foreach ( $updates as $update ) {
                        DeferredUpdates::addUpdate( $update );
                }
        }
index cc976ed..58472e9 100644 (file)
@@ -24,6 +24,8 @@
 
 require_once __DIR__ . '/Maintenance.php';
 
+use Wikimedia\Rdbms\ResultWrapper;
+
 /**
  * Maintenance script that sends SQL queries from the specified file to the database.
  *
@@ -50,7 +52,7 @@ class MwSql extends Maintenance {
                $wiki = $this->hasOption( 'wikidb' ) ? $this->getOption( 'wikidb' ) : false;
                // Get the appropriate load balancer (for this wiki)
                if ( $this->hasOption( 'cluster' ) ) {
-                       $lb = wfGetLBFactory()->getExternalLB( $this->getOption( 'cluster' ), $wiki );
+                       $lb = wfGetLBFactory()->getExternalLB( $this->getOption( 'cluster' ) );
                } else {
                        $lb = wfGetLB( $wiki );
                }
@@ -137,7 +139,7 @@ class MwSql extends Maintenance {
                        }
                        if ( $historyFile ) {
                                # Delimiter is eated by streamStatementEnd, we add it
-                               # up in the history (bug 37020)
+                               # up in the history (T39020)
                                readline_add_history( $wholeLine . ';' );
                                readline_write_history( $historyFile );
                        }
@@ -159,7 +161,7 @@ class MwSql extends Maintenance {
 
        /**
         * Print the results, callback for $db->sourceStream()
-        * @param ResultWrapper $res The results object
+        * @param ResultWrapper|bool $res The results object
         * @param IDatabase $db
         */
        public function sqlPrintResult( $res, $db ) {
index f322a03..2d0c9ee 100644 (file)
@@ -3,7 +3,7 @@
 -- Unique indexes need to be handled with INSERT SELECT since just running
 -- the CREATE INDEX statement will fail if there are duplicate values.
 --
--- Ignore duplicates, several tables will have them (e.g. bug 16966) but in
+-- Ignore duplicates, several tables will have them (e.g. T18966) but in
 -- most cases it's harmless to discard them.
 
 --------------------------------------------------------------------------------
diff --git a/maintenance/storage/fixBug20757.php b/maintenance/storage/fixBug20757.php
deleted file mode 100644 (file)
index b444f31..0000000
+++ /dev/null
@@ -1,349 +0,0 @@
-<?php
-/**
- * Script to fix bug 20757.
- *
- * 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 ExternalStorage
- */
-
-require_once __DIR__ . '/../Maintenance.php';
-
-/**
- * Maintenance script to fix bug 20757.
- *
- * @ingroup Maintenance ExternalStorage
- */
-class FixBug20757 extends Maintenance {
-       public $batchSize = 10000;
-       public $mapCache = [];
-       public $mapCacheSize = 0;
-       public $maxMapCacheSize = 1000000;
-
-       function __construct() {
-               parent::__construct();
-               $this->addDescription( 'Script to fix bug 20757 assuming that blob_tracking is intact' );
-               $this->addOption( 'dry-run', 'Report only' );
-               $this->addOption( 'start', 'old_id to start at', false, true );
-       }
-
-       function execute() {
-               $dbr = $this->getDB( DB_REPLICA );
-               $dbw = $this->getDB( DB_MASTER );
-
-               $dryRun = $this->getOption( 'dry-run' );
-               if ( $dryRun ) {
-                       print "Dry run only.\n";
-               }
-
-               $startId = $this->getOption( 'start', 0 );
-               $numGood = 0;
-               $numFixed = 0;
-               $numBad = 0;
-
-               $totalRevs = $dbr->selectField( 'text', 'MAX(old_id)', false, __METHOD__ );
-
-               // In MySQL 4.1+, the binary field old_text has a non-working LOWER() function
-               $lowerLeft = 'LOWER(CONVERT(LEFT(old_text,22) USING latin1))';
-
-               while ( true ) {
-                       print "ID: $startId / $totalRevs\r";
-
-                       $res = $dbr->select(
-                               'text',
-                               [ 'old_id', 'old_flags', 'old_text' ],
-                               [
-                                       'old_id > ' . intval( $startId ),
-                                       'old_flags LIKE \'%object%\' AND old_flags NOT LIKE \'%external%\'',
-                                       "$lowerLeft = 'o:15:\"historyblobstub\"'",
-                               ],
-                               __METHOD__,
-                               [
-                                       'ORDER BY' => 'old_id',
-                                       'LIMIT' => $this->batchSize,
-                               ]
-                       );
-
-                       if ( !$res->numRows() ) {
-                               break;
-                       }
-
-                       $secondaryIds = [];
-                       $stubs = [];
-
-                       foreach ( $res as $row ) {
-                               $startId = $row->old_id;
-
-                               // Basic sanity checks
-                               $obj = unserialize( $row->old_text );
-                               if ( $obj === false ) {
-                                       print "{$row->old_id}: unrecoverable: cannot unserialize\n";
-                                       ++$numBad;
-                                       continue;
-                               }
-
-                               if ( !is_object( $obj ) ) {
-                                       print "{$row->old_id}: unrecoverable: unserialized to type " .
-                                               gettype( $obj ) . ", possible double-serialization\n";
-                                       ++$numBad;
-                                       continue;
-                               }
-
-                               if ( strtolower( get_class( $obj ) ) !== 'historyblobstub' ) {
-                                       print "{$row->old_id}: unrecoverable: unexpected object class " .
-                                               get_class( $obj ) . "\n";
-                                       ++$numBad;
-                                       continue;
-                               }
-
-                               // Process flags
-                               $flags = explode( ',', $row->old_flags );
-                               if ( in_array( 'utf-8', $flags ) || in_array( 'utf8', $flags ) ) {
-                                       $legacyEncoding = false;
-                               } else {
-                                       $legacyEncoding = true;
-                               }
-
-                               // Queue the stub for future batch processing
-                               $id = intval( $obj->mOldId );
-                               $secondaryIds[] = $id;
-                               $stubs[$row->old_id] = [
-                                       'legacyEncoding' => $legacyEncoding,
-                                       'secondaryId' => $id,
-                                       'hash' => $obj->mHash,
-                               ];
-                       }
-
-                       $secondaryIds = array_unique( $secondaryIds );
-
-                       if ( !count( $secondaryIds ) ) {
-                               continue;
-                       }
-
-                       // Run the batch query on blob_tracking
-                       $res = $dbr->select(
-                               'blob_tracking',
-                               '*',
-                               [
-                                       'bt_text_id' => $secondaryIds,
-                               ],
-                               __METHOD__
-                       );
-                       $trackedBlobs = [];
-                       foreach ( $res as $row ) {
-                               $trackedBlobs[$row->bt_text_id] = $row;
-                       }
-
-                       // Process the stubs
-                       foreach ( $stubs as $primaryId => $stub ) {
-                               $secondaryId = $stub['secondaryId'];
-                               if ( !isset( $trackedBlobs[$secondaryId] ) ) {
-                                       // No tracked blob. Work out what went wrong
-                                       $secondaryRow = $dbr->selectRow(
-                                               'text',
-                                               [ 'old_flags', 'old_text' ],
-                                               [ 'old_id' => $secondaryId ],
-                                               __METHOD__
-                                       );
-                                       if ( !$secondaryRow ) {
-                                               print "$primaryId: unrecoverable: secondary row is missing\n";
-                                               ++$numBad;
-                                       } elseif ( $this->isUnbrokenStub( $stub, $secondaryRow ) ) {
-                                               // Not broken yet, and not in the tracked clusters so it won't get
-                                               // broken by the current RCT run.
-                                               ++$numGood;
-                                       } elseif ( strpos( $secondaryRow->old_flags, 'external' ) !== false ) {
-                                               print "$primaryId: unrecoverable: secondary gone to {$secondaryRow->old_text}\n";
-                                               ++$numBad;
-                                       } else {
-                                               print "$primaryId: unrecoverable: miscellaneous corruption of secondary row\n";
-                                               ++$numBad;
-                                       }
-                                       unset( $stubs[$primaryId] );
-                                       continue;
-                               }
-                               $trackRow = $trackedBlobs[$secondaryId];
-
-                               // Check that the specified text really is available in the tracked source row
-                               $url = "DB://{$trackRow->bt_cluster}/{$trackRow->bt_blob_id}/{$stub['hash']}";
-                               $text = ExternalStore::fetchFromURL( $url );
-                               if ( $text === false ) {
-                                       print "$primaryId: unrecoverable: source text missing\n";
-                                       ++$numBad;
-                                       unset( $stubs[$primaryId] );
-                                       continue;
-                               }
-                               if ( md5( $text ) !== $stub['hash'] ) {
-                                       print "$primaryId: unrecoverable: content hashes do not match\n";
-                                       ++$numBad;
-                                       unset( $stubs[$primaryId] );
-                                       continue;
-                               }
-
-                               // Find the page_id and rev_id
-                               // The page is probably the same as the page of the secondary row
-                               $pageId = intval( $trackRow->bt_page );
-                               if ( !$pageId ) {
-                                       $revId = $pageId = 0;
-                               } else {
-                                       $revId = $this->findTextIdInPage( $pageId, $primaryId );
-                                       if ( !$revId ) {
-                                               // Actually an orphan
-                                               $pageId = $revId = 0;
-                                       }
-                               }
-
-                               $newFlags = $stub['legacyEncoding'] ? 'external' : 'external,utf-8';
-
-                               if ( !$dryRun ) {
-                                       // Reset the text row to point to the original copy
-                                       $this->beginTransaction( $dbw, __METHOD__ );
-                                       $dbw->update(
-                                               'text',
-                                               // SET
-                                               [
-                                                       'old_flags' => $newFlags,
-                                                       'old_text' => $url
-                                               ],
-                                               // WHERE
-                                               [ 'old_id' => $primaryId ],
-                                               __METHOD__
-                                       );
-
-                                       // Add a blob_tracking row so that the new reference can be recompressed
-                                       // without needing to run trackBlobs.php again
-                                       $dbw->insert( 'blob_tracking',
-                                               [
-                                                       'bt_page' => $pageId,
-                                                       'bt_rev_id' => $revId,
-                                                       'bt_text_id' => $primaryId,
-                                                       'bt_cluster' => $trackRow->bt_cluster,
-                                                       'bt_blob_id' => $trackRow->bt_blob_id,
-                                                       'bt_cgz_hash' => $stub['hash'],
-                                                       'bt_new_url' => null,
-                                                       'bt_moved' => 0,
-                                               ],
-                                               __METHOD__
-                                       );
-                                       $this->commitTransaction( $dbw, __METHOD__ );
-                                       $this->waitForSlaves();
-                               }
-
-                               print "$primaryId: resolved to $url\n";
-                               ++$numFixed;
-                       }
-               }
-
-               print "\n";
-               print "Fixed: $numFixed\n";
-               print "Unrecoverable: $numBad\n";
-               print "Good stubs: $numGood\n";
-       }
-
-       function waitForSlaves() {
-               static $iteration = 0;
-               ++$iteration;
-               if ( ++$iteration > 50 == 0 ) {
-                       wfWaitForSlaves();
-                       $iteration = 0;
-               }
-       }
-
-       function findTextIdInPage( $pageId, $textId ) {
-               $ids = $this->getRevTextMap( $pageId );
-               if ( !isset( $ids[$textId] ) ) {
-                       return null;
-               } else {
-                       return $ids[$textId];
-               }
-       }
-
-       function getRevTextMap( $pageId ) {
-               if ( !isset( $this->mapCache[$pageId] ) ) {
-                       // Limit cache size
-                       while ( $this->mapCacheSize > $this->maxMapCacheSize ) {
-                               $key = key( $this->mapCache );
-                               $this->mapCacheSize -= count( $this->mapCache[$key] );
-                               unset( $this->mapCache[$key] );
-                       }
-
-                       $dbr = $this->getDB( DB_REPLICA );
-                       $map = [];
-                       $res = $dbr->select( 'revision',
-                               [ 'rev_id', 'rev_text_id' ],
-                               [ 'rev_page' => $pageId ],
-                               __METHOD__
-                       );
-                       foreach ( $res as $row ) {
-                               $map[$row->rev_text_id] = $row->rev_id;
-                       }
-                       $this->mapCache[$pageId] = $map;
-                       $this->mapCacheSize += count( $map );
-               }
-
-               return $this->mapCache[$pageId];
-       }
-
-       /**
-        * This is based on part of HistoryBlobStub::getText().
-        * Determine if the text can be retrieved from the row in the normal way.
-        * @param array $stub
-        * @param stdClass $secondaryRow
-        * @return bool
-        */
-       function isUnbrokenStub( $stub, $secondaryRow ) {
-               $flags = explode( ',', $secondaryRow->old_flags );
-               $text = $secondaryRow->old_text;
-               if ( in_array( 'external', $flags ) ) {
-                       $url = $text;
-                       MediaWiki\suppressWarnings();
-                       list( /* $proto */, $path ) = explode( '://', $url, 2 );
-                       MediaWiki\restoreWarnings();
-
-                       if ( $path == "" ) {
-                               return false;
-                       }
-                       $text = ExternalStore::fetchFromURL( $url );
-               }
-               if ( !in_array( 'object', $flags ) ) {
-                       return false;
-               }
-
-               if ( in_array( 'gzip', $flags ) ) {
-                       $obj = unserialize( gzinflate( $text ) );
-               } else {
-                       $obj = unserialize( $text );
-               }
-
-               if ( !is_object( $obj ) ) {
-                       // Correct for old double-serialization bug.
-                       $obj = unserialize( $obj );
-               }
-
-               if ( !is_object( $obj ) ) {
-                       return false;
-               }
-
-               $obj->uncompress();
-               $text = $obj->getItem( $stub['hash'] );
-
-               return $text !== false;
-       }
-}
-
-$maintClass = 'FixBug20757';
-require_once RUN_MAINTENANCE_IF_MAIN;
diff --git a/maintenance/storage/fixT22757.php b/maintenance/storage/fixT22757.php
new file mode 100644 (file)
index 0000000..e8bd23d
--- /dev/null
@@ -0,0 +1,349 @@
+<?php
+/**
+ * Script to fix T22757.
+ *
+ * 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 ExternalStorage
+ */
+
+require_once __DIR__ . '/../Maintenance.php';
+
+/**
+ * Maintenance script to fix T22757.
+ *
+ * @ingroup Maintenance ExternalStorage
+ */
+class FixT22757 extends Maintenance {
+       public $batchSize = 10000;
+       public $mapCache = [];
+       public $mapCacheSize = 0;
+       public $maxMapCacheSize = 1000000;
+
+       function __construct() {
+               parent::__construct();
+               $this->addDescription( 'Script to fix T22757 assuming that blob_tracking is intact' );
+               $this->addOption( 'dry-run', 'Report only' );
+               $this->addOption( 'start', 'old_id to start at', false, true );
+       }
+
+       function execute() {
+               $dbr = $this->getDB( DB_REPLICA );
+               $dbw = $this->getDB( DB_MASTER );
+
+               $dryRun = $this->getOption( 'dry-run' );
+               if ( $dryRun ) {
+                       print "Dry run only.\n";
+               }
+
+               $startId = $this->getOption( 'start', 0 );
+               $numGood = 0;
+               $numFixed = 0;
+               $numBad = 0;
+
+               $totalRevs = $dbr->selectField( 'text', 'MAX(old_id)', false, __METHOD__ );
+
+               // In MySQL 4.1+, the binary field old_text has a non-working LOWER() function
+               $lowerLeft = 'LOWER(CONVERT(LEFT(old_text,22) USING latin1))';
+
+               while ( true ) {
+                       print "ID: $startId / $totalRevs\r";
+
+                       $res = $dbr->select(
+                               'text',
+                               [ 'old_id', 'old_flags', 'old_text' ],
+                               [
+                                       'old_id > ' . intval( $startId ),
+                                       'old_flags LIKE \'%object%\' AND old_flags NOT LIKE \'%external%\'',
+                                       "$lowerLeft = 'o:15:\"historyblobstub\"'",
+                               ],
+                               __METHOD__,
+                               [
+                                       'ORDER BY' => 'old_id',
+                                       'LIMIT' => $this->batchSize,
+                               ]
+                       );
+
+                       if ( !$res->numRows() ) {
+                               break;
+                       }
+
+                       $secondaryIds = [];
+                       $stubs = [];
+
+                       foreach ( $res as $row ) {
+                               $startId = $row->old_id;
+
+                               // Basic sanity checks
+                               $obj = unserialize( $row->old_text );
+                               if ( $obj === false ) {
+                                       print "{$row->old_id}: unrecoverable: cannot unserialize\n";
+                                       ++$numBad;
+                                       continue;
+                               }
+
+                               if ( !is_object( $obj ) ) {
+                                       print "{$row->old_id}: unrecoverable: unserialized to type " .
+                                               gettype( $obj ) . ", possible double-serialization\n";
+                                       ++$numBad;
+                                       continue;
+                               }
+
+                               if ( strtolower( get_class( $obj ) ) !== 'historyblobstub' ) {
+                                       print "{$row->old_id}: unrecoverable: unexpected object class " .
+                                               get_class( $obj ) . "\n";
+                                       ++$numBad;
+                                       continue;
+                               }
+
+                               // Process flags
+                               $flags = explode( ',', $row->old_flags );
+                               if ( in_array( 'utf-8', $flags ) || in_array( 'utf8', $flags ) ) {
+                                       $legacyEncoding = false;
+                               } else {
+                                       $legacyEncoding = true;
+                               }
+
+                               // Queue the stub for future batch processing
+                               $id = intval( $obj->mOldId );
+                               $secondaryIds[] = $id;
+                               $stubs[$row->old_id] = [
+                                       'legacyEncoding' => $legacyEncoding,
+                                       'secondaryId' => $id,
+                                       'hash' => $obj->mHash,
+                               ];
+                       }
+
+                       $secondaryIds = array_unique( $secondaryIds );
+
+                       if ( !count( $secondaryIds ) ) {
+                               continue;
+                       }
+
+                       // Run the batch query on blob_tracking
+                       $res = $dbr->select(
+                               'blob_tracking',
+                               '*',
+                               [
+                                       'bt_text_id' => $secondaryIds,
+                               ],
+                               __METHOD__
+                       );
+                       $trackedBlobs = [];
+                       foreach ( $res as $row ) {
+                               $trackedBlobs[$row->bt_text_id] = $row;
+                       }
+
+                       // Process the stubs
+                       foreach ( $stubs as $primaryId => $stub ) {
+                               $secondaryId = $stub['secondaryId'];
+                               if ( !isset( $trackedBlobs[$secondaryId] ) ) {
+                                       // No tracked blob. Work out what went wrong
+                                       $secondaryRow = $dbr->selectRow(
+                                               'text',
+                                               [ 'old_flags', 'old_text' ],
+                                               [ 'old_id' => $secondaryId ],
+                                               __METHOD__
+                                       );
+                                       if ( !$secondaryRow ) {
+                                               print "$primaryId: unrecoverable: secondary row is missing\n";
+                                               ++$numBad;
+                                       } elseif ( $this->isUnbrokenStub( $stub, $secondaryRow ) ) {
+                                               // Not broken yet, and not in the tracked clusters so it won't get
+                                               // broken by the current RCT run.
+                                               ++$numGood;
+                                       } elseif ( strpos( $secondaryRow->old_flags, 'external' ) !== false ) {
+                                               print "$primaryId: unrecoverable: secondary gone to {$secondaryRow->old_text}\n";
+                                               ++$numBad;
+                                       } else {
+                                               print "$primaryId: unrecoverable: miscellaneous corruption of secondary row\n";
+                                               ++$numBad;
+                                       }
+                                       unset( $stubs[$primaryId] );
+                                       continue;
+                               }
+                               $trackRow = $trackedBlobs[$secondaryId];
+
+                               // Check that the specified text really is available in the tracked source row
+                               $url = "DB://{$trackRow->bt_cluster}/{$trackRow->bt_blob_id}/{$stub['hash']}";
+                               $text = ExternalStore::fetchFromURL( $url );
+                               if ( $text === false ) {
+                                       print "$primaryId: unrecoverable: source text missing\n";
+                                       ++$numBad;
+                                       unset( $stubs[$primaryId] );
+                                       continue;
+                               }
+                               if ( md5( $text ) !== $stub['hash'] ) {
+                                       print "$primaryId: unrecoverable: content hashes do not match\n";
+                                       ++$numBad;
+                                       unset( $stubs[$primaryId] );
+                                       continue;
+                               }
+
+                               // Find the page_id and rev_id
+                               // The page is probably the same as the page of the secondary row
+                               $pageId = intval( $trackRow->bt_page );
+                               if ( !$pageId ) {
+                                       $revId = $pageId = 0;
+                               } else {
+                                       $revId = $this->findTextIdInPage( $pageId, $primaryId );
+                                       if ( !$revId ) {
+                                               // Actually an orphan
+                                               $pageId = $revId = 0;
+                                       }
+                               }
+
+                               $newFlags = $stub['legacyEncoding'] ? 'external' : 'external,utf-8';
+
+                               if ( !$dryRun ) {
+                                       // Reset the text row to point to the original copy
+                                       $this->beginTransaction( $dbw, __METHOD__ );
+                                       $dbw->update(
+                                               'text',
+                                               // SET
+                                               [
+                                                       'old_flags' => $newFlags,
+                                                       'old_text' => $url
+                                               ],
+                                               // WHERE
+                                               [ 'old_id' => $primaryId ],
+                                               __METHOD__
+                                       );
+
+                                       // Add a blob_tracking row so that the new reference can be recompressed
+                                       // without needing to run trackBlobs.php again
+                                       $dbw->insert( 'blob_tracking',
+                                               [
+                                                       'bt_page' => $pageId,
+                                                       'bt_rev_id' => $revId,
+                                                       'bt_text_id' => $primaryId,
+                                                       'bt_cluster' => $trackRow->bt_cluster,
+                                                       'bt_blob_id' => $trackRow->bt_blob_id,
+                                                       'bt_cgz_hash' => $stub['hash'],
+                                                       'bt_new_url' => null,
+                                                       'bt_moved' => 0,
+                                               ],
+                                               __METHOD__
+                                       );
+                                       $this->commitTransaction( $dbw, __METHOD__ );
+                                       $this->waitForSlaves();
+                               }
+
+                               print "$primaryId: resolved to $url\n";
+                               ++$numFixed;
+                       }
+               }
+
+               print "\n";
+               print "Fixed: $numFixed\n";
+               print "Unrecoverable: $numBad\n";
+               print "Good stubs: $numGood\n";
+       }
+
+       function waitForSlaves() {
+               static $iteration = 0;
+               ++$iteration;
+               if ( ++$iteration > 50 == 0 ) {
+                       wfWaitForSlaves();
+                       $iteration = 0;
+               }
+       }
+
+       function findTextIdInPage( $pageId, $textId ) {
+               $ids = $this->getRevTextMap( $pageId );
+               if ( !isset( $ids[$textId] ) ) {
+                       return null;
+               } else {
+                       return $ids[$textId];
+               }
+       }
+
+       function getRevTextMap( $pageId ) {
+               if ( !isset( $this->mapCache[$pageId] ) ) {
+                       // Limit cache size
+                       while ( $this->mapCacheSize > $this->maxMapCacheSize ) {
+                               $key = key( $this->mapCache );
+                               $this->mapCacheSize -= count( $this->mapCache[$key] );
+                               unset( $this->mapCache[$key] );
+                       }
+
+                       $dbr = $this->getDB( DB_REPLICA );
+                       $map = [];
+                       $res = $dbr->select( 'revision',
+                               [ 'rev_id', 'rev_text_id' ],
+                               [ 'rev_page' => $pageId ],
+                               __METHOD__
+                       );
+                       foreach ( $res as $row ) {
+                               $map[$row->rev_text_id] = $row->rev_id;
+                       }
+                       $this->mapCache[$pageId] = $map;
+                       $this->mapCacheSize += count( $map );
+               }
+
+               return $this->mapCache[$pageId];
+       }
+
+       /**
+        * This is based on part of HistoryBlobStub::getText().
+        * Determine if the text can be retrieved from the row in the normal way.
+        * @param array $stub
+        * @param stdClass $secondaryRow
+        * @return bool
+        */
+       function isUnbrokenStub( $stub, $secondaryRow ) {
+               $flags = explode( ',', $secondaryRow->old_flags );
+               $text = $secondaryRow->old_text;
+               if ( in_array( 'external', $flags ) ) {
+                       $url = $text;
+                       MediaWiki\suppressWarnings();
+                       list( /* $proto */, $path ) = explode( '://', $url, 2 );
+                       MediaWiki\restoreWarnings();
+
+                       if ( $path == "" ) {
+                               return false;
+                       }
+                       $text = ExternalStore::fetchFromURL( $url );
+               }
+               if ( !in_array( 'object', $flags ) ) {
+                       return false;
+               }
+
+               if ( in_array( 'gzip', $flags ) ) {
+                       $obj = unserialize( gzinflate( $text ) );
+               } else {
+                       $obj = unserialize( $text );
+               }
+
+               if ( !is_object( $obj ) ) {
+                       // Correct for old double-serialization bug.
+                       $obj = unserialize( $obj );
+               }
+
+               if ( !is_object( $obj ) ) {
+                       return false;
+               }
+
+               $obj->uncompress();
+               $text = $obj->getItem( $stub['hash'] );
+
+               return $text !== false;
+       }
+}
+
+$maintClass = 'FixT22757';
+require_once RUN_MAINTENANCE_IF_MAIN;
index a2dc376..4f22843 100644 (file)
@@ -69,7 +69,7 @@ class TrackBlobs {
                echo "Doing integrity check...\n";
                $dbr = wfGetDB( DB_REPLICA );
 
-               // Scan for HistoryBlobStub objects in the text table (bug 20757)
+               // Scan for HistoryBlobStub objects in the text table (T22757)
 
                $exists = $dbr->selectField( 'text', 1,
                        'old_flags LIKE \'%object%\' AND old_flags NOT LIKE \'%external%\' ' .
@@ -84,7 +84,7 @@ class TrackBlobs {
                        exit( 1 );
                }
 
-               // Scan the archive table for HistoryBlobStub objects or external flags (bug 22624)
+               // Scan the archive table for HistoryBlobStub objects or external flags (T24624)
                $flags = $dbr->selectField( 'archive', 'ar_flags',
                        'ar_flags LIKE \'%external%\' OR (' .
                        'ar_flags LIKE \'%object%\' ' .
index 892f799..44922a4 100644 (file)
@@ -594,7 +594,7 @@ CREATE TABLE /*_*/categorylinks (
   -- conversion algorithm is run.  We store this so that we can update
   -- collations without reparsing all pages.
   -- Note: If you change the length of this field, you also need to change
-  -- code in LinksUpdate.php. See bug 25254.
+  -- code in LinksUpdate.php. See T27254.
   cl_sortkey_prefix varchar(255) binary NOT NULL default '',
 
   -- This isn't really used at present. Provided for an optional
@@ -816,7 +816,7 @@ CREATE TABLE /*_*/ipblocks (
   -- Size chosen to allow IPv6
   -- FIXME: these fields were originally blank for single-IP blocks,
   -- but now they are populated. No migration was ever done. They
-  -- should be fixed to be blank again for such blocks (bug 49504).
+  -- should be fixed to be blank again for such blocks (T51504).
   ipb_range_start tinyblob NOT NULL,
   ipb_range_end tinyblob NOT NULL,
 
index a672e29..d96cecd 100755 (executable)
@@ -112,7 +112,7 @@ class UpdateMediaWiki extends Maintenance {
                }
 
                $lang = Language::factory( 'en' );
-               // Set global language to ensure localised errors are in English (bug 20633)
+               // Set global language to ensure localised errors are in English (T22633)
                RequestContext::getMain()->setLanguage( $lang );
                $wgLang = $lang; // BackCompat
 
@@ -203,7 +203,7 @@ class UpdateMediaWiki extends Maintenance {
 
                # Don't try to access the database
                # This needs to be disabled early since extensions will try to use the l10n
-               # cache from $wgExtensionFunctions (bug 20471)
+               # cache from $wgExtensionFunctions (T22471)
                $wgLocalisationCacheConf = [
                        'class' => 'LocalisationCache',
                        'storeClass' => 'LCStoreNull',
index 9893342..69c9265 100644 (file)
@@ -195,7 +195,7 @@ class UserDupes {
                        "SELECT user_name,COUNT(*) AS n
                                FROM $user
                        GROUP BY user_name
-                         HAVING n > 1", __METHOD__ );
+                               HAVING n > 1", __METHOD__ );
 
                $list = [];
                foreach ( $result as $row ) {
index 10a6de8..ea5835d 100644 (file)
 }
 
 .config-plainlink a {
-       background: none !important;
-       padding: 0 !important;
+       background: none !important; /* stylelint-disable-line declaration-no-important */
+       padding: 0 !important; /* stylelint-disable-line declaration-no-important */
 }
 
 .config-download-link {
index d6cb43f..5c6b262 100644 (file)
@@ -251,7 +251,6 @@ return [
                'scripts' => 'resources/src/jquery/jquery.highlightText.js',
                'dependencies' => [
                        'mediawiki.RegExp',
-                       'dom-level2-shim',
                ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
@@ -345,7 +344,6 @@ return [
                'styles' => 'resources/src/jquery/jquery.tablesorter.less',
                'messages' => [ 'sort-descending', 'sort-ascending' ],
                'dependencies' => [
-                       'dom-level2-shim',
                        'mediawiki.RegExp',
                        'mediawiki.language.months',
                ],
@@ -736,7 +734,7 @@ return [
 
        // Deprecated since MediaWiki 1.29.0
        'json' => [
-               'deprecated' => 'Use of the "json" MediaWiki module is deprecated since MediaWiki 1.29.0',
+               'deprecated' => 'Use of the "json" module is deprecated since MediaWiki 1.29.0',
                'targets' => [ 'desktop', 'mobile' ],
        ],
 
@@ -937,7 +935,6 @@ return [
        'mediawiki.api.upload' => [
                'scripts' => 'resources/src/mediawiki/api/upload.js',
                'dependencies' => [
-                       'dom-level2-shim',
                        'mediawiki.api',
                        'mediawiki.api.edit',
                ],
@@ -1220,7 +1217,6 @@ return [
        'mediawiki.Upload' => [
                'scripts' => 'resources/src/mediawiki/mediawiki.Upload.js',
                'dependencies' => [
-                       'dom-level2-shim',
                        'mediawiki.api.upload',
                ],
        ],
@@ -1364,9 +1360,10 @@ return [
        'mediawiki.user' => [
                'scripts' => 'resources/src/mediawiki/mediawiki.user.js',
                'dependencies' => [
-                       'mediawiki.cookie',
                        'mediawiki.api',
                        'mediawiki.api.user',
+                       'mediawiki.cookie',
+                       'mediawiki.storage',
                        'user.options',
                        'user.tokens',
                ],
@@ -1437,7 +1434,7 @@ return [
                'styles' => 'resources/src/mediawiki.action/mediawiki.action.edit.collapsibleFooter.css',
                'dependencies' => [
                        'jquery.makeCollapsible',
-                       'mediawiki.cookie',
+                       'mediawiki.storage',
                        'mediawiki.icon',
                ],
        ],
@@ -1612,7 +1609,6 @@ return [
                        'mediawiki.util',
                        'mediawiki.language',
                        'user.options',
-                       'dom-level2-shim',
                ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
@@ -1751,6 +1747,11 @@ return [
 
        /* MediaWiki Special pages */
 
+       'mediawiki.rcfilters.filters.base.styles' => [
+               'styles' => [
+                       'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less',
+               ],
+       ],
        'mediawiki.rcfilters.filters.dm' => [
                'scripts' => [
                        'resources/src/mediawiki.rcfilters/mw.rcfilters.js',
@@ -1786,7 +1787,6 @@ return [
                        'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.variables.less',
                        'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.less',
                        'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.Overlay.less',
-                       'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less',
                        'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterItemWidget.less',
                        'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.CapsuleItemWidget.less',
                        'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterGroupWidget.less',
@@ -1805,6 +1805,7 @@ return [
                        'rcfilters-invalid-filter',
                        'rcfilters-empty-filter',
                        'rcfilters-filterlist-title',
+                       'rcfilters-filterlist-feedbacklink',
                        'rcfilters-filterlist-noresults',
                        'rcfilters-filtergroup-registration',
                        'rcfilters-filter-registered-label',
@@ -1844,6 +1845,7 @@ return [
                        'rcfilters-filter-logactions-description',
                        'rcfilters-highlightbutton-title',
                        'rcfilters-highlightmenu-title',
+                       'rcfilters-highlightmenu-help',
                        'recentchanges-noresult',
                ],
                'dependencies' => [
@@ -1851,6 +1853,7 @@ return [
                        'mediawiki.rcfilters.filters.dm',
                        'oojs-ui.styles.icons-moderation',
                        'oojs-ui.styles.icons-editing-core',
+                       'oojs-ui.styles.icons-interactions',
                ],
        ],
        'mediawiki.special' => [
@@ -1927,7 +1930,10 @@ return [
        'mediawiki.special.block' => [
                'scripts' => 'resources/src/mediawiki.special/mediawiki.special.block.js',
                'styles' => 'resources/src/mediawiki.special/mediawiki.special.block.css',
-               'dependencies' => 'mediawiki.util',
+               'dependencies' => [
+                       'mediawiki.util',
+                       'mediawiki.htmlform',
+               ],
        ],
        'mediawiki.special.changeslist' => [
                'styles' => 'resources/src/mediawiki.special/mediawiki.special.changeslist.css',
@@ -2483,11 +2489,10 @@ return [
        ],
 
        /* dom-level2-shim */
-       // IE 8
+       // Deprecated since MediaWiki 1.29.0
        'dom-level2-shim' => [
-               'scripts' => 'resources/src/polyfill-nodeTypes.js',
+               'deprecated' => 'Use of the "dom-level2-shim" module is deprecated since MediaWiki 1.29.0',
                'targets' => [ 'desktop', 'mobile' ],
-               'skipFunction' => 'resources/src/dom-level2-skip.js',
        ],
 
        /* OOjs */
index 8b85a20..a84374a 100644 (file)
@@ -12,5 +12,6 @@
        "ooui-dialog-process-retry": "ز نۉ تلاش کونين",
        "ooui-dialog-process-continue": "ديندا گرهڌن",
        "ooui-selectfile-button-select": "گولإڤورچين کردن جانیا",
-       "ooui-selectfile-placeholder": "هيژ جانيایي گولإ ڤورچين نڤابيڌإ"
+       "ooui-selectfile-placeholder": "هيژ جانيایي گولإ ڤورچين نڤابيڌإ",
+       "ooui-selectfile-dragdrop-placeholder": "جانيانأ ڤأنين ايچو"
 }
index 83af863..cbfcab0 100644 (file)
@@ -18,5 +18,9 @@
        "ooui-dialog-process-error": "Un dra bennak a-dreuz a zo bet",
        "ooui-dialog-process-dismiss": "Disteurel",
        "ooui-dialog-process-retry": "Klask en-dro",
-       "ooui-dialog-process-continue": "Kenderc'hel"
+       "ooui-dialog-process-continue": "Kenderc'hel",
+       "ooui-selectfile-button-select": "Diuzañ ur restr",
+       "ooui-selectfile-not-supported": "N'eo ket skoret an diuzañ restroù",
+       "ooui-selectfile-placeholder": "N'eus bet diuzet restr ebet",
+       "ooui-selectfile-dragdrop-placeholder": "Lezel ar restr amañ"
 }
index af97d17..722b3e2 100644 (file)
@@ -3,5 +3,21 @@
                "authors": [
                        "Jagwar"
                ]
-       }
+       },
+       "ooui-outline-control-move-down": "Hampidina ilay zavatra",
+       "ooui-outline-control-move-up": "Hampiakatra ilay zavatra",
+       "ooui-outline-control-remove": "Hanala iay zavatra",
+       "ooui-toolbar-more": "Be kokoa",
+       "ooui-toolgroup-expand": "Be kokoa",
+       "ooui-toolgroup-collapse": "Kely kokoa",
+       "ooui-dialog-message-accept": "OK",
+       "ooui-dialog-message-reject": "Avela",
+       "ooui-dialog-process-error": "Nisy hadisoana nitranga",
+       "ooui-dialog-process-dismiss": "Esorina",
+       "ooui-dialog-process-retry": "Andramana indray",
+       "ooui-dialog-process-continue": "Tohizana",
+       "ooui-selectfile-button-select": "Misafidia rakitra iray",
+       "ooui-selectfile-not-supported": "Tsy zaka ny fisafidiana rakitra",
+       "ooui-selectfile-placeholder": "Tsy misy rakitra voafidy",
+       "ooui-selectfile-dragdrop-placeholder": "Hametraka rakitra eto"
 }
index c8fba3d..e3f3e11 100644 (file)
@@ -7,7 +7,13 @@
        },
        "ooui-outline-control-move-down": "Flytt element ned",
        "ooui-outline-control-move-up": "Flytt element opp",
-       "ooui-toolbar-more": "Fleire",
+       "ooui-toolbar-more": "Meir",
+       "ooui-toolgroup-expand": "Meir",
+       "ooui-toolgroup-collapse": "Færre",
+       "ooui-dialog-message-reject": "Bryt av",
+       "ooui-dialog-process-error": "Noko gjekk gale",
+       "ooui-dialog-process-dismiss": "Lat att",
+       "ooui-dialog-process-continue": "Hald fram",
        "ooui-selectfile-button-select": "Vel ei fil",
        "ooui-selectfile-placeholder": "Inga fil er vald"
 }
index 8bd4be8..386871c 100644 (file)
@@ -1,7 +1,8 @@
 {
        "@metadata": {
                "authors": [
-                       "Saanvel"
+                       "Saanvel",
+                       "Abbas dhothar"
                ]
        },
        "ooui-outline-control-move-down": "شیہ تھلے کرو",
@@ -9,6 +10,7 @@
        "ooui-outline-control-remove": "شیہ مٹاؤ",
        "ooui-toolbar-more": "ہور",
        "ooui-toolgroup-expand": "ہور",
+       "ooui-toolgroup-collapse": "گھٹ",
        "ooui-dialog-message-accept": "OK",
        "ooui-dialog-message-reject": "مکاؤ",
        "ooui-dialog-process-error": "کوئی رپھڑ پے گیا اے۔",
index f206a72..84048e7 100644 (file)
@@ -18,6 +18,7 @@
        "ooui-dialog-process-dismiss": "צומאַכן",
        "ooui-dialog-process-retry": "פרובירט נאכאמאל",
        "ooui-dialog-process-continue": "פֿארזעצן",
+       "ooui-selectfile-button-select": "קלויבט א טעקע",
        "ooui-selectfile-not-supported": "טעקע אויסווייל נישט געשטיצט",
        "ooui-selectfile-placeholder": "קיין טעקע נישט אויסגעוויילט"
 }
index 2307413..541462f 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.19.2
+ * OOjs UI v0.19.4
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-02-14T22:47:20Z
+ * Date: 2017-02-28T23:19:40Z
  */
 ( function ( OO ) {
 
index 524c16b..0818782 100644 (file)
@@ -1,13 +1,15 @@
 /*!
- * OOjs UI v0.19.2
+ * OOjs UI v0.19.4
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-02-14T22:47:25Z
+ * Date: 2017-02-28T23:19:44Z
  */
+/* stylelint-disable selector-no-vendor-prefix, at-rule-no-unknown */
+/* stylelint-enable selector-no-vendor-prefix, at-rule-no-unknown */
 .oo-ui-element-hidden {
   display: none !important;
   /* stylelint-disable-line declaration-no-important */
@@ -41,8 +43,8 @@
   cursor: default;
 }
 .oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
-.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
-.oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+.oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
+.oo-ui-buttonElement-frameless.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
   display: inline-block;
   vertical-align: middle;
 }
@@ -67,7 +69,7 @@
 }
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:hover,
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus {
-  outline: none;
+  outline: 0;
 }
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:hover > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus > .oo-ui-iconElement-icon {
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:hover,
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:focus {
   border-color: #aaa;
-  outline: none;
+  outline: 0;
 }
 .oo-ui-buttonElement-framed > input.oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
 .oo-ui-buttonElement-framed.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
   margin-left: -0.5em;
   margin-right: -0.5em;
+  display: inline-block;
+  vertical-align: middle;
 }
 .oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
   margin-right: 0.3em;
@@ -472,7 +476,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   position: relative;
 }
 .oo-ui-panelLayout-scrollable {
-  overflow-y: auto;
+  overflow: auto;
   -webkit-transform: translateZ(0);
           transform: translateZ(0);
 }
@@ -650,7 +654,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 .oo-ui-popupWidget {
   position: absolute;
-  left: 0;
 }
 .oo-ui-popupWidget-popup {
   position: relative;
@@ -665,7 +668,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   display: block;
   position: absolute;
   /* `top` property is to be set in theme's selector due to specific `@size-anchor` values */
-  left: 0;
   background-repeat: no-repeat;
 }
 .oo-ui-popupWidget-head {
@@ -807,7 +809,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:hover,
 .oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:focus {
   border-color: rgba(0, 0, 0, 0.2);
-  outline: none;
+  outline: 0;
 }
 .oo-ui-dropdownInputWidget.oo-ui-widget-disabled select {
   color: #ccc;
@@ -929,14 +931,41 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   -webkit-transition: border-color 250ms ease, box-shadow 250ms ease;
      -moz-transition: border-color 250ms ease, box-shadow 250ms ease;
           transition: border-color 250ms ease, box-shadow 250ms ease;
+  /* stylelint-disable indentation */
+  /* stylelint-enable indentation */
 }
 .oo-ui-textInputWidget input.oo-ui-pendingElement-pending,
 .oo-ui-textInputWidget textarea.oo-ui-pendingElement-pending {
   background-color: transparent;
 }
+.oo-ui-textInputWidget input::-webkit-input-placeholder,
+.oo-ui-textInputWidget textarea::-webkit-input-placeholder {
+  color: #72777d;
+  opacity: 1;
+}
+.oo-ui-textInputWidget input:-ms-input-placeholder,
+.oo-ui-textInputWidget textarea:-ms-input-placeholder {
+  color: #72777d;
+  opacity: 1;
+}
+.oo-ui-textInputWidget input::-moz-placeholder,
+.oo-ui-textInputWidget textarea::-moz-placeholder {
+  color: #72777d;
+  opacity: 1;
+}
+.oo-ui-textInputWidget input:-moz-placeholder,
+.oo-ui-textInputWidget textarea:-moz-placeholder {
+  color: #72777d;
+  opacity: 1;
+}
+.oo-ui-textInputWidget input::placeholder,
+.oo-ui-textInputWidget textarea::placeholder {
+  color: #72777d;
+  opacity: 1;
+}
 .oo-ui-textInputWidget.oo-ui-widget-enabled input:focus,
 .oo-ui-textInputWidget.oo-ui-widget-enabled textarea:focus {
-  outline: none;
+  outline: 0;
   border-color: #a7dcff;
   box-shadow: 0 0 0.3em #a7dcff, 0 0 0 #fff;
 }
@@ -1058,9 +1087,11 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
      -moz-box-sizing: border-box;
           box-sizing: border-box;
 }
-.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator,
-.oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
+.oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon,
+.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
   position: absolute;
+  top: 0;
+  height: 100%;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle {
   cursor: pointer;
@@ -1076,20 +1107,18 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-dropdownWidget-handle:hover {
   border-color: rgba(0, 0, 0, 0.2);
 }
-.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
-  top: 0;
-  right: 0;
-  margin: 0.775em;
-}
 .oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
-  top: 0;
   left: 0.25em;
-  margin: 0.3em;
+  margin: 0 0.3em;
 }
 .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
   line-height: 2.5em;
   margin: 0 0.5em;
 }
+.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
+  right: 0;
+  margin: 0 0.775em;
+}
 .oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle {
   color: #ccc;
   text-shadow: 0 1px 1px #fff;
index f3b3fce..f468d17 100644 (file)
@@ -1,13 +1,15 @@
 /*!
- * OOjs UI v0.19.2
+ * OOjs UI v0.19.4
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-02-14T22:47:25Z
+ * Date: 2017-02-28T23:19:44Z
  */
+/* stylelint-disable selector-no-vendor-prefix, at-rule-no-unknown */
+/* stylelint-enable selector-no-vendor-prefix, at-rule-no-unknown */
 .oo-ui-element-hidden {
   display: none !important;
   /* stylelint-disable-line declaration-no-important */
@@ -41,8 +43,8 @@
   cursor: default;
 }
 .oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
-.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
-.oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+.oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
+.oo-ui-buttonElement-frameless.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
   display: inline-block;
   vertical-align: middle;
 }
@@ -64,9 +66,6 @@
 .oo-ui-buttonElement > .oo-ui-buttonElement-button:focus::-moz-focus-inner {
   border-color: transparent;
 }
-.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-  margin-left: 0;
-}
 .oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
   margin-right: 0.25em;
   margin-left: 0.46875em;
   padding-left: 2.4em;
 }
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
-  padding: 0.546875em 1em;
+  position: relative;
   min-height: 2.5em;
-  min-width: 3.125em;
   border-radius: 2px;
-  position: relative;
+  padding: 0.546875em 1em;
+}
+.oo-ui-buttonElement-framed.oo-ui-iconElement > .oo-ui-buttonElement-button {
+  min-width: 3.125em;
+}
+.oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-indicatorElement > .oo-ui-buttonElement-button {
+  min-width: 0;
 }
 .oo-ui-buttonElement-framed > input.oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
   line-height: 1.25;
 }
 .oo-ui-buttonElement-framed.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+  display: block;
   position: absolute;
-  top: 0.2em;
+  top: 0;
+  height: 100%;
   left: 0.5625em;
 }
 .oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
@@ -613,7 +620,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   position: relative;
 }
 .oo-ui-panelLayout-scrollable {
-  overflow-y: auto;
+  overflow: auto;
   -webkit-transform: translateZ(0);
           transform: translateZ(0);
 }
@@ -654,7 +661,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   margin-right: 0;
 }
 .oo-ui-horizontalLayout > .oo-ui-layout {
-  margin-bottom: 0;
+  margin-top: 0;
 }
 .oo-ui-optionWidget {
   position: relative;
@@ -806,7 +813,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 .oo-ui-popupWidget {
   position: absolute;
-  left: 0;
 }
 .oo-ui-popupWidget-popup {
   position: relative;
@@ -821,7 +827,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   display: block;
   position: absolute;
   /* `top` property is to be set in theme's selector due to specific `@size-anchor` values */
-  left: 0;
   background-repeat: no-repeat;
 }
 .oo-ui-popupWidget-head {
@@ -1044,17 +1049,23 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
      -moz-box-sizing: border-box;
           box-sizing: border-box;
 }
+.oo-ui-dropdownInputWidget-php {
+  border-right: 1px solid #a2a9b1;
+  border-radius: 2px;
+  overflow-x: hidden;
+}
 .oo-ui-dropdownInputWidget select {
-  background-color: #fff;
-  height: 2.275em;
-  font-size: inherit;
-  font-family: inherit;
+  -webkit-appearance: none;
+     -moz-appearance: none;
+          appearance: none;
   -webkit-box-sizing: border-box;
      -moz-box-sizing: border-box;
           box-sizing: border-box;
   border: 1px solid #a2a9b1;
   border-radius: 2px;
-  padding-left: 1em;
+  padding: 0.5em 1em;
+  font-size: inherit;
+  font-family: inherit;
   vertical-align: middle;
 }
 .oo-ui-dropdownInputWidget option {
@@ -1063,14 +1074,42 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   height: 1.5em;
   padding: 0.5em 1em;
 }
-.oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:hover,
+.oo-ui-dropdownInputWidget.oo-ui-widget-enabled select {
+  background-color: #f8f9fa;
+  background-position: -9999em 0;
+  background-repeat: no-repeat;
+  color: #222;
+  -webkit-transition: background-color 100ms, border-color 100ms, box-shadow 100ms;
+     -moz-transition: background-color 100ms, border-color 100ms, box-shadow 100ms;
+          transition: background-color 100ms, border-color 100ms, box-shadow 100ms;
+}
+.oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:hover {
+  background-color: #fff;
+  color: #444;
+  border-color: #a2a9b1;
+}
+.oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:active {
+  color: #000;
+  border-color: #72777d;
+}
 .oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:focus {
+  border-color: #36c;
   outline: 0;
+  box-shadow: inset 0 0 0 1px #36c;
+}
+.oo-ui-dropdownInputWidget.oo-ui-widget-enabled select::-ms-expand {
+  display: none;
+}
+.oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:not( [no-ie] ) {
+  background-position: right 1.75em center;
+  width: calc( 100% + 1em );
+  height: 2.5em;
+  padding: 0 0 0 1em;
 }
 .oo-ui-dropdownInputWidget.oo-ui-widget-disabled select {
+  background-color: #eaecf0;
   color: #72777d;
   border-color: #c8ccd1;
-  background-color: #eaecf0;
 }
 .oo-ui-radioInputWidget {
   position: relative;
@@ -1304,6 +1343,8 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   -webkit-transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
      -moz-transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
           transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+  /* stylelint-disable indentation */
+  /* stylelint-enable indentation */
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled input:hover,
 .oo-ui-textInputWidget.oo-ui-widget-enabled textarea:hover {
@@ -1328,28 +1369,36 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   border-color: #c8ccd1;
   box-shadow: inset 0 0 0 1px #c8ccd1;
 }
-@media screen and (min-width: 0) {
-  .oo-ui-textInputWidget.oo-ui-widget-enabled textarea:focus {
-    outline: 1px solid #36c;
-    outline-offset: -2px;
-  }
-}
-.oo-ui-textInputWidget.oo-ui-widget-enabled :-moz-placeholder {
+.oo-ui-textInputWidget.oo-ui-widget-enabled input::-webkit-input-placeholder,
+.oo-ui-textInputWidget.oo-ui-widget-enabled textarea::-webkit-input-placeholder {
   color: #72777d;
   opacity: 1;
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled ::-moz-placeholder {
+.oo-ui-textInputWidget.oo-ui-widget-enabled input:-ms-input-placeholder,
+.oo-ui-textInputWidget.oo-ui-widget-enabled textarea:-ms-input-placeholder {
   color: #72777d;
   opacity: 1;
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled :-ms-input-placeholder {
+.oo-ui-textInputWidget.oo-ui-widget-enabled input::-moz-placeholder,
+.oo-ui-textInputWidget.oo-ui-widget-enabled textarea::-moz-placeholder {
   color: #72777d;
+  opacity: 1;
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled ::-webkit-input-placeholder {
+.oo-ui-textInputWidget.oo-ui-widget-enabled input:-moz-placeholder,
+.oo-ui-textInputWidget.oo-ui-widget-enabled textarea:-moz-placeholder {
   color: #72777d;
+  opacity: 1;
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled :placeholder-shown {
+.oo-ui-textInputWidget.oo-ui-widget-enabled input::placeholder,
+.oo-ui-textInputWidget.oo-ui-widget-enabled textarea::placeholder {
   color: #72777d;
+  opacity: 1;
+}
+@media screen and (min-width: 0) {
+  .oo-ui-textInputWidget.oo-ui-widget-enabled textarea:focus {
+    outline: 1px solid #36c;
+    outline-offset: -2px;
+  }
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input,
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea {
@@ -1385,7 +1434,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 .oo-ui-textInputWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
   left: 0;
-  height: 100%;
   max-height: 2.375em;
   margin-left: 0.5em;
   background-position: right center;
@@ -1401,8 +1449,9 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 .oo-ui-textInputWidget > .oo-ui-labelElement-label {
   color: #72777d;
-  padding: 0.4em;
-  line-height: 1.5;
+  margin-top: 1px;
+  padding: 0.625em 0.546875em 0.546875em;
+  line-height: 1.172em;
 }
 .oo-ui-textInputWidget-labelPosition-after.oo-ui-indicatorElement > .oo-ui-labelElement-label {
   margin-right: 2.0875em;
@@ -1490,9 +1539,11 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
      -moz-box-sizing: border-box;
           box-sizing: border-box;
 }
-.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator,
-.oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
+.oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon,
+.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
   position: absolute;
+  top: 0;
+  height: 100%;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle {
   cursor: pointer;
@@ -1508,14 +1559,12 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   border-radius: 2px;
 }
 .oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
-  top: 0;
   right: 0;
-  margin: 0.775em;
+  margin: 0 0.775em;
 }
 .oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
-  top: 0;
   left: 0.25em;
-  margin: 0.3em;
+  margin: 0 0.3em;
 }
 .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
   margin: 0 1em;
@@ -1614,8 +1663,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-comboBoxInputWidget-php > .oo-ui-indicatorElement-indicator {
   pointer-events: none;
 }
-.oo-ui-comboBoxInputWidget input,
-.oo-ui-comboBoxInputWidget textarea {
+.oo-ui-comboBoxInputWidget input {
   height: 2.5em;
   border-top-right-radius: 0;
   border-bottom-right-radius: 0;
@@ -1635,8 +1683,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   border-top-left-radius: 0;
   border-bottom-left-radius: 0;
 }
-.oo-ui-comboBoxInputWidget.oo-ui-comboBoxInputWidget-empty input,
-.oo-ui-comboBoxInputWidget.oo-ui-comboBoxInputWidget-empty textarea {
+.oo-ui-comboBoxInputWidget.oo-ui-comboBoxInputWidget-empty input {
   border-right-width: 1px;
 }
 .oo-ui-comboBoxInputWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
index e327e5f..9eb8716 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.19.2
+ * OOjs UI v0.19.4
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-02-14T22:47:20Z
+ * Date: 2017-02-28T23:19:40Z
  */
 ( function ( OO ) {
 
@@ -1072,6 +1072,73 @@ OO.ui.Element.static.getDimensions = function ( el ) {
        }
 };
 
+/**
+ * Get the number of pixels that an element's content is scrolled to the left.
+ *
+ * Adapted from <https://github.com/othree/jquery.rtl-scroll-type>.
+ * Original code copyright 2012 Wei-Ko Kao, licensed under the MIT License.
+ *
+ * This function smooths out browser inconsistencies (nicely described in the README at
+ * <https://github.com/othree/jquery.rtl-scroll-type>) and produces a result consistent
+ * with Firefox's 'scrollLeft', which seems the sanest.
+ *
+ * @static
+ * @method
+ * @param {HTMLElement|Window} el Element to measure
+ * @return {number} Scroll position from the left.
+ *  If the element's direction is LTR, this is a positive number between `0` (initial scroll position)
+ *  and `el.scrollWidth - el.clientWidth` (furthest possible scroll position).
+ *  If the element's direction is RTL, this is a negative number between `0` (initial scroll position)
+ *  and `-el.scrollWidth + el.clientWidth` (furthest possible scroll position).
+ */
+OO.ui.Element.static.getScrollLeft = ( function () {
+       var rtlScrollType = null;
+
+       function test() {
+               var $definer = $( '<div dir="rtl" style="font-size: 14px; width: 1px; height: 1px; position: absolute; top: -1000px; overflow: scroll">A</div>' ),
+                       definer = $definer[ 0 ];
+
+               $definer.appendTo( 'body' );
+               if ( definer.scrollLeft > 0 ) {
+                       // Safari, Chrome
+                       rtlScrollType = 'default';
+               } else {
+                       definer.scrollLeft = 1;
+                       if ( definer.scrollLeft === 0 ) {
+                               // Firefox, old Opera
+                               rtlScrollType = 'negative';
+                       } else {
+                               // Internet Explorer, Edge
+                               rtlScrollType = 'reverse';
+                       }
+               }
+               $definer.remove();
+       }
+
+       return function getScrollLeft( el ) {
+               var isRoot = el.window === el ||
+                               el === el.ownerDocument.body ||
+                               el === el.ownerDocument.documentElement,
+                       scrollLeft = isRoot ? $( window ).scrollLeft() : el.scrollLeft,
+                       // All browsers use the correct scroll type ('negative') on the root, so don't
+                       // do any fixups when looking at the root element
+                       direction = isRoot ? 'ltr' : $( el ).css( 'direction' );
+
+               if ( direction === 'rtl' ) {
+                       if ( rtlScrollType === null ) {
+                               test();
+                       }
+                       if ( rtlScrollType === 'reverse' ) {
+                               scrollLeft = -scrollLeft;
+                       } else if ( rtlScrollType === 'default' ) {
+                               scrollLeft = scrollLeft - el.scrollWidth + el.clientWidth;
+                       }
+               }
+
+               return scrollLeft;
+       };
+}() );
+
 /**
  * Get scrollable object parent
  *
@@ -1117,7 +1184,8 @@ OO.ui.Element.static.getRootScrollableElement = function ( el ) {
  */
 OO.ui.Element.static.getClosestScrollableContainer = function ( el, dimension ) {
        var i, val,
-               // props = [ 'overflow' ] doesn't work due to https://bugzilla.mozilla.org/show_bug.cgi?id=889091
+               // Browsers do not correctly return the computed value of 'overflow' when 'overflow-x' and
+               // 'overflow-y' have different values, so we need to check the separate properties.
                props = [ 'overflow-x', 'overflow-y' ],
                $parent = $( el ).parent();
 
@@ -1132,6 +1200,11 @@ OO.ui.Element.static.getClosestScrollableContainer = function ( el, dimension )
                i = props.length;
                while ( i-- ) {
                        val = $parent.css( props[ i ] );
+                       // We assume that elements with 'overflow' (in any direction) set to 'hidden' will never be
+                       // scrolled in that direction, but they can actually be scrolled programatically. The user can
+                       // unintentionally perform a scroll in such case even if the application doesn't scroll
+                       // programatically, e.g. when jumping to an anchor, or when using built-in find functionality.
+                       // This could cause funny issues...
                        if ( val === 'auto' || val === 'scroll' ) {
                                return $parent[ 0 ];
                        }
@@ -3818,6 +3891,11 @@ OO.ui.LabelWidget = function OoUiLabelWidget( config ) {
        if ( this.input instanceof OO.ui.InputWidget ) {
                if ( this.input.getInputId() ) {
                        this.$element.attr( 'for', this.input.getInputId() );
+               } else {
+                       this.$label.on( 'click', function () {
+                               this.fieldWidget.focus();
+                               return false;
+                       }.bind( this ) );
                }
        }
        this.$element.addClass( 'oo-ui-labelWidget' );
@@ -3971,8 +4049,8 @@ OO.ui.mixin.PendingElement.prototype.popPending = function () {
 };
 
 /**
- * Element that will stick under a specified container, even when it is inserted elsewhere in the
- * document (for example, in a OO.ui.Window's $overlay).
+ * Element that will stick adjacent to a specified container, even when it is inserted elsewhere
+ * in the document (for example, in an OO.ui.Window's $overlay).
  *
  * The elements's position is automatically calculated and maintained when window is resized or the
  * page is scrolled. If you reposition the container manually, you have to call #position to make
@@ -3988,7 +4066,19 @@ OO.ui.mixin.PendingElement.prototype.popPending = function () {
  * @constructor
  * @param {Object} [config] Configuration options
  * @cfg {jQuery} [$floatable] Node to position, assigned to #$floatable, omit to use #$element
- * @cfg {jQuery} [$floatableContainer] Node to position below
+ * @cfg {jQuery} [$floatableContainer] Node to position adjacent to
+ * @cfg {string} [verticalPosition='below'] Where to position $floatable vertically:
+ *  'below': Directly below $floatableContainer, aligning f's top edge with fC's bottom edge
+ *  'above': Directly above $floatableContainer, aligning f's bottom edge with fC's top edge
+ *  'top': Align the top edge with $floatableContainer's top edge
+ *  'bottom': Align the bottom edge with $floatableContainer's bottom edge
+ *  'center': Vertically align the center with $floatableContainer's center
+ * @cfg {string} [horizontalPosition='start'] Where to position $floatable horizontally:
+ *  'before': Directly before $floatableContainer, aligning f's end edge with fC's start edge
+ *  'after': Directly after $floatableContainer, algining f's start edge with fC's end edge
+ *  'start': Align the start (left in LTR, right in RTL) edge with $floatableContainer's start edge
+ *  'end': Align the end (right in LTR, left in RTL) edge with $floatableContainer's end edge
+ *  'center': Horizontally align the center with $floatableContainer's center
  */
 OO.ui.mixin.FloatableElement = function OoUiMixinFloatableElement( config ) {
        // Configuration initialization
@@ -4005,6 +4095,8 @@ OO.ui.mixin.FloatableElement = function OoUiMixinFloatableElement( config ) {
        // Initialization
        this.setFloatableContainer( config.$floatableContainer );
        this.setFloatableElement( config.$floatable || this.$element );
+       this.setVerticalPosition( config.verticalPosition || 'below' );
+       this.setHorizontalPosition( config.horizontalPosition || 'start' );
 };
 
 /* Methods */
@@ -4029,7 +4121,7 @@ OO.ui.mixin.FloatableElement.prototype.setFloatableElement = function ( $floatab
 /**
  * Set floatable container.
  *
- * The element will be always positioned under the specified container.
+ * The element will be positioned relative to the specified container.
  *
  * @param {jQuery|null} $floatableContainer Container to keep visible, or null to unset
  */
@@ -4040,6 +4132,36 @@ OO.ui.mixin.FloatableElement.prototype.setFloatableContainer = function ( $float
        }
 };
 
+/**
+ * Change how the element is positioned vertically.
+ *
+ * @param {string} position 'below', 'above', 'top', 'bottom' or 'center'
+ */
+OO.ui.mixin.FloatableElement.prototype.setVerticalPosition = function ( position ) {
+       if ( [ 'below', 'above', 'top', 'bottom', 'center' ].indexOf( position ) === -1 ) {
+               throw new Error( 'Invalid value for vertical position: ' + position );
+       }
+       this.verticalPosition = position;
+       if ( this.$floatable ) {
+               this.position();
+       }
+};
+
+/**
+ * Change how the element is positioned horizontally.
+ *
+ * @param {string} position 'before', 'after', 'start', 'end' or 'center'
+ */
+OO.ui.mixin.FloatableElement.prototype.setHorizontalPosition = function ( position ) {
+       if ( [ 'before', 'after', 'start', 'end', 'center' ].indexOf( position ) === -1 ) {
+               throw new Error( 'Invalid value for horizontal position: ' + position );
+       }
+       this.horizontalPosition = position;
+       if ( this.$floatable ) {
+               this.position();
+       }
+};
+
 /**
  * Toggle positioning.
  *
@@ -4057,11 +4179,20 @@ OO.ui.mixin.FloatableElement.prototype.togglePositioning = function ( positionin
 
        positioning = positioning === undefined ? !this.positioning : !!positioning;
 
+       if ( positioning && !this.warnedUnattached && !this.isElementAttached() ) {
+               OO.ui.warnDeprecation( 'FloatableElement#togglePositioning: Before calling this method, the element must be attached to the DOM.' );
+               this.warnedUnattached = true;
+       }
+
        if ( this.positioning !== positioning ) {
                this.positioning = positioning;
 
+               this.needsCustomPosition =
+                       this.verticalPostion !== 'below' ||
+                       this.horizontalPosition !== 'start' ||
+                       !OO.ui.contains( this.$floatableContainer[ 0 ], this.$floatable[ 0 ] );
+
                closestScrollableOfContainer = OO.ui.Element.static.getClosestScrollableContainer( this.$floatableContainer[ 0 ] );
-               this.needsCustomPosition = !OO.ui.contains( this.$floatableContainer[ 0 ], this.$floatable[ 0 ] );
                // If the scrollable is the root, we have to listen to scroll events
                // on the window because of browser inconsistencies.
                if ( $( closestScrollableOfContainer ).is( 'html, body' ) ) {
@@ -4104,10 +4235,9 @@ OO.ui.mixin.FloatableElement.prototype.togglePositioning = function ( positionin
  * @return {boolean}
  */
 OO.ui.mixin.FloatableElement.prototype.isElementInViewport = function ( $element, $container ) {
-       var elemRect, contRect,
-               leftEdgeInBounds = false,
-               bottomEdgeInBounds = false,
-               rightEdgeInBounds = false;
+       var elemRect, contRect, topEdgeInBounds, bottomEdgeInBounds, leftEdgeInBounds, rightEdgeInBounds,
+               startEdgeInBounds, endEdgeInBounds,
+               direction = $element.css( 'direction' );
 
        elemRect = $element[ 0 ].getBoundingClientRect();
        if ( $container[ 0 ] === window ) {
@@ -4121,20 +4251,35 @@ OO.ui.mixin.FloatableElement.prototype.isElementInViewport = function ( $element
                contRect = $container[ 0 ].getBoundingClientRect();
        }
 
-       // For completeness, if we still cared about topEdgeInBounds, that'd be:
-       // elemRect.top >= contRect.top && elemRect.top <= contRect.bottom
-       if ( elemRect.left >= contRect.left && elemRect.left <= contRect.right ) {
-               leftEdgeInBounds = true;
+       topEdgeInBounds = elemRect.top >= contRect.top && elemRect.top <= contRect.bottom;
+       bottomEdgeInBounds = elemRect.bottom >= contRect.top && elemRect.bottom <= contRect.bottom;
+       leftEdgeInBounds = elemRect.left >= contRect.left && elemRect.left <= contRect.right;
+       rightEdgeInBounds = elemRect.right >= contRect.left && elemRect.right <= contRect.right;
+       if ( direction === 'rtl' ) {
+               startEdgeInBounds = rightEdgeInBounds;
+               endEdgeInBounds = leftEdgeInBounds;
+       } else {
+               startEdgeInBounds = leftEdgeInBounds;
+               endEdgeInBounds = rightEdgeInBounds;
        }
-       if ( elemRect.bottom >= contRect.top && elemRect.bottom <= contRect.bottom ) {
-               bottomEdgeInBounds = true;
+
+       if ( this.verticalPosition === 'below' && !bottomEdgeInBounds ) {
+               return false;
        }
-       if ( elemRect.right >= contRect.left && elemRect.right <= contRect.right ) {
-               rightEdgeInBounds = true;
+       if ( this.verticalPosition === 'above' && !topEdgeInBounds ) {
+               return false;
+       }
+       if ( this.horizontalPosition === 'before' && !startEdgeInBounds ) {
+               return false;
+       }
+       if ( this.horizontalPosition === 'after' && !endEdgeInBounds ) {
+               return false;
        }
 
-       // We only care that any part of the bottom edge is visible
-       return bottomEdgeInBounds && ( leftEdgeInBounds || rightEdgeInBounds );
+       // The other positioning values are all about being inside the container,
+       // so in those cases all we care about is that any part of the container is visible.
+       return elemRect.top <= contRect.bottom && elemRect.bottom >= contRect.top &&
+               elemRect.left <= contRect.right && elemRect.right >= contRect.left;
 };
 
 /**
@@ -4145,7 +4290,9 @@ OO.ui.mixin.FloatableElement.prototype.isElementInViewport = function ( $element
  * @chainable
  */
 OO.ui.mixin.FloatableElement.prototype.position = function () {
-       var pos;
+       var containerPos, direction, $offsetParent, isBody, scrollableX, scrollableY,
+               horizScrollbarHeight, vertScrollbarWidth, scrollTop, scrollLeft,
+               newPos = { top: '', left: '', bottom: '', right: '' };
 
        if ( !this.positioning ) {
                return this;
@@ -4162,16 +4309,106 @@ OO.ui.mixin.FloatableElement.prototype.position = function () {
                return;
        }
 
-       pos = OO.ui.Element.static.getRelativePosition( this.$floatableContainer, this.$floatable.offsetParent() );
-       // Position under container
-       pos.top += this.$floatableContainer.height();
-       // In LTR, we position from the left, and pos.left is already set
-       // In RTL, we position from the right instead.
-       if ( this.$floatableContainer.css( 'direction' ) === 'rtl' ) {
-               pos.right = this.$floatable.offsetParent().width() - pos.left - this.$floatableContainer.outerWidth();
-               delete pos.left;
+       direction = this.$floatableContainer.css( 'direction' );
+       $offsetParent = this.$floatable.offsetParent();
+       if ( $offsetParent.is( 'html' ) ) {
+               // The innerHeight/Width and clientHeight/Width calculations don't work well on the
+               // <html> element, but they do work on the <body>
+               $offsetParent = $( $offsetParent[ 0 ].ownerDocument.body );
+       }
+       isBody = $offsetParent.is( 'body' );
+       scrollableX = $offsetParent.css( 'overflow-x' ) === 'scroll' || $offsetParent.css( 'overflow-x' ) === 'auto';
+       scrollableY = $offsetParent.css( 'overflow-y' ) === 'scroll' || $offsetParent.css( 'overflow-y' ) === 'auto';
+
+       vertScrollbarWidth = $offsetParent.innerWidth() - $offsetParent.prop( 'clientWidth' );
+       horizScrollbarHeight = $offsetParent.innerHeight() - $offsetParent.prop( 'clientHeight' );
+       // We don't need to compute and add scrollTop and scrollLeft if the scrollable container is the body,
+       // or if it isn't scrollable
+       scrollTop = scrollableY && !isBody ? $offsetParent.scrollTop() : 0;
+       scrollLeft = scrollableX && !isBody ? OO.ui.Element.static.getScrollLeft( $offsetParent[ 0 ] ) : 0;
+
+       // Avoid passing the <body> to getRelativePosition(), because it won't return what we expect
+       // if the <body> has a margin
+       containerPos = isBody ?
+               this.$floatableContainer.offset() :
+               OO.ui.Element.static.getRelativePosition( this.$floatableContainer, $offsetParent );
+       containerPos.bottom = containerPos.top + this.$floatableContainer.outerHeight();
+       containerPos.right = containerPos.left + this.$floatableContainer.outerWidth();
+       containerPos.start = direction === 'rtl' ? containerPos.right : containerPos.left;
+       containerPos.end = direction === 'rtl' ? containerPos.left : containerPos.right;
+
+       if ( this.verticalPosition === 'below' ) {
+               newPos.top = containerPos.bottom;
+       } else if ( this.verticalPosition === 'above' ) {
+               newPos.bottom = $offsetParent.outerHeight() - containerPos.top;
+       } else if ( this.verticalPosition === 'top' ) {
+               newPos.top = containerPos.top;
+       } else if ( this.verticalPosition === 'bottom' ) {
+               newPos.bottom = $offsetParent.outerHeight() - containerPos.bottom;
+       } else if ( this.verticalPosition === 'center' ) {
+               newPos.top = containerPos.top +
+                       ( this.$floatableContainer.height() - this.$floatable.height() ) / 2;
+       }
+
+       if ( this.horizontalPosition === 'before' ) {
+               newPos.end = containerPos.start;
+       } else if ( this.horizontalPosition === 'after' ) {
+               newPos.start = containerPos.end;
+       } else if ( this.horizontalPosition === 'start' ) {
+               newPos.start = containerPos.start;
+       } else if ( this.horizontalPosition === 'end' ) {
+               newPos.end = containerPos.end;
+       } else if ( this.horizontalPosition === 'center' ) {
+               newPos.left = containerPos.left +
+                       ( this.$floatableContainer.width() - this.$floatable.width() ) / 2;
+       }
+
+       if ( newPos.start !== undefined ) {
+               if ( direction === 'rtl' ) {
+                       newPos.right = ( isBody ? $( $offsetParent[ 0 ].ownerDocument.documentElement ) : $offsetParent ).outerWidth() - newPos.start;
+               } else {
+                       newPos.left = newPos.start;
+               }
+               delete newPos.start;
+       }
+       if ( newPos.end !== undefined ) {
+               if ( direction === 'rtl' ) {
+                       newPos.left = newPos.end;
+               } else {
+                       newPos.right = ( isBody ? $( $offsetParent[ 0 ].ownerDocument.documentElement ) : $offsetParent ).outerWidth() - newPos.end;
+               }
+               delete newPos.end;
+       }
+
+       // Account for scroll position
+       if ( newPos.top !== '' ) {
+               newPos.top += scrollTop;
+       }
+       if ( newPos.bottom !== '' ) {
+               newPos.bottom -= scrollTop;
+       }
+       if ( newPos.left !== '' ) {
+               newPos.left += scrollLeft;
+       }
+       if ( newPos.right !== '' ) {
+               newPos.right -= scrollLeft;
        }
-       this.$floatable.css( pos );
+
+       // Account for scrollbar gutter
+       if ( newPos.bottom !== '' ) {
+               newPos.bottom -= horizScrollbarHeight;
+       }
+       if ( direction === 'rtl' ) {
+               if ( newPos.left !== '' ) {
+                       newPos.left -= vertScrollbarWidth;
+               }
+       } else {
+               if ( newPos.right !== '' ) {
+                       newPos.right -= vertScrollbarWidth;
+               }
+       }
+
+       this.$floatable.css( newPos );
 
        // We updated the position, so re-evaluate the clipping state.
        // (ClippableElement does not listen to 'scroll' events on $floatableContainer's parent, and so
@@ -4281,6 +4518,11 @@ OO.ui.mixin.ClippableElement.prototype.setClippableContainer = function ( $clipp
 OO.ui.mixin.ClippableElement.prototype.toggleClipping = function ( clipping ) {
        clipping = clipping === undefined ? !this.clipping : !!clipping;
 
+       if ( clipping && !this.warnedUnattached && !this.isElementAttached() ) {
+               OO.ui.warnDeprecation( 'ClippableElement#toggleClipping: Before calling this method, the element must be attached to the DOM.' );
+               this.warnedUnattached = true;
+       }
+
        if ( this.clipping !== clipping ) {
                this.clipping = clipping;
                if ( clipping ) {
@@ -4476,6 +4718,8 @@ OO.ui.mixin.ClippableElement.prototype.clip = function () {
  * By default, each popup has an anchor that points toward its origin.
  * Please see the [OOjs UI documentation on Mediawiki] [1] for more information and examples.
  *
+ * Unlike most widgets, PopupWidget is initially hidden and must be shown by calling #toggle.
+ *
  *     @example
  *     // A popup widget.
  *     var popup = new OO.ui.PopupWidget( {
@@ -4717,6 +4961,14 @@ OO.ui.PopupWidget.prototype.hasAnchor = function () {
 };
 
 /**
+ * Toggle visibility of the popup. The popup is initially hidden and must be shown by calling
+ * `.toggle( true )` after its #$element is attached to the DOM.
+ *
+ * Do not show the popup while it is not attached to the DOM. The calculations required to display
+ * it in the right place and with the right dimensions only work correctly while it is attached.
+ * Side-effects may include broken interface and exceptions being thrown. This wasn't always
+ * strictly enforced, so currently it only generates a warning in the browser console.
+ *
  * @inheritdoc
  */
 OO.ui.PopupWidget.prototype.toggle = function ( show ) {
@@ -4725,6 +4977,11 @@ OO.ui.PopupWidget.prototype.toggle = function ( show ) {
 
        change = show !== this.isVisible();
 
+       if ( show && !this.warnedUnattached && !this.isElementAttached() ) {
+               OO.ui.warnDeprecation( 'PopupWidget#toggle: Before calling this method, the popup must be attached to the DOM.' );
+               this.warnedUnattached = true;
+       }
+
        // Parent method
        OO.ui.PopupWidget.parent.prototype.toggle.call( this, show );
 
@@ -6362,6 +6619,8 @@ OO.ui.MenuSectionOptionWidget.static.highlightable = false;
  * - Down-arrow key: highlight the next menu option
  * - Esc key: hide the menu
  *
+ * Unlike most widgets, MenuSelectWidget is initially hidden and must be shown by calling #toggle.
+ *
  * Please see the [OOjs UI documentation on MediaWiki][1] for more information.
  * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options
  *
@@ -6381,6 +6640,7 @@ OO.ui.MenuSectionOptionWidget.static.highlightable = false;
  *  that toggles the menu's visibility on click, the menu will be hidden then re-shown when the user clicks
  *  that button, unless the button (or its parent widget) is passed in here.
  * @cfg {boolean} [autoHide=true] Hide the menu when the mouse is pressed outside the menu.
+ * @cfg {boolean} [hideOnChoose=true] Hide the menu when the user chooses an option.
  * @cfg {boolean} [filterFromInput=false] Filter the displayed options from the input
  */
 OO.ui.MenuSelectWidget = function OoUiMenuSelectWidget( config ) {
@@ -6395,6 +6655,7 @@ OO.ui.MenuSelectWidget = function OoUiMenuSelectWidget( config ) {
 
        // Properties
        this.autoHide = config.autoHide === undefined || !!config.autoHide;
+       this.hideOnChoose = config.hideOnChoose === undefined || !!config.hideOnChoose;
        this.filterFromInput = !!config.filterFromInput;
        this.$input = config.$input ? config.$input : config.input ? config.input.$input : null;
        this.$widget = config.widget ? config.widget.$element : null;
@@ -6548,7 +6809,7 @@ OO.ui.MenuSelectWidget.prototype.unbindKeyPressListener = function () {
 /**
  * Choose an item.
  *
- * When a user chooses an item, the menu is closed.
+ * When a user chooses an item, the menu is closed, unless the hideOnChoose config option is set to false.
  *
  * Note that ‘choose’ should never be modified programmatically. A user can choose an option with the keyboard
  * or mouse and it becomes selected. To select an item programmatically, use the #selectItem method.
@@ -6558,7 +6819,9 @@ OO.ui.MenuSelectWidget.prototype.unbindKeyPressListener = function () {
  */
 OO.ui.MenuSelectWidget.prototype.chooseItem = function ( item ) {
        OO.ui.MenuSelectWidget.parent.prototype.chooseItem.call( this, item );
-       this.toggle( false );
+       if ( this.hideOnChoose ) {
+               this.toggle( false );
+       }
        return this;
 };
 
@@ -6602,6 +6865,14 @@ OO.ui.MenuSelectWidget.prototype.clearItems = function () {
 };
 
 /**
+ * Toggle visibility of the menu. The menu is initially hidden and must be shown by calling
+ * `.toggle( true )` after its #$element is attached to the DOM.
+ *
+ * Do not show the menu while it is not attached to the DOM. The calculations required to display
+ * it in the right place and with the right dimensions only work correctly while it is attached.
+ * Side-effects may include broken interface and exceptions being thrown. This wasn't always
+ * strictly enforced, so currently it only generates a warning in the browser console.
+ *
  * @inheritdoc
  */
 OO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) {
@@ -6610,6 +6881,11 @@ OO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) {
        visible = ( visible === undefined ? !this.visible : !!visible ) && !!this.items.length;
        change = visible !== this.isVisible();
 
+       if ( visible && !this.warnedUnattached && !this.isElementAttached() ) {
+               OO.ui.warnDeprecation( 'MenuSelectWidget#toggle: Before calling this method, the menu must be attached to the DOM.' );
+               this.warnedUnattached = true;
+       }
+
        // Parent method
        OO.ui.MenuSelectWidget.parent.prototype.toggle.call( this, visible );
 
@@ -10077,6 +10353,7 @@ OO.ui.ComboBoxInputWidget.prototype.setOptions = function ( options ) {
  * @cfg {string|OO.ui.HtmlSnippet} [help] Help text. When help text is specified, a "help" icon will appear
  *  in the upper-right corner of the rendered field; clicking it will display the text in a popup.
  *  For important messages, you are advised to use `notices`, as they are always shown.
+ * @cfg {jQuery} [$overlay] Passed to OO.ui.PopupButtonWidget for help popup, if `help` is given.
  *
  * @throws {Error} An error is thrown if no widget is specified
  */
@@ -10115,6 +10392,7 @@ OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) {
        this.align = null;
        if ( config.help ) {
                this.popupButtonWidget = new OO.ui.PopupButtonWidget( {
+                       $overlay: config.$overlay,
                        popup: {
                                padded: true
                        },
@@ -10139,6 +10417,11 @@ OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) {
        if ( fieldWidget.constructor.static.supportsSimpleLabel ) {
                if ( this.fieldWidget.getInputId() ) {
                        this.$label.attr( 'for', this.fieldWidget.getInputId() );
+               } else {
+                       this.$label.on( 'click', function () {
+                               this.fieldWidget.focus();
+                               return false;
+                       }.bind( this ) );
                }
        }
        this.$element
@@ -10419,6 +10702,7 @@ OO.inheritClass( OO.ui.ActionFieldLayout, OO.ui.FieldLayout );
  * @cfg {string|OO.ui.HtmlSnippet} [help] Help text. When help text is specified, a "help" icon will appear
  *  in the upper-right corner of the rendered field; clicking it will display the text in a popup.
  *  For important messages, you are advised to use `notices`, as they are always shown.
+ * @cfg {jQuery} [$overlay] Passed to OO.ui.PopupButtonWidget for help popup, if `help` is given.
  */
 OO.ui.FieldsetLayout = function OoUiFieldsetLayout( config ) {
        // Configuration initialization
@@ -10436,6 +10720,7 @@ OO.ui.FieldsetLayout = function OoUiFieldsetLayout( config ) {
        this.$header = $( '<div>' );
        if ( config.help ) {
                this.popupButtonWidget = new OO.ui.PopupButtonWidget( {
+                       $overlay: config.$overlay,
                        popup: {
                                padded: true
                        },
index 3989caa..b39010c 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.19.2
+ * OOjs UI v0.19.4
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-02-14T22:47:20Z
+ * Date: 2017-02-28T23:19:40Z
  */
 ( function ( OO ) {
 
index b154288..4d7f9d7 100644 (file)
@@ -1,13 +1,15 @@
 /*!
- * OOjs UI v0.19.2
+ * OOjs UI v0.19.4
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-02-14T22:47:25Z
+ * Date: 2017-02-28T23:19:44Z
  */
+/* stylelint-disable selector-no-vendor-prefix, at-rule-no-unknown */
+/* stylelint-enable selector-no-vendor-prefix, at-rule-no-unknown */
 .oo-ui-popupTool .oo-ui-popupWidget-popup,
 .oo-ui-popupTool .oo-ui-popupWidget-anchor {
   z-index: 4;
index 5d313ab..59de29b 100644 (file)
@@ -1,13 +1,15 @@
 /*!
- * OOjs UI v0.19.2
+ * OOjs UI v0.19.4
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-02-14T22:47:25Z
+ * Date: 2017-02-28T23:19:44Z
  */
+/* stylelint-disable selector-no-vendor-prefix, at-rule-no-unknown */
+/* stylelint-enable selector-no-vendor-prefix, at-rule-no-unknown */
 .oo-ui-tool.oo-ui-widget-enabled {
   -webkit-transition: background-color 100ms;
      -moz-transition: background-color 100ms;
@@ -37,9 +39,6 @@
   height: 2.5em;
   width: 1.875em;
 }
-.oo-ui-toolGroupTool > .oo-ui-popupToolGroup.oo-ui-labelElement > .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-  line-height: 2.1;
-}
 .oo-ui-toolGroup {
   display: inline-block;
   vertical-align: middle;
   width: 1.875em;
   min-width: 1.875em;
 }
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title,
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel {
-  line-height: 2;
-}
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
   padding-left: 0.5em;
   color: #222;
index e89a734..777debf 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.19.2
+ * OOjs UI v0.19.4
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-02-14T22:47:20Z
+ * Date: 2017-02-28T23:19:40Z
  */
 ( function ( OO ) {
 
index b8445e9..a1064bb 100644 (file)
@@ -1,13 +1,15 @@
 /*!
- * OOjs UI v0.19.2
+ * OOjs UI v0.19.4
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-02-14T22:47:25Z
+ * Date: 2017-02-28T23:19:44Z
  */
+/* stylelint-disable selector-no-vendor-prefix, at-rule-no-unknown */
+/* stylelint-enable selector-no-vendor-prefix, at-rule-no-unknown */
 .oo-ui-draggableElement-handle,
 .oo-ui-draggableElement-handle.oo-ui-widget {
   cursor: move;
@@ -33,7 +35,7 @@
   display: inline-block;
 }
 .oo-ui-bookletLayout-stackLayout.oo-ui-stackLayout-continuous > .oo-ui-panelLayout-scrollable {
-  overflow-y: hidden;
+  overflow: hidden;
 }
 .oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout {
   width: 100%;
      -moz-box-sizing: border-box;
           box-sizing: border-box;
 }
-.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout-scrollable {
-  overflow-y: auto;
-}
-.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout-padded {
-  padding: 2em;
-}
 .oo-ui-bookletLayout-outlinePanel-editable > .oo-ui-outlineSelectWidget {
   position: absolute;
   top: 0;
   left: 0;
   right: 0;
   bottom: 3em;
-  overflow-y: auto;
+  overflow: auto;
 }
 .oo-ui-bookletLayout-outlinePanel > .oo-ui-outlineControlsWidget {
   position: absolute;
 .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator,
 .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
   position: absolute;
+  top: 0;
+  height: 100%;
 }
 .oo-ui-widget-disabled .oo-ui-selectFileWidget-info {
   cursor: default;
   border-width: 1px 0 1px 1px;
 }
 .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
-  top: 0;
   left: 0;
-  height: 2.3em;
   margin-left: 0.3em;
 }
 .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
-  top: 0;
   right: 0;
-  height: 2.3em;
   margin-right: 0.775em;
 }
 .oo-ui-selectFileWidget-label {
   background-color: #a7dcff;
   text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
 }
-.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-important {
-  font-weight: bold;
-}
-.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-iconElement-icon {
-  opacity: 0.5;
-}
-.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-labelElement-label {
-  color: #777;
-}
 .oo-ui-outlineControlsWidget {
   height: 3em;
   background-color: #fff;
   display: block;
   position: relative;
 }
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-iconElement-icon,
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-indicatorElement-indicator {
+  position: absolute;
+  top: 0;
+  height: 100%;
+}
 .oo-ui-capsuleMultiselectWidget-content {
   position: relative;
 }
 .oo-ui-capsuleMultiselectWidget-handle:last-child {
   margin-right: 0;
 }
-.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-indicatorElement-indicator,
-.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-iconElement-icon {
-  position: absolute;
-}
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input {
   border: 0;
   line-height: 1.675em;
   background-color: transparent;
   color: #000;
   vertical-align: middle;
+  /* stylelint-disable indentation */
+  /* stylelint-enable indentation */
 }
-.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input:focus {
-  outline: none;
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input::-webkit-input-placeholder {
+  color: #72777d;
+  opacity: 1;
 }
-.oo-ui-capsuleMultiselectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiselectWidget-handle {
-  padding-right: 2.4875em;
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input:-ms-input-placeholder {
+  color: #72777d;
+  opacity: 1;
 }
-.oo-ui-capsuleMultiselectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-indicatorElement-indicator {
-  right: 0;
-  top: 0;
-  margin: 0.775em;
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input::-moz-placeholder {
+  color: #72777d;
+  opacity: 1;
+}
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input:-moz-placeholder {
+  color: #72777d;
+  opacity: 1;
+}
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input::placeholder {
+  color: #72777d;
+  opacity: 1;
+}
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input:focus {
+  outline: 0;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-iconElement .oo-ui-capsuleMultiselectWidget-handle {
   padding-left: 2.475em;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-iconElement .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-iconElement-icon {
   left: 0;
-  top: 0;
-  margin: 0.3em;
+  margin: 0 0.3em;
+}
+.oo-ui-capsuleMultiselectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiselectWidget-handle {
+  padding-right: 2.4875em;
+}
+.oo-ui-capsuleMultiselectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-indicatorElement-indicator {
+  right: 0;
+  margin: 0 0.775em;
 }
 .oo-ui-capsuleMultiselectWidget:hover .oo-ui-capsuleMultiselectWidget-handle {
   border-color: rgba(0, 0, 0, 0.2);
   cursor: text;
 }
 .oo-ui-capsuleItemWidget:focus {
-  outline: none;
+  outline: 0;
   border-color: #087ecc;
 }
 .oo-ui-capsuleItemWidget.oo-ui-widget-disabled {
index aab3b62..495cbfe 100644 (file)
@@ -1,13 +1,15 @@
 /*!
- * OOjs UI v0.19.2
+ * OOjs UI v0.19.4
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-02-14T22:47:25Z
+ * Date: 2017-02-28T23:19:44Z
  */
+/* stylelint-disable selector-no-vendor-prefix, at-rule-no-unknown */
+/* stylelint-enable selector-no-vendor-prefix, at-rule-no-unknown */
 .oo-ui-draggableElement-handle,
 .oo-ui-draggableElement-handle.oo-ui-widget {
   cursor: move;
 .oo-ui-draggableGroupElement-horizontal .oo-ui-draggableElement {
   display: inline-block;
 }
+.oo-ui-draggableElement-handle:focus {
+  border-radius: 2px;
+  box-shadow: inset 0 0 0 1px #36c, 0 0 0 1px #36c;
+  outline: 0;
+}
 .oo-ui-bookletLayout-stackLayout.oo-ui-stackLayout-continuous > .oo-ui-panelLayout-scrollable {
-  overflow-y: hidden;
+  overflow: hidden;
 }
 .oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout {
   width: 100%;
      -moz-box-sizing: border-box;
           box-sizing: border-box;
 }
-.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout-scrollable {
-  overflow-y: auto;
-}
-.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout-padded {
-  padding: 2em;
-}
 .oo-ui-bookletLayout-outlinePanel-editable > .oo-ui-outlineSelectWidget {
   position: absolute;
   top: 0;
   left: 0;
   right: 0;
   bottom: 3em;
-  overflow-y: auto;
+  overflow: auto;
 }
 .oo-ui-bookletLayout-outlinePanel > .oo-ui-outlineControlsWidget {
   position: absolute;
 .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator,
 .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
   position: absolute;
+  top: 0;
+  height: 100%;
 }
 .oo-ui-widget-disabled .oo-ui-selectFileWidget-info {
   cursor: default;
 }
 .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
   left: 0;
-  top: 0;
-  height: 2.3em;
   margin-left: 0.5em;
 }
 .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
-  top: 0;
   right: 0;
-  height: 2.3em;
   margin-right: 0.775em;
 }
 .oo-ui-selectFileWidget-label {
 .oo-ui-selectFileWidget-notsupported.oo-ui-indicatorElement .oo-ui-selectFileWidget-label {
   right: 2em;
 }
-.oo-ui-selectFileWidget-supported.oo-ui-widget-enabled.oo-ui-selectFileWidget-canDrop.oo-ui-selectFileWidget-dropTarget {
-  background-color: #eaf3ff;
-}
 .oo-ui-selectFileWidget-dropTarget {
   background-color: #fff;
   border: 1px solid #a2a9b1;
+  border-radius: 2px;
   vertical-align: middle;
   overflow: hidden;
-  border-radius: 2px;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
   border-radius: 2px;
   white-space: normal;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-widget-enabled.oo-ui-selectFileWidget-dropTarget {
-  background-color: #eee;
+  background-color: #fff;
   border-style: dashed;
+  -webkit-transition: background-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+     -moz-transition: background-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+          transition: background-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+}
+.oo-ui-selectFileWidget-empty.oo-ui-widget-enabled.oo-ui-selectFileWidget-dropTarget:hover {
+  border-color: #72777d;
+}
+.oo-ui-selectFileWidget-supported.oo-ui-widget-enabled.oo-ui-selectFileWidget-canDrop.oo-ui-selectFileWidget-dropTarget {
+  background-color: #eaf3ff;
+  color: #36c;
 }
 .oo-ui-selectFileWidget.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
 .oo-ui-selectFileWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
 .oo-ui-outlineOptionWidget-level-2 .oo-ui-iconElement-icon {
   left: 4em;
 }
-.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-important {
-  font-weight: bold;
-}
-.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-iconElement-icon {
-  opacity: 0.5;
-}
-.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-labelElement-label {
-  color: #777;
-}
 .oo-ui-outlineControlsWidget {
   height: 3em;
   background-color: #fff;
   display: block;
   position: relative;
 }
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-iconElement-icon,
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-indicatorElement-indicator {
+  position: absolute;
+  top: 0;
+  height: 100%;
+}
 .oo-ui-capsuleMultiselectWidget-content {
   position: relative;
 }
 .oo-ui-capsuleMultiselectWidget-handle:last-child {
   margin-right: 0;
 }
-.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-indicatorElement-indicator,
-.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-iconElement-icon {
-  position: absolute;
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input {
+  border: 0;
+  line-height: 1.675;
+  margin: 0 0 0 0.2em;
+  padding: 0;
+  font-size: inherit;
+  font-family: inherit;
+  background-color: transparent;
+  color: #000;
+  vertical-align: middle;
+  /* stylelint-disable indentation */
+  /* stylelint-enable indentation */
 }
-.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content :-moz-placeholder {
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input::-webkit-input-placeholder {
   color: #72777d;
   opacity: 1;
 }
-.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content ::-moz-placeholder {
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input:-ms-input-placeholder {
   color: #72777d;
   opacity: 1;
 }
-.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content :-ms-input-placeholder {
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input::-moz-placeholder {
   color: #72777d;
+  opacity: 1;
 }
-.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content ::-webkit-input-placeholder {
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input:-moz-placeholder {
   color: #72777d;
+  opacity: 1;
 }
-.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content :placeholder-shown {
+.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input::placeholder {
   color: #72777d;
-}
-.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input {
-  border: 0;
-  line-height: 1.675;
-  margin: 0 0 0 0.2em;
-  padding: 0;
-  font-size: inherit;
-  font-family: inherit;
-  background-color: transparent;
-  color: #000;
-  vertical-align: middle;
+  opacity: 1;
 }
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input:focus {
   outline: 0;
 }
-.oo-ui-capsuleMultiselectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiselectWidget-handle {
-  padding-right: 2.4875em;
-}
-.oo-ui-capsuleMultiselectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-indicatorElement-indicator {
-  right: 0;
-  top: 0;
-  margin: 0.775em;
-}
 .oo-ui-capsuleMultiselectWidget.oo-ui-iconElement .oo-ui-capsuleMultiselectWidget-handle {
   padding-left: 2.475em;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-iconElement .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-iconElement-icon {
   left: 0;
-  top: 0;
-  margin: 0.3em;
+  margin: 0 0.3em;
+}
+.oo-ui-capsuleMultiselectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiselectWidget-handle {
+  padding-right: 2.4875em;
+}
+.oo-ui-capsuleMultiselectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-indicatorElement-indicator {
+  right: 0;
+  margin: 0 0.775em;
 }
 .oo-ui-capsuleMultiselectWidget-popup {
   margin-top: -1px;
   display: inline-block;
   cursor: default;
   white-space: nowrap;
-  width: auto;
-  max-width: 100%;
   -webkit-box-sizing: border-box;
      -moz-box-sizing: border-box;
           box-sizing: border-box;
-  vertical-align: middle;
+  width: auto;
+  max-width: 100%;
   height: 1.7em;
-  line-height: 1.7;
-  background-color: #eee;
-  color: #222;
   margin: 0.1em;
   border: 1px solid #a2a9b1;
   border-radius: 2px;
   padding: 0 0.4em;
+  line-height: 1.7;
+  vertical-align: middle;
 }
 .oo-ui-capsuleItemWidget.oo-ui-labelElement .oo-ui-labelElement-label {
   display: inline-block;
   overflow: hidden;
   cursor: text;
 }
-.oo-ui-capsuleItemWidget:focus {
-  outline: 0;
-  border-color: #36c;
-  box-shadow: inset 0 0 0 1px #36c;
-}
-.oo-ui-capsuleItemWidget.oo-ui-widget-disabled {
-  background-color: #eaecf0;
-  color: #72777d;
-  border-color: #c8ccd1;
-  text-shadow: 0 1px 1px #fff;
-}
-.oo-ui-capsuleItemWidget > .oo-ui-buttonElement {
-  display: none;
-}
 .oo-ui-capsuleItemWidget.oo-ui-widget-enabled {
+  background-color: #f8f9fa;
+  color: #222;
   padding-right: 1.5375em;
+  -webkit-transition: background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
+     -moz-transition: background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
+          transition: background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
+}
+.oo-ui-capsuleItemWidget.oo-ui-widget-enabled:hover {
+  background-color: #fff;
+  color: #444;
+  border-color: #a2a9b1;
+}
+.oo-ui-capsuleItemWidget.oo-ui-widget-enabled:focus {
+  border-color: #36c;
+  box-shadow: inset 0 0 0 1px #36c;
+  outline: 0;
 }
 .oo-ui-capsuleItemWidget.oo-ui-widget-enabled > .oo-ui-buttonElement {
   display: block;
   bottom: 0;
   height: auto;
 }
+.oo-ui-capsuleItemWidget.oo-ui-widget-disabled {
+  background-color: #eaecf0;
+  color: #72777d;
+  border-color: #c8ccd1;
+  text-shadow: 0 1px 1px #fff;
+}
+.oo-ui-capsuleItemWidget.oo-ui-widget-disabled > .oo-ui-buttonElement {
+  display: none;
+}
 .oo-ui-searchWidget-query {
   position: absolute;
   top: 0;
index d5a796b..b89262d 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.19.2
+ * OOjs UI v0.19.4
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-02-14T22:47:20Z
+ * Date: 2017-02-28T23:19:40Z
  */
 ( function ( OO ) {
 
index 310d616..b546dd1 100644 (file)
@@ -1,13 +1,15 @@
 /*!
- * OOjs UI v0.19.2
+ * OOjs UI v0.19.4
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-02-14T22:47:25Z
+ * Date: 2017-02-28T23:19:44Z
  */
+/* stylelint-disable selector-no-vendor-prefix, at-rule-no-unknown */
+/* stylelint-enable selector-no-vendor-prefix, at-rule-no-unknown */
 .oo-ui-actionWidget.oo-ui-pendingElement-pending {
   background-image: /* @embed */ url(themes/apex/images/textures/pending.gif);
 }
index 4b99fa6..701c058 100644 (file)
@@ -1,13 +1,15 @@
 /*!
- * OOjs UI v0.19.2
+ * OOjs UI v0.19.4
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-02-14T22:47:25Z
+ * Date: 2017-02-28T23:19:44Z
  */
+/* stylelint-disable selector-no-vendor-prefix, at-rule-no-unknown */
+/* stylelint-enable selector-no-vendor-prefix, at-rule-no-unknown */
 .oo-ui-window {
   background: transparent;
 }
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless:active {
   background-color: rgba(0, 0, 0, 0.1);
 }
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:hover,
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:hover,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:hover,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:hover {
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:hover,
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:hover {
   background-color: rgba(8, 126, 204, 0.05);
 }
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:active,
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:active,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:active,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:active {
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:active,
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:active {
   background-color: rgba(8, 126, 204, 0.1);
 }
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive .oo-ui-labelElement-label,
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive .oo-ui-labelElement-label,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive .oo-ui-labelElement-label,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive .oo-ui-labelElement-label {
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive .oo-ui-labelElement-label {
   font-weight: bold;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive:hover,
index c842c62..ad3c226 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.19.2
+ * OOjs UI v0.19.4
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-02-14T22:47:20Z
+ * Date: 2017-02-28T23:19:40Z
  */
 ( function ( OO ) {
 
index ec755a1..ea2e2ec 100644 (file)
@@ -56,6 +56,7 @@
                        "rtl": "images/icons/articleRedirect-rtl.svg"
                } },
                "searchCaseSensitive": { "file": "images/icons/case-sensitive.svg" },
+               "searchDiacritics": { "file": "images/icons/diacritic.svg" },
                "searchRegularExpression": { "file": "images/icons/regular-expression.svg" },
                "specialCharacter": { "file": "images/icons/specialCharacter.svg" },
                "table": { "file": "images/icons/table.svg" },
index 449cb77..d68e70c 100644 (file)
                } },
                "clear": { "file": "images/icons/clear.svg" },
                "clock": { "file": "images/icons/clock.svg" },
+               "feedback": { "file": {
+                       "ltr": "images/icons/feedback-ltr.svg",
+                       "rtl": "images/icons/feedback-rtl.svg"
+               } },
                "funnel": { "file": {
                        "ltr": "images/icons/funnel-ltr.svg",
                        "rtl": "images/icons/funnel-rtl.svg"
index 46cd9b0..749e38f 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <g id="regular-expression">
+    <g id="case-sensitive">
         <path id="upper-case" d="M7.53 7L4 17h2.063l.72-2.406h3.624l.72 2.406h2.062L9.65 7h-2.12zm1.064 1.53L9.938 13H7.25l1.344-4.47z"/>
         <path id="lower-case" d="M18.55 17l-.184-1.035h-.055c-.35.44-.71.747-1.08.92-.37.167-.85.25-1.44.25-.564 0-.955-.208-1.377-.625-.42-.418-.627-1.012-.627-1.784 0-.808.283-1.403.846-1.784.568-.386 1.193-.607 2.208-.64l1.322-.04v-.335c0-.772-.396-1.158-1.187-1.158-.61 0-1.325.18-2.147.55l-.688-1.4c.877-.46 1.85-.69 2.916-.69 1.024 0 1.59.22 2.134.662.545.445.818 1.12.818 2.03V17h-1.45m-.394-3.527l-.802.027c-.604.018-1.054.127-1.35.327-.294.2-.442.504-.442.912 0 .58.336.87 1.008.87.48 0 .865-.137 1.152-.414.29-.277.436-.645.436-1.103v-.627"/>
     </g>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/diacritic.png b/resources/lib/oojs-ui/themes/apex/images/icons/diacritic.png
new file mode 100644 (file)
index 0000000..2359b19
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/diacritic.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/diacritic.svg b/resources/lib/oojs-ui/themes/apex/images/icons/diacritic.svg
new file mode 100644 (file)
index 0000000..4565101
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <g id="diacritic">
+      <path id="letter-a" d="M13.55 17l-.184-1.035h-.055c-.35.44-.71.747-1.08.92-.37.167-.85.25-1.44.25-.563 0-.954-.208-1.376-.625-.42-.418-.627-1.012-.627-1.784 0-.808.283-1.403.846-1.784.568-.386 1.193-.607 2.208-.64l1.323-.04v-.335c0-.772-.396-1.158-1.187-1.158-.61 0-1.325.18-2.147.55l-.69-1.4c.878-.46 1.85-.69 2.917-.69 1.024 0 1.59.22 2.134.66.546.446.82 1.12.82 2.03V17h-1.45m-.395-3.527l-.802.027c-.604.018-1.054.127-1.35.327-.294.2-.442.504-.442.912 0 .58.337.87 1.01.87.48 0 .864-.138 1.15-.415.29-.277.437-.645.437-1.103v-.627"/>
+      <path id="tilde" d="M12.012 7.527l-.466-.306a.832.832 0 0 1-.085-.048c-.264-.17-.467-.256-.608-.256a.518.518 0 0 0-.466.256c-.107.17-.16.418-.16.743v.066H9.047c0-.748.144-1.326.432-1.733.294-.407.703-.61 1.228-.61.203 0 .406.037.61.114.208.073.43.19.66.357l.517.355c.124.082.237.146.338.19a.77.77 0 0 0 .288.066c.204 0 .362-.088.475-.265.113-.176.17-.42.17-.735v-.066h1.177c0 .75-.147 1.327-.44 1.735-.29.407-.695.61-1.22.61-.203 0-.4-.032-.593-.098a3.107 3.107 0 0 1-.678-.373z"/>
+    </g>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr-invert.png
new file mode 100644 (file)
index 0000000..f49ebeb
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr-invert.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr-invert.svg
new file mode 100644 (file)
index 0000000..d32e478
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
+    <path d="M8.202 15.834l.568 2.101c.198.765 1.06 1.22 1.8 1.016.698-.193 1.125-.983.926-1.747l-.38-1.37H20L17.229 5 4.155 12.652c-.427.762.088 2.748.823 3.182h3.224z"/>
+</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr.png b/resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr.png
new file mode 100644 (file)
index 0000000..ac5787b
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr.svg b/resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr.svg
new file mode 100644 (file)
index 0000000..0fdeed9
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M8.202 15.834l.568 2.101c.198.765 1.06 1.22 1.8 1.016.698-.193 1.125-.983.926-1.747l-.38-1.37H20L17.229 5 4.155 12.652c-.427.762.088 2.748.823 3.182h3.224z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl-invert.png
new file mode 100644 (file)
index 0000000..efba220
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl-invert.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl-invert.svg
new file mode 100644 (file)
index 0000000..14be7ff
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
+    <path d="M15.798 15.834l-.568 2.101c-.198.765-1.06 1.22-1.8 1.016-.698-.193-1.125-.983-.926-1.747l.38-1.37H4L6.771 5l13.074 7.652c.427.762-.088 2.748-.823 3.182h-3.224z"/>
+</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl.png b/resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl.png
new file mode 100644 (file)
index 0000000..fdbe5e1
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl.svg b/resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl.svg
new file mode 100644 (file)
index 0000000..022d86d
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M15.798 15.834l-.568 2.101c-.198.765-1.06 1.22-1.8 1.016-.698-.193-1.125-.983-.926-1.747l.38-1.37H4L6.771 5l13.074 7.652c.427.762-.088 2.748-.823 3.182h-3.224z"/>
+</svg>
index 21efb82..7cbbced 100644 (file)
@@ -76,6 +76,7 @@
                        "rtl": "images/icons/articleRedirect-rtl.svg"
                } },
                "searchCaseSensitive": { "file": "images/icons/case-sensitive.svg" },
+               "searchDiacritics": { "file": "images/icons/diacritic.svg" },
                "searchRegularExpression": { "file": "images/icons/regular-expression.svg" },
                "specialCharacter": { "file": "images/icons/specialCharacter.svg" },
                "table": { "file": "images/icons/table.svg" },
index e040ffb..3436446 100644 (file)
                } },
                "clear": { "file": "images/icons/clear.svg" },
                "clock": { "file": "images/icons/clock.svg" },
+               "feedback": {
+                       "file": {
+                               "ltr": "images/icons/feedback-ltr.svg",
+                               "rtl": "images/icons/feedback-rtl.svg"
+                       },
+                       "variants": [ "progressive" ]
+               },
                "funnel": { "file": {
                        "ltr": "images/icons/funnel-ltr.svg",
                        "rtl": "images/icons/funnel-rtl.svg"
index dbd98d2..e5590a3 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#fff">
-    <g id="regular-expression">
+    <g id="case-sensitive">
         <path id="upper-case" d="M7.53 7L4 17h2.063l.72-2.406h3.624l.72 2.406h2.062L9.65 7h-2.12zm1.064 1.53L9.938 13H7.25l1.344-4.47z"/>
         <path id="lower-case" d="M18.55 17l-.184-1.035h-.055c-.35.44-.71.747-1.08.92-.37.167-.85.25-1.44.25-.564 0-.955-.208-1.377-.625-.42-.418-.627-1.012-.627-1.784 0-.808.283-1.403.846-1.784.568-.386 1.193-.607 2.208-.64l1.322-.04v-.335c0-.772-.396-1.158-1.187-1.158-.61 0-1.325.18-2.147.55l-.688-1.4c.877-.46 1.85-.69 2.916-.69 1.024 0 1.59.22 2.134.662.545.445.818 1.12.818 2.03V17h-1.45m-.394-3.527l-.802.027c-.604.018-1.054.127-1.35.327-.294.2-.442.504-.442.912 0 .58.336.87 1.008.87.48 0 .865-.137 1.152-.414.29-.277.436-.645.436-1.103v-.627"/>
     </g>
index c5f35b0..ff6e102 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#36c">
-    <g id="regular-expression">
+    <g id="case-sensitive">
         <path id="upper-case" d="M7.53 7L4 17h2.063l.72-2.406h3.624l.72 2.406h2.062L9.65 7h-2.12zm1.064 1.53L9.938 13H7.25l1.344-4.47z"/>
         <path id="lower-case" d="M18.55 17l-.184-1.035h-.055c-.35.44-.71.747-1.08.92-.37.167-.85.25-1.44.25-.564 0-.955-.208-1.377-.625-.42-.418-.627-1.012-.627-1.784 0-.808.283-1.403.846-1.784.568-.386 1.193-.607 2.208-.64l1.322-.04v-.335c0-.772-.396-1.158-1.187-1.158-.61 0-1.325.18-2.147.55l-.688-1.4c.877-.46 1.85-.69 2.916-.69 1.024 0 1.59.22 2.134.662.545.445.818 1.12.818 2.03V17h-1.45m-.394-3.527l-.802.027c-.604.018-1.054.127-1.35.327-.294.2-.442.504-.442.912 0 .58.336.87 1.008.87.48 0 .865-.137 1.152-.414.29-.277.436-.645.436-1.103v-.627"/>
     </g>
index 46cd9b0..749e38f 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <g id="regular-expression">
+    <g id="case-sensitive">
         <path id="upper-case" d="M7.53 7L4 17h2.063l.72-2.406h3.624l.72 2.406h2.062L9.65 7h-2.12zm1.064 1.53L9.938 13H7.25l1.344-4.47z"/>
         <path id="lower-case" d="M18.55 17l-.184-1.035h-.055c-.35.44-.71.747-1.08.92-.37.167-.85.25-1.44.25-.564 0-.955-.208-1.377-.625-.42-.418-.627-1.012-.627-1.784 0-.808.283-1.403.846-1.784.568-.386 1.193-.607 2.208-.64l1.322-.04v-.335c0-.772-.396-1.158-1.187-1.158-.61 0-1.325.18-2.147.55l-.688-1.4c.877-.46 1.85-.69 2.916-.69 1.024 0 1.59.22 2.134.662.545.445.818 1.12.818 2.03V17h-1.45m-.394-3.527l-.802.027c-.604.018-1.054.127-1.35.327-.294.2-.442.504-.442.912 0 .58.336.87 1.008.87.48 0 .865-.137 1.152-.414.29-.277.436-.645.436-1.103v-.627"/>
     </g>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic-invert.png
new file mode 100644 (file)
index 0000000..7bb19e3
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic-invert.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic-invert.svg
new file mode 100644 (file)
index 0000000..b19dd0d
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#fff">
+    <g id="diacritic">
+      <path id="letter-a" d="M13.55 17l-.184-1.035h-.055c-.35.44-.71.747-1.08.92-.37.167-.85.25-1.44.25-.563 0-.954-.208-1.376-.625-.42-.418-.627-1.012-.627-1.784 0-.808.283-1.403.846-1.784.568-.386 1.193-.607 2.208-.64l1.323-.04v-.335c0-.772-.396-1.158-1.187-1.158-.61 0-1.325.18-2.147.55l-.69-1.4c.878-.46 1.85-.69 2.917-.69 1.024 0 1.59.22 2.134.66.546.446.82 1.12.82 2.03V17h-1.45m-.395-3.527l-.802.027c-.604.018-1.054.127-1.35.327-.294.2-.442.504-.442.912 0 .58.337.87 1.01.87.48 0 .864-.138 1.15-.415.29-.277.437-.645.437-1.103v-.627"/>
+      <path id="tilde" d="M12.012 7.527l-.466-.306a.832.832 0 0 1-.085-.048c-.264-.17-.467-.256-.608-.256a.518.518 0 0 0-.466.256c-.107.17-.16.418-.16.743v.066H9.047c0-.748.144-1.326.432-1.733.294-.407.703-.61 1.228-.61.203 0 .406.037.61.114.208.073.43.19.66.357l.517.355c.124.082.237.146.338.19a.77.77 0 0 0 .288.066c.204 0 .362-.088.475-.265.113-.176.17-.42.17-.735v-.066h1.177c0 .75-.147 1.327-.44 1.735-.29.407-.695.61-1.22.61-.203 0-.4-.032-.593-.098a3.107 3.107 0 0 1-.678-.373z"/>
+    </g>
+</g></svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic-progressive.png
new file mode 100644 (file)
index 0000000..eb76fd0
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic-progressive.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic-progressive.svg
new file mode 100644 (file)
index 0000000..fed1164
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#36c">
+    <g id="diacritic">
+      <path id="letter-a" d="M13.55 17l-.184-1.035h-.055c-.35.44-.71.747-1.08.92-.37.167-.85.25-1.44.25-.563 0-.954-.208-1.376-.625-.42-.418-.627-1.012-.627-1.784 0-.808.283-1.403.846-1.784.568-.386 1.193-.607 2.208-.64l1.323-.04v-.335c0-.772-.396-1.158-1.187-1.158-.61 0-1.325.18-2.147.55l-.69-1.4c.878-.46 1.85-.69 2.917-.69 1.024 0 1.59.22 2.134.66.546.446.82 1.12.82 2.03V17h-1.45m-.395-3.527l-.802.027c-.604.018-1.054.127-1.35.327-.294.2-.442.504-.442.912 0 .58.337.87 1.01.87.48 0 .864-.138 1.15-.415.29-.277.437-.645.437-1.103v-.627"/>
+      <path id="tilde" d="M12.012 7.527l-.466-.306a.832.832 0 0 1-.085-.048c-.264-.17-.467-.256-.608-.256a.518.518 0 0 0-.466.256c-.107.17-.16.418-.16.743v.066H9.047c0-.748.144-1.326.432-1.733.294-.407.703-.61 1.228-.61.203 0 .406.037.61.114.208.073.43.19.66.357l.517.355c.124.082.237.146.338.19a.77.77 0 0 0 .288.066c.204 0 .362-.088.475-.265.113-.176.17-.42.17-.735v-.066h1.177c0 .75-.147 1.327-.44 1.735-.29.407-.695.61-1.22.61-.203 0-.4-.032-.593-.098a3.107 3.107 0 0 1-.678-.373z"/>
+    </g>
+</g></svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic.png
new file mode 100644 (file)
index 0000000..2359b19
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/diacritic.svg
new file mode 100644 (file)
index 0000000..4565101
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <g id="diacritic">
+      <path id="letter-a" d="M13.55 17l-.184-1.035h-.055c-.35.44-.71.747-1.08.92-.37.167-.85.25-1.44.25-.563 0-.954-.208-1.376-.625-.42-.418-.627-1.012-.627-1.784 0-.808.283-1.403.846-1.784.568-.386 1.193-.607 2.208-.64l1.323-.04v-.335c0-.772-.396-1.158-1.187-1.158-.61 0-1.325.18-2.147.55l-.69-1.4c.878-.46 1.85-.69 2.917-.69 1.024 0 1.59.22 2.134.66.546.446.82 1.12.82 2.03V17h-1.45m-.395-3.527l-.802.027c-.604.018-1.054.127-1.35.327-.294.2-.442.504-.442.912 0 .58.337.87 1.01.87.48 0 .864-.138 1.15-.415.29-.277.437-.645.437-1.103v-.627"/>
+      <path id="tilde" d="M12.012 7.527l-.466-.306a.832.832 0 0 1-.085-.048c-.264-.17-.467-.256-.608-.256a.518.518 0 0 0-.466.256c-.107.17-.16.418-.16.743v.066H9.047c0-.748.144-1.326.432-1.733.294-.407.703-.61 1.228-.61.203 0 .406.037.61.114.208.073.43.19.66.357l.517.355c.124.082.237.146.338.19a.77.77 0 0 0 .288.066c.204 0 .362-.088.475-.265.113-.176.17-.42.17-.735v-.066h1.177c0 .75-.147 1.327-.44 1.735-.29.407-.695.61-1.22.61-.203 0-.4-.032-.593-.098a3.107 3.107 0 0 1-.678-.373z"/>
+    </g>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr-invert.png
new file mode 100644 (file)
index 0000000..f49ebeb
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr-invert.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr-invert.svg
new file mode 100644 (file)
index 0000000..8ed4be9
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#fff">
+    <path d="M8.202 15.834l.568 2.101c.198.765 1.06 1.22 1.8 1.016.698-.193 1.125-.983.926-1.747l-.38-1.37H20L17.229 5 4.155 12.652c-.427.762.088 2.748.823 3.182h3.224z"/>
+</g></svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr-progressive.png
new file mode 100644 (file)
index 0000000..28405a8
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr-progressive.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr-progressive.svg
new file mode 100644 (file)
index 0000000..49425d0
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#36c">
+    <path d="M8.202 15.834l.568 2.101c.198.765 1.06 1.22 1.8 1.016.698-.193 1.125-.983.926-1.747l-.38-1.37H20L17.229 5 4.155 12.652c-.427.762.088 2.748.823 3.182h3.224z"/>
+</g></svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr.png
new file mode 100644 (file)
index 0000000..ac5787b
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-ltr.svg
new file mode 100644 (file)
index 0000000..0fdeed9
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M8.202 15.834l.568 2.101c.198.765 1.06 1.22 1.8 1.016.698-.193 1.125-.983.926-1.747l-.38-1.37H20L17.229 5 4.155 12.652c-.427.762.088 2.748.823 3.182h3.224z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl-invert.png
new file mode 100644 (file)
index 0000000..efba220
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl-invert.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl-invert.svg
new file mode 100644 (file)
index 0000000..f4e7932
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#fff">
+    <path d="M15.798 15.834l-.568 2.101c-.198.765-1.06 1.22-1.8 1.016-.698-.193-1.125-.983-.926-1.747l.38-1.37H4L6.771 5l13.074 7.652c.427.762-.088 2.748-.823 3.182h-3.224z"/>
+</g></svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl-progressive.png
new file mode 100644 (file)
index 0000000..27bcc2d
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl-progressive.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl-progressive.svg
new file mode 100644 (file)
index 0000000..413ea34
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#36c">
+    <path d="M15.798 15.834l-.568 2.101c-.198.765-1.06 1.22-1.8 1.016-.698-.193-1.125-.983-.926-1.747l.38-1.37H4L6.771 5l13.074 7.652c.427.762-.088 2.748-.823 3.182h-3.224z"/>
+</g></svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl.png
new file mode 100644 (file)
index 0000000..fdbe5e1
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/feedback-rtl.svg
new file mode 100644 (file)
index 0000000..022d86d
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M15.798 15.834l-.568 2.101c-.198.765-1.06 1.22-1.8 1.016-.698-.193-1.125-.983-.926-1.747l.38-1.37H4L6.771 5l13.074 7.652c.427.762-.088 2.748-.823 3.182h-3.224z"/>
+</svg>
diff --git a/resources/src/dom-level2-skip.js b/resources/src/dom-level2-skip.js
deleted file mode 100644 (file)
index 484c295..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-/*!
- * Skip function for dom-level2-shim module.
- *
- * Tests for window.Node because that's the only thing that this shim is adding.
- */
-return !!window.Node;
index f4ef540..11f472e 100644 (file)
@@ -1,4 +1,4 @@
-@import "mediawiki.mixins";
+@import 'mediawiki.mixins';
 
 /* Table Sorting */
 
index 011f9c5..938962f 100644 (file)
@@ -2,27 +2,31 @@
        var collapsibleLists, handleOne;
 
        // Collapsible lists of categories and templates
+       // If changing or removing a storeKey, ensure there is a strategy for old keys.
+       // E.g. detect existence via requestIdleCallback and remove. (T121646)
        collapsibleLists = [
                {
                        listSel: '.templatesUsed ul',
                        togglerSel: '.mw-templatesUsedExplanation',
-                       cookieName: 'templates-used-list'
+                       storeKey: 'mwedit-state-templatesUsed'
                },
                {
                        listSel: '.hiddencats ul',
                        togglerSel: '.mw-hiddenCategoriesExplanation',
-                       cookieName: 'hidden-categories-list'
+                       storeKey: 'mwedit-state-hiddenCategories'
                },
                {
                        listSel: '.preview-limit-report-wrapper',
                        togglerSel: '.mw-limitReportExplanation',
-                       cookieName: 'preview-limit-report'
+                       storeKey: 'mwedit-state-limitReport'
                }
        ];
 
-       handleOne = function ( $list, $toggler, cookieName ) {
-               // Collapsed by default
-               var isCollapsed = mw.cookie.get( cookieName ) !== 'expanded';
+       handleOne = function ( $list, $toggler, storeKey ) {
+               var collapsedVal = '0',
+                       expandedVal = '1',
+                       // Default to collapsed if not set
+                       isCollapsed = mw.storage.get( storeKey ) !== expandedVal;
 
                // Style the toggler with an arrow icon and add a tabIndex and a role for accessibility
                $toggler.addClass( 'mw-editfooter-toggler' ).prop( 'tabIndex', 0 ).attr( 'role', 'button' );
 
                $list.on( 'beforeExpand.mw-collapsible', function () {
                        $toggler.removeClass( 'mw-icon-arrow-collapsed' ).addClass( 'mw-icon-arrow-expanded' );
-                       mw.cookie.set( cookieName, 'expanded' );
+                       mw.storage.set( storeKey, expandedVal );
                } );
 
                $list.on( 'beforeCollapse.mw-collapsible', function () {
                        $toggler.removeClass( 'mw-icon-arrow-expanded' ).addClass( 'mw-icon-arrow-collapsed' );
-                       mw.cookie.set( cookieName, 'collapsed' );
+                       mw.storage.set( storeKey, collapsedVal );
                } );
        };
 
@@ -55,7 +59,7 @@
                        handleOne(
                                $editForm.find( collapsibleLists[ i ].listSel ),
                                $editForm.find( collapsibleLists[ i ].togglerSel ),
-                               collapsibleLists[ i ].cookieName
+                               collapsibleLists[ i ].storeKey
                        );
                }
        } );
index b63f87d..d228236 100644 (file)
@@ -6,6 +6,10 @@
 #wpTextbox1 {
        margin: 0;
        display: block;
+       /* Ensure the textarea is not higher than browser's viewport on small screens */
+       max-height: 100vh;
+       /* But don't let it collapse into nothingness on really tiny screens */
+       min-height: 5em;
 }
 
 /* Adjustments to edit form elements */
index fd5dbc9..f3ea163 100644 (file)
@@ -1,6 +1,6 @@
 /* Styles for the JavaScript enhancements of the history page */
 
-#pagehistory li.before input[name="oldid"],
-#pagehistory li.after input[name="diff"] {
+#pagehistory li.before input[name='oldid'],
+#pagehistory li.after input[name='diff'] {
        visibility: hidden;
 }
index 6e0010c..a5ca65e 100644 (file)
@@ -32,7 +32,7 @@
 }
 
 .skin-monobook .postedit {
-       top: 6em !important;
+       top: 6em !important; /* stylelint-disable-line declaration-no-important */
 }
 
 .postedit-faded {
index b791db8..dccbacc 100644 (file)
        list-style: none none;
        display: inline;
        /* shared.css has some very weird directionality-specific rules for 'ul' we need to override,
-          search for "Correct directionality when page dir is different from site/user dir" */
+        * search for "Correct directionality when page dir is different from site/user dir" */
+       /* stylelint-disable declaration-no-important */
        margin: 0 !important;
        padding: 0 !important;
+       /* stylelint-enable declaration-no-important */
 }
 
 /* @noflip */
index 7c2f92b..b047f62 100644 (file)
@@ -99,26 +99,26 @@ img {
  * MediaWiki-specific elements
  */
 #globalWrapper {
-       width: 100% !important;
-       min-width: 0 !important;
+       width: 100% !important; /* stylelint-disable-line declaration-no-important */
+       min-width: 0 !important; /* stylelint-disable-line declaration-no-important */
 }
 
 .mw-body {
        background: #fff;
        color: #000;
-       border: 0 !important;
-       padding: 0 !important;
-       margin: 0 !important;
+       border: 0 !important; /* stylelint-disable-line declaration-no-important */
+       padding: 0 !important; /* stylelint-disable-line declaration-no-important */
+       margin: 0 !important; /* stylelint-disable-line declaration-no-important */
        direction: ltr;
 }
 
 #column-content {
-       margin: 0 !important;
+       margin: 0 !important; /* stylelint-disable-line declaration-no-important */
 }
 
 #column-content .mw-body {
        padding: 1em;
-       margin: 0 !important;
+       margin: 0 !important; /* stylelint-disable-line declaration-no-important */
 }
 
 #toc {
@@ -164,14 +164,14 @@ img {
  * Links
  */
 a {
-       background: none !important;
-       padding: 0 !important;
+       background: none !important; /* stylelint-disable-line declaration-no-important */
+       padding: 0 !important; /* stylelint-disable-line declaration-no-important */
 }
 
 /* Expand URLs for printing */
 .mw-body a.external.text:after,
 .mw-body a.external.autonumber:after {
-       content: " (" attr( href ) ")";
+       content: ' (' attr( href ) ')';
        word-break: break-all;
        word-wrap: break-word;
 }
@@ -179,7 +179,7 @@ a {
 /* Expand protocol-relative URLs for printing */
 .mw-body a.external.text[href^='//']:after,
 .mw-body a.external.autonumber[href^='//']:after {
-       content: " (https:" attr( href ) ")";
+       content: ' (https:' attr( href ) ')';
 }
 
 a,
@@ -187,11 +187,11 @@ a.external,
 a.new,
 a.stub {
        /* IE 6 & 7 don't understand `inherit` */
-       color: #000 !important;
-       text-decoration: none !important;
+       color: #000 !important; /* stylelint-disable-line declaration-no-important */
+       text-decoration: none !important; /* stylelint-disable-line declaration-no-important */
        /* Modern browser will apply this, IE 6 & 7 ignore the unknown */
-       color: inherit !important; /* stylelint-disable-line declaration-block-no-duplicate-properties */
-       text-decoration: inherit !important; /* stylelint-disable-line declaration-block-no-duplicate-properties */
+       color: inherit !important; /* stylelint-disable-line declaration-block-no-duplicate-properties, declaration-no-important */
+       text-decoration: inherit !important; /* stylelint-disable-line declaration-block-no-duplicate-properties, declaration-no-important */
 }
 
 /**
index 8f4ac7d..ff0c0e3 100644 (file)
@@ -56,22 +56,22 @@ wbr {
 
 /* Input types that should follow user direction, like buttons */
 /* TODO: What about buttons in wikipage content ? */
-input[type="submit"],
-input[type="button"],
-input[type="reset"],
-input[type="file"] {
+input[type='submit'],
+input[type='button'],
+input[type='reset'],
+input[type='file'] {
        direction: ltr;
 }
 
 /* Override default values */
-textarea[dir="ltr"],
-input[dir="ltr"] {
+textarea[dir='ltr'],
+input[dir='ltr'] {
        /* @noflip */
        direction: ltr;
 }
 
-textarea[dir="rtl"],
-input[dir="rtl"] {
+textarea[dir='rtl'],
+input[dir='rtl'] {
        /* @noflip */
        direction: rtl;
 }
@@ -325,8 +325,8 @@ a.new {
 /* Plainlinks - this can be used to switch
  * off special external link styling */
 .plainlinks a.external {
-       background: none !important;
-       padding: 0 !important;
+       background: none !important; /* stylelint-disable-line declaration-no-important */
+       padding: 0 !important; /* stylelint-disable-line declaration-no-important */
 }
 
 /* External URLs should always be treated as LTR (T6330) */
@@ -540,7 +540,7 @@ table.wikitable > caption {
 }
 
 .mw-small-spinner {
-       padding: 10px !important;
+       padding: 10px !important; /* stylelint-disable-line declaration-no-important */
        margin-right: 0.6em;
        background-image: url( images/spinner.gif );
        background-position: center center;
@@ -570,7 +570,7 @@ h1:lang( pi ),
 h1:lang( sa ),
 h1:lang( ta ),
 h1:lang( te ) {
-       line-height: 1.6em !important;
+       line-height: 1.6em !important; /* stylelint-disable-line declaration-no-important */
 }
 
 /* stylelint-disable selector-list-comma-newline-after */
index 4cca1a6..1e952b0 100644 (file)
@@ -1,7 +1,7 @@
 // Common Less mixin library for MediaWiki
 //
 // By default the folder containing this file is included in $wgResourceLoaderLESSImportPaths,
-// which makes this file importable by all less files via '@import "mediawiki.mixins";'.
+// 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.
 // The signatures of parametrized mixins should be kept as stable as possible.
@@ -88,9 +88,9 @@
 }
 
 .flex-display( @display: flex ) {
-       display: ~"-webkit-@{display}"; // iOS 6-, Safari 3.1-6
-       display: ~"-moz-@{display}"; // Firefox 21-
-       display: ~"-ms-@{display}box"; // IE 10
+       display: ~'-webkit-@{display}'; // iOS 6-, Safari 3.1-6
+       display: ~'-moz-@{display}'; // Firefox 21-
+       display: ~'-ms-@{display}box'; // IE 10
        display: @display;
 }
 
 // Screen Reader Helper Mixin
 .mixin-screen-reader-text() {
        display: block;
-       position: absolute !important;
+       position: absolute !important; /* stylelint-disable-line declaration-no-important */
        clip: rect( 1px, 1px, 1px, 1px );
        width: 1px;
        height: 1px;
index a404286..64d6b3d 100644 (file)
@@ -1,7 +1,7 @@
 // This is a separate file because importing the mixin causes
 // the keyframes blocks to be included in the output, regardless
 // of whether .rotation is used.
-@import "mediawiki.mixins.animation";
+@import 'mediawiki.mixins.animation';
 
 .rotate-frames() {
        from {
index 1bfa3a3..a0ff767 100644 (file)
@@ -17,8 +17,8 @@
        line-height: normal;
        font-weight: normal;
 
-       & > input[type="checkbox"],
-       & > input[type="radio"] {
+       & > input[type='checkbox'],
+       & > input[type='radio'] {
                width: auto;
                height: auto;
                margin: 0 0.1em 0 0;
index edb6744..d6ce734 100644 (file)
         * Update the model with an updated list of changes
         *
         * @param {jQuery|string} changesListContent
+        * @param {jQuery} $fieldset
         */
-       mw.rcfilters.dm.ChangesListViewModel.prototype.update = function ( changesListContent ) {
+       mw.rcfilters.dm.ChangesListViewModel.prototype.update = function ( changesListContent, $fieldset ) {
                this.valid = true;
-               this.emit( 'update', changesListContent );
+               this.emit( 'update', changesListContent, $fieldset );
        };
 
 }( mediaWiki ) );
index 675f4b5..18f1299 100644 (file)
 
        /* Methods */
 
+       /**
+        * Return the representation of the state of this item.
+        *
+        * @return {Object} State of the object
+        */
+       mw.rcfilters.dm.FilterItem.prototype.getState = function () {
+               return {
+                       selected: this.isSelected(),
+                       included: this.isIncluded(),
+                       conflicted: this.isConflicted(),
+                       fullyCovered: this.isFullyCovered()
+               };
+       };
+
        /**
         * Get the name of this filter
         *
index d58eb2e..2afe286 100644 (file)
                                        // For example, see two groups with conflicts:
                                        // userExpLevel: [
                                        //   {
-                                       //      name: 'experienced',
-                                       //      conflicts: [ 'unregistered' ]
+                                       //     name: 'experienced',
+                                       //     conflicts: [ 'unregistered' ]
                                        //   }
                                        // ],
                                        // registration: [
                                        //   {
-                                       //      name: 'registered',
+                                       //     name: 'registered',
                                        //   },
                                        //   {
-                                       //      name: 'unregistered',
+                                       //     name: 'unregistered',
                                        //   }
                                        // ]
                                        // If we select 'experienced', then 'unregistered' is in conflict (and vice versa),
diff --git a/resources/src/mediawiki.rcfilters/images/marker-ltr.svg b/resources/src/mediawiki.rcfilters/images/marker-ltr.svg
new file mode 100644 (file)
index 0000000..eb42923
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" height="24" width="24">
+    <path d="M5.066 18.236l.14-.244c.976-1.69 1.341-4.587.815-6.469l-.14-.507.2-.365L11.074 2l9.011 5.203-4.994 8.65-.204.354-.522.134c-1.893.485-4.22 2.252-5.195 3.94l-.14.244-.721-.416-1.041 1.89H3.914l1.893-3.336z" fill-rule="evenodd"/>
+</svg>
diff --git a/resources/src/mediawiki.rcfilters/images/marker-rtl.svg b/resources/src/mediawiki.rcfilters/images/marker-rtl.svg
new file mode 100644 (file)
index 0000000..9b1940e
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" height="24" width="24">
+    <path d="M18.934 18.236l-.14-.244c-.976-1.69-1.341-4.587-.815-6.469l.14-.507-.2-.365L12.926 2 3.914 7.203l4.994 8.65.204.354.522.134c1.893.485 4.22 2.252 5.195 3.94l.14.244.721-.416 1.041 1.89h3.355l-1.893-3.336z" fill-rule="evenodd"/>
+</svg>
diff --git a/resources/src/mediawiki.rcfilters/images/pending.gif b/resources/src/mediawiki.rcfilters/images/pending.gif
new file mode 100644 (file)
index 0000000..1194eed
Binary files /dev/null and b/resources/src/mediawiki.rcfilters/images/pending.gif differ
index 1df31a2..1c05909 100644 (file)
@@ -62,7 +62,6 @@
                // Check all filter interactions
                this.filtersModel.reassessFilterInteractions();
 
-               this.updateURL();
                this.updateChangesList();
        };
 
                // Check all filter interactions
                this.filtersModel.reassessFilterInteractions();
 
-               this.updateURL();
                this.updateChangesList();
        };
 
        /**
-        * Update the state of a filter
+        * Update the selected state of a filter
         *
         * @param {string} filterName Filter name
-        * @param {boolean} isSelected Filter selected state
+        * @param {boolean} [isSelected] Filter selected state
         */
-       mw.rcfilters.Controller.prototype.updateFilter = function ( filterName, isSelected ) {
+       mw.rcfilters.Controller.prototype.toggleFilterSelect = function ( filterName, isSelected ) {
                var obj = {},
                        filterItem = this.filtersModel.getItemByName( filterName );
 
+               isSelected = isSelected === undefined ? !filterItem.isSelected() : isSelected;
+
                if ( filterItem.isSelected() !== isSelected ) {
                        obj[ filterName ] = isSelected;
                        this.filtersModel.updateFilters( obj );
 
-                       this.updateURL();
                        this.updateChangesList();
 
                        // Check filter interactions
 
        /**
         * Update the URL of the page to reflect current filters
+        *
+        * This should not be called directly from outside the controller.
+        * If an action requires changing the URL, it should either use the
+        * highlighting actions below, or call #updateChangesList which does
+        * the uri corrections already.
+        *
+        * @private
+        * @param {Object} [params] Extra parameters to add to the API call
         */
-       mw.rcfilters.Controller.prototype.updateURL = function () {
-               var uri = this.getUpdatedUri();
+       mw.rcfilters.Controller.prototype.updateURL = function ( params ) {
+               var uri;
+
+               params = params || {};
+
+               uri = this.getUpdatedUri();
+               uri.extend( params );
+
                window.history.pushState( { tag: 'rcfilters' }, document.title, uri.toString() );
        };
 
         * Fetch the list of changes from the server for the current filters
         *
         * @return {jQuery.Promise} Promise object that will resolve with the changes list
+        *  or with a string denoting no results.
         */
        mw.rcfilters.Controller.prototype.fetchChangesList = function () {
                var uri = this.getUpdatedUri(),
                        latestRequest = function () {
                                return requestId === this.requestCounter;
                        }.bind( this );
-               uri.extend( this.filtersModel.getParametersFromFilters() );
+
                return $.ajax( uri.toString(), { contentType: 'html' } )
-                       .then( function ( html ) {
-                               return latestRequest() ?
-                                       $( $.parseHTML( html ) ).find( '.mw-changeslist' ).first().contents() :
-                                       null;
-                       } ).then( null, function () {
-                               return latestRequest() ? 'NO_RESULTS' : null;
-                       } );
+                       .then(
+                               // Success
+                               function ( html ) {
+                                       var $parsed;
+                                       if ( !latestRequest() ) {
+                                               return $.Deferred().reject();
+                                       }
+
+                                       $parsed = $( $.parseHTML( html ) );
+
+                                       return {
+                                               // Changes list
+                                               changes: $parsed.find( '.mw-changeslist' ).first().contents(),
+                                               // Fieldset
+                                               fieldset: $parsed.find( 'fieldset.rcoptions' ).first()
+                                       };
+                               },
+                               // Failure
+                               function ( responseObj ) {
+                                       var $parsed;
+
+                                       if ( !latestRequest() ) {
+                                               return $.Deferred().reject();
+                                       }
+
+                                       $parsed = $( $.parseHTML( responseObj.responseText ) );
+
+                                       // Force a resolve state to this promise
+                                       return $.Deferred().resolve( {
+                                               changes: 'NO_RESULTS',
+                                               fieldset: $parsed.find( 'fieldset.rcoptions' ).first()
+                                       } ).promise();
+                               }
+                       );
        };
 
        /**
         * Update the list of changes and notify the model
+        *
+        * @param {Object} [params] Extra parameters to add to the API call
         */
-       mw.rcfilters.Controller.prototype.updateChangesList = function () {
+       mw.rcfilters.Controller.prototype.updateChangesList = function ( params ) {
+               this.updateURL( params );
                this.changesListModel.invalidate();
                this.fetchChangesList()
-                       .always( function ( changesListContent ) {
-                               if ( changesListContent ) {
-                                       this.changesListModel.update( changesListContent );
-                               }
-                       }.bind( this ) );
+                       .then(
+                               // Success
+                               function ( pieces ) {
+                                       var $changesListContent = pieces.changes,
+                                               $fieldset = pieces.fieldset;
+                                       this.changesListModel.update( $changesListContent, $fieldset );
+                               }.bind( this )
+                               // Do nothing for failure
+                       );
        };
 
        /**
index 33e9f57..255d93b 100644 (file)
                                filtersWidget = new mw.rcfilters.ui.FilterWrapperWidget(
                                        controller, filtersModel, { $overlay: $overlay } );
 
+                       // TODO: The changesListWrapperWidget should be able to initialize
+                       // after the model is ready.
                        // eslint-disable-next-line no-new
                        new mw.rcfilters.ui.ChangesListWrapperWidget(
                                filtersModel, changesListModel, $( '.mw-changeslist, .mw-changeslist-empty' ) );
 
-                       // eslint-disable-next-line no-new
-                       new mw.rcfilters.ui.FormWrapperWidget(
-                               changesListModel, $( '.rcoptions form' ) );
-
                        controller.initialize( {
                                registration: {
                                        title: mw.msg( 'rcfilters-filtergroup-registration' ),
                                }
                        } );
 
-                       $( '.rcoptions' ).before( filtersWidget.$element );
+                       // eslint-disable-next-line no-new
+                       new mw.rcfilters.ui.FormWrapperWidget(
+                               filtersModel, changesListModel, controller, $( 'fieldset.rcoptions' ) );
+
+                       $( '.rcfilters-container' ).append( filtersWidget.$element );
                        $( 'body' ).append( $overlay );
 
-                       // HACK: Remove old-style filter links for filters handled by the widget
-                       // Ideally the widget would handle all filters and we'd just remove .rcshowhide entirely
-                       $( '.rcshowhide' ).children().each( function () {
-                               // HACK: Interpret the class name to get the filter name
-                               // This should really be set as a data attribute
-                               var i,
-                                       name = null,
-                                       // Some of the older browsers we support don't have .classList,
-                                       // so we have to interpret the class attribute manually.
-                                       classes = this.getAttribute( 'class' ).split( ' ' );
-                               for ( i = 0; i < classes.length; i++ ) {
-                                       if ( classes[ i ].substr( 0, 'rcshow'.length ) === 'rcshow' ) {
-                                               name = classes[ i ].substr( 'rcshow'.length );
-                                               break;
-                                       }
-                               }
-                               if ( name === null ) {
-                                       return;
-                               }
-                               if ( name === 'hidemine' ) {
-                                       // HACK: the span for hidemyself is called hidemine
-                                       name = 'hidemyself';
-                               }
-                               // This span corresponds to a filter that's in our model, so remove it
-                               if ( filtersModel.getItemByName( name ) ) {
-                                       // HACK: Remove the text node after the span.
-                                       // If there isn't one, we're at the end, so remove the text node before the span.
-                                       // This would be unnecessary if we added separators with CSS.
-                                       if ( this.nextSibling && this.nextSibling.nodeType === Node.TEXT_NODE ) {
-                                               this.parentNode.removeChild( this.nextSibling );
-                                       } else if ( this.previousSibling && this.previousSibling.nodeType === Node.TEXT_NODE ) {
-                                               this.parentNode.removeChild( this.previousSibling );
-                                       }
-                                       // Remove the span itself
-                                       this.parentNode.removeChild( this );
-                               }
-                       } );
+                       // Set as ready
+                       $( '.rcfilters-head' ).addClass( 'mw-rcfilters-ui-ready' );
 
                        window.addEventListener( 'popstate', function () {
-                               controller.updateFromURL();
                                controller.updateChangesList();
                        } );
+
+                       $( 'a.mw-helplink' ).attr(
+                               'href',
+                               'https://www.mediawiki.org/wiki/Special:MyLanguage/Help:New_filters_for_edit_review'
+                       );
                }
        };
 
index 8423363..d47346c 100644 (file)
@@ -1,9 +1,33 @@
 // Corrections for the standard special page
-.rcoptions {
-       border: 0;
-       border-bottom: 1px solid #a2a9b1;
+.client-js{
+       .rcoptions {
+               border: 0;
+               border-bottom: 1px solid #a2a9b1;
 
-       legend {
-               display: none;
+               legend {
+                       display: none;
+               }
        }
+
+       .rcfilters-head {
+               min-height: 270px;
+               &:not( .mw-rcfilters-ui-ready ) {
+                       /* @embed */
+                       background-image: url( ../images/pending.gif );
+                       margin: 0;
+
+                       * {
+                               visibility: hidden;
+                       }
+               }
+       }
+
+       .rcfilters-container {
+               min-height: 100px;
+               margin: 0;
+       }
+}
+
+.mw-rcfilters-staticfilters-selected {
+       font-weight: bold;
 }
index 5c31b5d..2ce2c7f 100644 (file)
@@ -1,5 +1,5 @@
-@import "mediawiki.mixins";
-@import "mw.rcfilters.variables";
+@import 'mediawiki.mixins';
+@import 'mw.rcfilters.variables';
 
 // This is a general mixin for a color circle
 .mw-rcfilters-mixin-circle( @color: white, @diameter: 2em, @padding: 0.5em, @border: false ) {
@@ -23,7 +23,7 @@
 // a color class on its parent element
 .result-circle( @colorName: 'none' ) {
        &-@{colorName} {
-               .mw-rcfilters-mixin-circle( ~"@{highlight-@{colorName}}", @result-circle-diameter, 0 );
+               .mw-rcfilters-mixin-circle( ~'@{highlight-@{colorName}}', @result-circle-diameter, 0 );
                display: none;
 
                .mw-rcfilters-highlight-color-@{colorName} & {
 
 // This mixin produces color mixes for two, three and four colors
 .highlight-color-mix( @color1, @color2, @color3: false, @color4: false ) {
-       @highlight-color-class-var: ~".mw-rcfilters-highlight-color-@{color1}.mw-rcfilters-highlight-color-@{color2}";
+       @highlight-color-class-var: ~'.mw-rcfilters-highlight-color-@{color1}.mw-rcfilters-highlight-color-@{color2}';
 
        // The nature of these variables and them being inside
        // a 'tint' and 'average' LESS functions is such where
        // the parsing is failing if it is done inside those functions.
        // Instead, we first construct their LESS variable names,
        // and then we call them inside those functions by calling @@var
-       @c1var: ~"highlight-@{color1}";
-       @c2var: ~"highlight-@{color2}";
+       @c1var: ~'highlight-@{color1}';
+       @c2var: ~'highlight-@{color2}';
 
        // Two colors
        @{highlight-color-class-var} when ( @color3 = false ) and ( @color4 = false ) and not ( @color1 = false ), ( @color2 = false ) {
        }
        // Three colors
        @{highlight-color-class-var}.mw-rcfilters-highlight-color-@{color3} when ( @color4 = false ) and not ( @color3 = false ) {
-               @c3var: ~"highlight-@{color3}";
+               @c3var: ~'highlight-@{color3}';
                background-color: tint( mix( @@c1var, average( @@c2var, @@c3var ), 33% ), 30% );
        }
 
        // Four colors
        @{highlight-color-class-var}.mw-rcfilters-highlight-color-@{color3}.mw-rcfilters-highlight-color-@{color4} when not ( @color4 = false ) {
-               @c3var: ~"highlight-@{color3}";
-               @c4var: ~"highlight-@{color4}";
+               @c3var: ~'highlight-@{color3}';
+               @c4var: ~'highlight-@{color4}';
                background-color: tint( mix( @@c1var, mix( @@c2var, average( @@c3var, @@c4var ), 25% ), 25% ), 25% );
        }
 }
index 2521899..b16e84c 100644 (file)
@@ -1,6 +1,42 @@
-@import "mw.rcfilters.mixins";
+@import 'mw.rcfilters.mixins';
 
 .mw-rcfilters-ui-capsuleItemWidget {
+       background-color: #fff;
+       border-color: #979797;
+       color: #222;
+
+       // Background and color of the capsule widget need a bit
+       // more specificity to override ooui internals
+       &-muted.oo-ui-capsuleItemWidget.oo-ui-widget-enabled {
+               // Muted state
+               background-color: #eaecf0;
+               border-color: #c8ccd1;
+
+               .oo-ui-labelElement-label {
+                       color: #72777d;
+               }
+               .oo-ui-buttonWidget {
+                       opacity: @muted-opacity;
+               }
+       }
+
+       &-conflicted.oo-ui-capsuleItemWidget.oo-ui-widget-enabled {
+               background-color: #fee7e6; // Red90 AAA
+               border-color: #b32424; // Red30 AAA
+
+               .oo-ui-labelElement-label {
+                       color: #b32424;
+               }
+               .oo-ui-buttonWidget {
+                       opacity: @muted-opacity;
+               }
+       }
+
+       &-selected.oo-ui-capsuleItemWidget.oo-ui-widget-enabled {
+               background-color: #eaf3ff;
+               border-color: #36c;
+       }
+
        &-popup-content {
                padding: 0.5em;
                color: #54595d;
                cursor: pointer;
        }
 
-       &-muted {
-               // Muted state
-               // We want everything muted except the circle
-               background-color: rgba( 255, 255, 255, @muted-opacity );
-
-               .oo-ui-labelElement-label,
-               .oo-ui-buttonWidget {
-                       opacity: @muted-opacity;
-               }
-       }
-
        &-highlight {
                display: none;
                padding-right: 0.5em;
 
                }
 
-               &[data-color="c1"] {
-                       .mw-rcfilters-mixin-circle( @highlight-c1, 0.7em, ~"0 0.5em 0 0" );
+               &[data-color='c1'] {
+                       .mw-rcfilters-mixin-circle( @highlight-c1, 10px, ~'0 0.5em 0 0' );
                }
-               &[data-color="c2"] {
-                       .mw-rcfilters-mixin-circle( @highlight-c2, 0.7em, ~"0 0.5em 0 0" );
+               &[data-color='c2'] {
+                       .mw-rcfilters-mixin-circle( @highlight-c2, 10px, ~'0 0.5em 0 0' );
                }
-               &[data-color="c3"] {
-                       .mw-rcfilters-mixin-circle( @highlight-c3, 0.7em, ~"0 0.5em 0 0" );
+               &[data-color='c3'] {
+                       .mw-rcfilters-mixin-circle( @highlight-c3, 10px, ~'0 0.5em 0 0' );
                }
-               &[data-color="c4"] {
-                       .mw-rcfilters-mixin-circle( @highlight-c4, 0.7em, ~"0 0.5em 0 0" );
+               &[data-color='c4'] {
+                       .mw-rcfilters-mixin-circle( @highlight-c4, 10px, ~'0 0.5em 0 0' );
                }
-               &[data-color="c5"] {
-                       .mw-rcfilters-mixin-circle( @highlight-c5, 0.7em, ~"0 0.5em 0 0" );
+               &[data-color='c5'] {
+                       .mw-rcfilters-mixin-circle( @highlight-c5, 10px, ~'0 0.5em 0 0' );
                }
        }
 }
index 5ad2a19..c18fe5e 100644 (file)
@@ -6,14 +6,18 @@
                        list-style: none;
                        // Each li's margin-left should be the width of the highlights
                        // element + the margin
-                       margin-left: ~"calc( ( @{result-circle-diameter} + @{result-circle-margin} ) * 5 + @{result-circle-general-margin} )";
+                       margin-left: ~'calc( ( @{result-circle-diameter} + @{result-circle-margin} ) * 5 + @{result-circle-general-margin} )';
+
+                       li {
+                               list-style: none;
+                       }
                }
        }
 
        // Correction for Enhanced RC
        // This is outside the scope of the 'highlights' wrapper
        table.mw-enhanced-rc {
-               margin-left: ~"calc( ( @{result-circle-diameter} + @{result-circle-margin} ) * 5 + @{result-circle-general-margin} )";
+               margin-left: ~'calc( ( @{result-circle-diameter} + @{result-circle-margin} ) * 5 + @{result-circle-general-margin} )';
 
                td:last-child {
                        width: 100%;
@@ -26,7 +30,7 @@
                text-align: right;
                // The width is 5 circles times their diameter + individual margin
                // and then plus the general margin
-               width: ~"calc( ( @{result-circle-diameter} + @{result-circle-margin} ) * 5 )";
+               width: ~'calc( ( @{result-circle-diameter} + @{result-circle-margin} ) * 5 )';
                // And we want to shift the entire block to the left of the li
                position: absolute;
                left: 0;
index 8921f7a..a0ef293 100644 (file)
@@ -25,9 +25,4 @@
                text-align: right;
                padding-left: 0.5em;
        }
-
-       .oo-ui-capsuleItemWidget {
-               color: #222;
-               background-color: #fff;
-       }
 }
index 4619b6b..0f30137 100644 (file)
@@ -1,8 +1,12 @@
-@import "mw.rcfilters.mixins";
+@import 'mw.rcfilters.mixins';
 
 .mw-rcfilters-ui-filterItemHighlightButton {
+       .oo-ui-iconElement-icon.oo-ui-icon-highlight {
+               /* @embed */
+               background-image: url( ../images/marker-ltr.svg );
+       }
 
-       &-circle {
+       .oo-ui-buttonWidget.oo-ui-popupButtonWidget .oo-ui-buttonElement-button > &-circle {
                display: inline-block;
                vertical-align: middle;
                background-image: none;
                        &-c1 {
                                // These values duplicate the sizing of the icon
                                // width/height 1.875em
-                               .mw-rcfilters-mixin-circle( @highlight-c1, 1.875em, 0 );
+                               .mw-rcfilters-mixin-circle( @highlight-c1, 1.875em, 0.2em 0 );
                        }
                        &-c2 {
-                               .mw-rcfilters-mixin-circle( @highlight-c2, 1.875em, 0 );
+                               .mw-rcfilters-mixin-circle( @highlight-c2, 1.875em, 0.2em 0 );
                        }
                        &-c3 {
-                               .mw-rcfilters-mixin-circle( @highlight-c3, 1.875em, 0 );
+                               .mw-rcfilters-mixin-circle( @highlight-c3, 1.875em, 0.2em 0 );
                        }
                        &-c4 {
-                               .mw-rcfilters-mixin-circle( @highlight-c4, 1.875em, 0 );
+                               .mw-rcfilters-mixin-circle( @highlight-c4, 1.875em, 0.2em 0 );
                        }
                        &-c5 {
-                               .mw-rcfilters-mixin-circle( @highlight-c5, 1.875em, 0 );
+                               .mw-rcfilters-mixin-circle( @highlight-c5, 1.875em, 0.2em 0 );
                        }
                }
        }
index 94da3ac..0e38942 100644 (file)
@@ -1,9 +1,17 @@
-@import "mediawiki.mixins";
+@import 'mediawiki.mixins';
 
 .mw-rcfilters-ui-filterItemWidget {
        padding: 0 0.5em;
        .box-sizing( border-box );
 
+       &:not( :last-child ) {
+               border-bottom: solid 1px #eaecf0; // Base 80 AAA
+       }
+
+       &:hover {
+               background-color: #fbfbfb;
+       }
+
        .mw-rcfilters-ui-table {
                padding-top: 0.5em;
        }
                }
        }
 
+       &-selected {
+               background-color: #eaf3ff; // Accent90 AAA
+       }
+
        &-label {
                &-title {
                        font-weight: bold;
-                       font-size: 1.2em;
+                       font-size: 1.15em;
                        color: #222;
                }
                &-desc {
@@ -30,9 +42,8 @@
        &-filterCheckbox {
                .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline {
                        // Override margin-top and -bottom rules from FieldLayout
-                       margin: 0 !important;
+                       margin: 0 !important; /* stylelint-disable-line declaration-no-important */
                }
-
        }
 
        &-highlightButton {
index bdc94b3..970d140 100644 (file)
@@ -6,8 +6,18 @@
        &-popup {
                // We have to override OOUI's definition, which is set
                // on the inline style of the popup
-               margin-top: 2.4em !important;
+               margin-top: 2.4em !important; /* stylelint-disable-line declaration-no-important */
                max-width: 650px;
+
+               .oo-ui-popupWidget-body {
+                       max-height: 70vh;
+               }
+
+               .oo-ui-popupWidget-footer {
+                       background-color: #f8f9fa;
+                       text-align: right;
+                       padding: 0.5em;
+               }
        }
 
        &-search {
index 7fd3a21..3334d84 100644 (file)
@@ -4,9 +4,22 @@
                padding: 0.75em;
                // TODO: Unify colors with official design palette
                color: #54595d;
+       }
+
+       &-header {
                border-bottom: 1px solid #c8ccd1;
                background: #f8f9fa;
                overflow: hidden;
+
+               &-highlight {
+                       width: 1em;
+                       vertical-align: middle;
+               }
+
+               &-title {
+                       width: 100%;
+                       vertical-align: middle;
+               }
        }
 
        &-noresults {
@@ -14,8 +27,4 @@
                // TODO: Unify colors with official design palette
                color: #666;
        }
-
-       &-hightlightButton {
-               float: right;
-       }
 }
index 14c07c1..88f1195 100644 (file)
@@ -1,4 +1,4 @@
-@import "mw.rcfilters.mixins";
+@import 'mw.rcfilters.mixins';
 
 .mw-rcfilters-ui-highlightColorPickerWidget {
        &-label {
@@ -16,6 +16,8 @@
 
                        &-none {
                                .mw-rcfilters-mixin-circle( @highlight-none, 2em, 0.5em, true );
+                               // Override border to dashed
+                               border: 1px dashed #565656;
 
                                &.oo-ui-buttonOptionWidget.oo-ui-buttonElement-active,
                                &.oo-ui-buttonOptionWidget.oo-ui-optionWidget-pressed,
index cf03932..05f2f66 100644 (file)
@@ -24,6 +24,8 @@
                this.model = model;
                this.$overlay = config.$overlay || this.$element;
                this.positioned = false;
+               this.popupTimeoutShow = null;
+               this.popupTimeoutHide = null;
 
                // Parent constructor
                mw.rcfilters.ui.CapsuleItemWidget.parent.call( this, $.extend( {
@@ -60,8 +62,8 @@
                        .prepend( this.$highlight )
                        .attr( 'aria-haspopup', 'true' )
                        .addClass( 'mw-rcfilters-ui-capsuleItemWidget' )
-                       .on( 'mouseover', this.onHover.bind( this, true ) )
-                       .on( 'mouseout', this.onHover.bind( this, false ) );
+                       .on( 'mouseenter', this.onMouseEnter.bind( this ) )
+                       .on( 'mouseleave', this.onMouseLeave.bind( this ) );
 
                this.setCurrentMuteState();
                this.setHighlightColor();
                e.stopPropagation();
        };
 
+       /**
+        * Emit a click event when the capsule is clicked so we can aggregate this
+        * in the parent (the capsule)
+        */
+       mw.rcfilters.ui.CapsuleItemWidget.prototype.onClick = function () {
+               this.emit( 'click' );
+       };
+
        /**
         * Override the event listening to the item close button click
         */
                }
 
                // Respond to user removing the filter
-               this.controller.updateFilter( this.model.getName(), false );
+               this.controller.toggleFilterSelect( this.model.getName(), false );
                this.controller.clearHighlightColor( this.model.getName() );
        };
 
                                'mw-rcfilters-ui-capsuleItemWidget-muted',
                                !this.model.isSelected() ||
                                this.model.isIncluded() ||
-                               this.model.isConflicted() ||
                                this.model.isFullyCovered()
+                       )
+                       .toggleClass(
+                               'mw-rcfilters-ui-capsuleItemWidget-conflicted',
+                               this.model.isConflicted()
                        );
        };
 
        /**
-        * Respond to hover event on the capsule item.
-        *
-        * @param {boolean} isHovering Mouse is hovering on the item
+        * Respond to mouse enter event
         */
-       mw.rcfilters.ui.CapsuleItemWidget.prototype.onHover = function ( isHovering ) {
+       mw.rcfilters.ui.CapsuleItemWidget.prototype.onMouseEnter = function () {
                if ( this.model.getDescription() ) {
-                       this.popup.toggle( isHovering );
-
-                       if ( isHovering && !this.positioned ) {
+                       if ( !this.positioned ) {
                                // Recalculate position to be center of the capsule item
                                this.popup.$element.css( 'margin-left', ( this.$element.width() / 2 ) );
                                this.positioned = true;
                        }
+
+                       // Set timeout for the popup to show
+                       this.popupTimeoutShow = setTimeout( function () {
+                               this.popup.toggle( true );
+                       }.bind( this ), 500 );
+
+                       // Cancel the hide timeout
+                       clearTimeout( this.popupTimeoutHide );
+                       this.popupTimeoutHide = null;
+               }
+       };
+
+       /**
+        * Respond to mouse leave event
+        */
+       mw.rcfilters.ui.CapsuleItemWidget.prototype.onMouseLeave = function () {
+               this.popupTimeoutHide = setTimeout( function () {
+                       this.popup.toggle( false );
+               }.bind( this ), 250 );
+
+               // Clear the show timeout
+               clearTimeout( this.popupTimeoutShow );
+               this.popupTimeoutShow = null;
+       };
+
+       /**
+        * Set selected state on this widget
+        *
+        * @param {boolean} [isSelected] Widget is selected
+        */
+       mw.rcfilters.ui.CapsuleItemWidget.prototype.toggleSelected = function ( isSelected ) {
+               isSelected = isSelected !== undefined ? isSelected : !this.selected;
+
+               if ( this.selected !== isSelected ) {
+                       this.selected = isSelected;
+
+                       this.$element.toggleClass( 'mw-rcfilters-ui-capsuleItemWidget-selected', this.selected );
                }
        };
 
index 2bd2f0e..a06b103 100644 (file)
@@ -11,8 +11,6 @@
         * @param {OO.ui.InputWidget} filterInput A filter input that focuses the capsule widget
         * @param {Object} config Configuration object
         * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
-        * @cfg {number} [topScrollOffset=10] When scrolling the entire widget to the top, leave this
-        *  much space (in pixels) above the widget.
         */
        mw.rcfilters.ui.FilterCapsuleMultiselectWidget = function MwRcfiltersUiFilterCapsuleMultiselectWidget( controller, model, filterInput, config ) {
                var title = new OO.ui.LabelWidget( {
@@ -32,8 +30,8 @@
                this.controller = controller;
                this.model = model;
                this.filterInput = filterInput;
-
-               this.topScrollOffset = config.topScrollOffset || 10;
+               this.isSelecting = false;
+               this.selected = null;
 
                this.resetButton = new OO.ui.ButtonWidget( {
                        icon: 'trash',
@@ -54,7 +52,7 @@
                        itemUpdate: 'onModelItemUpdate',
                        highlightChange: 'onModelHighlightChange'
                } );
-               this.popup.connect( this, { toggle: 'onPopupToggle' } );
+               this.aggregate( { click: 'capsuleItemClick' } );
 
                // Add the filterInput as trigger
                this.filterInput.$input
                }
        };
 
-       /**
-        * Respond to popup toggle event
-        *
-        * @param {boolean} isVisible Popup is visible
-        */
-       mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.onPopupToggle = function ( isVisible ) {
-               if ( isVisible ) {
-                       this.scrollToTop();
-               }
-       };
-
-       /**
-        * Scroll the capsule to the top of the screen
-        */
-       mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.scrollToTop = function () {
-               var container = OO.ui.Element.static.getClosestScrollableContainer( this.$element[ 0 ], 'y' );
-
-               $( container ).animate( {
-                       scrollTop: this.$element.offset().top - this.topScrollOffset
-               } );
-       };
-
        /**
         * Reevaluate the restore state for the widget between setting to defaults and clearing all filters
         */
                this.emptyFilterMessage.toggle( currFiltersAreEmpty );
        };
 
+       /**
+        * Mark an item widget as selected
+        *
+        * @param {mw.rcfilters.ui.CapsuleItemWidget} item Capsule widget
+        */
+       mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.select = function ( item ) {
+               if ( this.selected !== item ) {
+                       // Unselect previous
+                       if ( this.selected ) {
+                               this.selected.toggleSelected( false );
+                       }
+
+                       // Select new one
+                       this.selected = item;
+                       if ( this.selected ) {
+                               item.toggleSelected( true );
+                       }
+               }
+       };
+
+       /**
+        * Reset selection and remove selected states from all items
+        */
+       mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.resetSelection = function () {
+               if ( this.selected !== null ) {
+                       this.selected = null;
+                       this.getItems().forEach( function ( capsuleWidget ) {
+                               capsuleWidget.toggleSelected( false );
+                       } );
+               }
+       };
+
        /**
         * @inheritdoc
         */
index f858ab0..a750c44 100644 (file)
@@ -19,6 +19,7 @@
 
                this.controller = controller;
                this.model = model;
+               this.filters = {};
 
                // Mixin constructors
                OO.ui.mixin.GroupWidget.call( this, config );
@@ -36,6 +37,7 @@
 
                this.$element
                        .addClass( 'mw-rcfilters-ui-filterGroupWidget' )
+                       .addClass( 'mw-rcfilters-ui-filterGroupWidget-name-' + this.model.getName() )
                        .append(
                                this.$label,
                                this.$group
                );
        };
 
+       /**
+        * Get an item widget from its filter name
+        *
+        * @param {string} filterName Filter name
+        * @return {mw.rcfilters.ui.FilterItemWidget} Item widget
+        */
+       mw.rcfilters.ui.FilterGroupWidget.prototype.getItemWidget = function ( filterName ) {
+               return this.filters[ filterName ];
+       };
+
+       /**
+        * Populate data from the model
+        */
        mw.rcfilters.ui.FilterGroupWidget.prototype.populateFromModel = function () {
                var widget = this;
 
+               this.clearItems();
+               this.filters = {};
+
                this.addItems(
                        this.model.getItems().map( function ( filterItem ) {
-                               return new mw.rcfilters.ui.FilterItemWidget(
+                               var groupWidget = new mw.rcfilters.ui.FilterItemWidget(
                                        widget.controller,
                                        filterItem,
                                        {
                                                $overlay: widget.$overlay
                                        }
                                );
+
+                               widget.filters[ filterItem.getName() ] = groupWidget;
+
+                               return groupWidget;
                        } )
                );
        };
index 32db0b6..17aad51 100644 (file)
 
                // Parent
                mw.rcfilters.ui.FilterItemHighlightButton.parent.call( this, $.extend( {}, config, {
-                       icon: 'edit',
+                       icon: 'highlight',
                        indicator: 'down',
                        popup: {
                                anchor: false,
                                padded: true,
                                align: 'backwards',
+                               horizontalPosition: 'end',
+                               $floatableContainer: this.$element,
                                width: 290,
                                $content: this.colorPickerWidget.$element
                        }
index 63db2b0..4ea284b 100644 (file)
@@ -21,6 +21,7 @@
 
                this.controller = controller;
                this.model = model;
+               this.selected = false;
 
                this.checkboxWidget = new mw.rcfilters.ui.CheckboxInputWidget( {
                        value: this.model.getName(),
@@ -44,7 +45,8 @@
                        this.controller,
                        this.model,
                        {
-                               $overlay: config.$overlay || this.$element
+                               $overlay: config.$overlay || this.$element,
+                               title: mw.msg( 'rcfilters-highlightmenu-help' )
                        }
                );
                this.highlightButton.toggle( this.model.isHighlightEnabled() );
@@ -93,7 +95,7 @@
         * @param {boolean} isSelected The checkbox is selected
         */
        mw.rcfilters.ui.FilterItemWidget.prototype.onCheckboxChange = function ( isSelected ) {
-               this.controller.updateFilter( this.model.getName(), isSelected );
+               this.controller.toggleFilterSelect( this.model.getName(), isSelected );
        };
 
        /**
                this.setCurrentMuteState();
        };
 
+       /**
+        * Set selected state on this widget
+        *
+        * @param {boolean} [isSelected] Widget is selected
+        */
+       mw.rcfilters.ui.FilterItemWidget.prototype.toggleSelected = function ( isSelected ) {
+               isSelected = isSelected !== undefined ? isSelected : !this.selected;
+
+               if ( this.selected !== isSelected ) {
+                       this.selected = isSelected;
+
+                       this.$element.toggleClass( 'mw-rcfilters-ui-filterItemWidget-selected', this.selected );
+               }
+       };
+
        /**
         * Set the current mute state for this item
         */
                        'mw-rcfilters-ui-filterItemWidget-muted',
                        this.model.isConflicted() ||
                        this.model.isIncluded() ||
-                       this.model.isFullyCovered() ||
                        (
                                // Item is also muted when any of the items in its group is active
                                this.model.getGroupModel().isActive() &&
index d46bd4b..3f67da4 100644 (file)
@@ -13,6 +13,7 @@
         * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
         */
        mw.rcfilters.ui.FilterWrapperWidget = function MwRcfiltersUiFilterWrapperWidget( controller, model, config ) {
+               var $footer = $( '<div>' );
                config = config || {};
 
                // Parent
                        }
                );
 
+               $footer.append(
+                       new OO.ui.ButtonWidget( {
+                               framed: false,
+                               icon: 'feedback',
+                               flags: [ 'progressive' ],
+                               label: mw.msg( 'rcfilters-filterlist-feedbacklink' ),
+                               href: 'https://www.mediawiki.org/wiki/Help_talk:New_filters_for_edit_review'
+                       } ).$element
+               );
+
                this.textInput = new OO.ui.TextInputWidget( {
                        classes: [ 'mw-rcfilters-ui-filterWrapperWidget-search' ],
                        icon: 'search',
@@ -43,6 +54,7 @@
                        $overlay: this.$overlay,
                        popup: {
                                $content: this.filterPopup.$element,
+                               $footer: $footer,
                                classes: [ 'mw-rcfilters-ui-filterWrapperWidget-popup' ],
                                width: 650
                        }
 
                // Events
                this.model.connect( this, {
-                       initialize: 'onModelInitialize'
+                       initialize: 'onModelInitialize',
+                       itemUpdate: 'onModelItemUpdate'
                } );
                this.textInput.connect( this, {
-                       change: 'onTextInputChange'
+                       change: 'onTextInputChange',
+                       enter: 'onTextInputEnter'
                } );
+               this.capsule.connect( this, { capsuleItemClick: 'onCapsuleItemClick' } );
+               this.capsule.popup.connect( this, { toggle: 'onCapsulePopupToggle' } );
+
+               // Initialize
                this.$element
                        .addClass( 'mw-rcfilters-ui-filterWrapperWidget' )
                        .append( this.capsule.$element, this.textInput.$element );
        OO.inheritClass( mw.rcfilters.ui.FilterWrapperWidget, OO.ui.Widget );
        OO.mixinClass( mw.rcfilters.ui.FilterWrapperWidget, OO.ui.mixin.PendingElement );
 
+       /**
+        * Respond to capsule item click and make the popup scroll down to the requested item
+        *
+        * @param {mw.rcfilters.ui.CapsuleItemWidget} item Clicked item
+        */
+       mw.rcfilters.ui.FilterWrapperWidget.prototype.onCapsuleItemClick = function ( item ) {
+               var filterName = item.getData(),
+                       // Find the item in the popup
+                       filterWidget = this.filterPopup.getItemWidget( filterName );
+
+               // Highlight item
+               this.filterPopup.select( filterName );
+               this.capsule.select( item );
+
+               this.scrollToTop( filterWidget.$element );
+       };
+
+       /**
+        * Respond to popup toggle event. Reset selection in the list when the popup is closed.
+        *
+        * @param {boolean} isVisible Popup is visible
+        */
+       mw.rcfilters.ui.FilterWrapperWidget.prototype.onCapsulePopupToggle = function ( isVisible ) {
+               if ( !isVisible ) {
+                       if ( !this.textInput.getValue() ) {
+                               // Only reset selection if we are not filtering
+                               this.filterPopup.resetSelection();
+                               this.capsule.resetSelection();
+                       }
+               } else {
+                       this.scrollToTop( this.capsule.$element, 10 );
+               }
+       };
+
        /**
         * Respond to text input change
         *
        mw.rcfilters.ui.FilterWrapperWidget.prototype.onTextInputChange = function ( newValue ) {
                // Filter the results
                this.filterPopup.filter( this.model.findMatches( newValue ) );
+
+               if ( !newValue ) {
+                       // If the value is empty, we didn't actually
+                       // filter anything. the filter method will run
+                       // and show all, but then will select the
+                       // top item - but in this case, no selection
+                       // should be made.
+                       this.filterPopup.resetSelection();
+               }
+               this.capsule.popup.clip();
+       };
+
+       /**
+        * Respond to text input enter event
+        */
+       mw.rcfilters.ui.FilterWrapperWidget.prototype.onTextInputEnter = function () {
+               var filter = this.filterPopup.getSelectedFilter();
+
+               // Toggle the filter
+               this.controller.toggleFilterSelect( filter );
        };
 
        /**
                        }
                } );
        };
+
+       /**
+        * Respond to item update and reset the selection. This will make it so that
+        * any actual interaction with the system resets the selection state of any item.
+        */
+       mw.rcfilters.ui.FilterWrapperWidget.prototype.onModelItemUpdate = function () {
+               if ( !this.textInput.getValue() ) {
+                       this.filterPopup.resetSelection();
+               }
+       };
+
+       /**
+        * Scroll the element to top within its container
+        *
+        * @private
+        * @param {jQuery} $element Element to position
+        * @param {number} [marginFromTop] When scrolling the entire widget to the top, leave this
+        *  much space (in pixels) above the widget.
+        */
+       mw.rcfilters.ui.FilterWrapperWidget.prototype.scrollToTop = function ( $element, marginFromTop ) {
+               var container = OO.ui.Element.static.getClosestScrollableContainer( $element[ 0 ], 'y' ),
+                       pos = OO.ui.Element.static.getRelativePosition( $element, $( container ) ),
+                       containerScrollTop = $( container ).is( 'body, html' ) ? 0 : $( container ).scrollTop();
+
+               // Scroll to item
+               $( container ).animate( {
+                       scrollTop: containerScrollTop + pos.top - ( marginFromTop || 0 )
+               } );
+       };
 }( mediaWiki ) );
index ae9ee71..cefe749 100644 (file)
                this.controller = controller;
                this.model = model;
                this.$overlay = config.$overlay || this.$element;
+               this.groups = {};
+               this.selected = null;
 
                this.highlightButton = new OO.ui.ButtonWidget( {
                        label: mw.message( 'rcfilters-highlightbutton-title' ).text(),
                        classes: [ 'mw-rcfilters-ui-filtersListWidget-hightlightButton' ]
                } );
 
-               this.$label.append( this.highlightButton.$element );
-
                this.noResultsLabel = new OO.ui.LabelWidget( {
                        label: mw.msg( 'rcfilters-filterlist-noresults' ),
                        classes: [ 'mw-rcfilters-ui-filtersListWidget-noresults' ]
                this.$element
                        .addClass( 'mw-rcfilters-ui-filtersListWidget' )
                        .append(
-                               this.$label,
+                               $( '<div>' )
+                                       .addClass( 'mw-rcfilters-ui-table' )
+                                       .addClass( 'mw-rcfilters-ui-filtersListWidget-header' )
+                                       .append(
+                                               $( '<div>' )
+                                                       .addClass( 'mw-rcfilters-ui-row' )
+                                                       .append(
+                                                               $( '<div>' )
+                                                                       .addClass( 'mw-rcfilters-ui-cell' )
+                                                                       .addClass( 'mw-rcfilters-ui-filtersListWidget-header-title' )
+                                                                       .append( this.$label ),
+                                                               $( '<div>' )
+                                                                       .addClass( 'mw-rcfilters-ui-cell' )
+                                                                       .addClass( 'mw-rcfilters-ui-filtersListWidget-header-highlight' )
+                                                                       .append( this.highlightButton.$element )
+                                                       )
+                                       ),
+                               // this.$label,
                                this.$group
                                        .addClass( 'mw-rcfilters-ui-filtersListWidget-group' ),
                                this.noResultsLabel.$element
 
                // Reset
                this.clearItems();
+               this.groups = {};
 
                this.addItems(
                        Object.keys( this.model.getFilterGroups() ).map( function ( groupName ) {
-                               return new mw.rcfilters.ui.FilterGroupWidget(
+                               var groupWidget = new mw.rcfilters.ui.FilterGroupWidget(
                                        widget.controller,
                                        widget.model.getGroup( groupName ),
                                        {
                                                $overlay: widget.$overlay
                                        }
                                );
+
+                               widget.groups[ groupName ] = groupWidget;
+                               return groupWidget;
                        } )
                );
        };
                this.controller.toggleHighlight();
        };
 
+       /**
+        * Find the filter item widget that corresponds to the item name
+        *
+        * @param {string} itemName Filter name
+        * @return {mw.rcfilters.ui.FilterItemWidget} Filter widget
+        */
+       mw.rcfilters.ui.FiltersListWidget.prototype.getItemWidget = function ( itemName ) {
+               var filterItem = this.model.getItemByName( itemName ),
+                       // Find the group
+                       groupWidget = this.groups[ filterItem.getGroupName() ];
+
+               // Find the item inside the group
+               return groupWidget.getItemWidget( itemName );
+       };
+
+       /**
+        * Get the current selection
+        *
+        * @return {string|null} Selected filter. Null if none is selected.
+        */
+       mw.rcfilters.ui.FiltersListWidget.prototype.getSelectedFilter = function () {
+               return this.selected;
+       };
+
+       /**
+        * Mark an item widget as selected
+        *
+        * @param {string} itemName Filter name
+        */
+       mw.rcfilters.ui.FiltersListWidget.prototype.select = function ( itemName ) {
+               var filterWidget;
+
+               if ( this.selected !== itemName ) {
+                       // Unselect previous
+                       if ( this.selected ) {
+                               filterWidget = this.getItemWidget( this.selected );
+                               filterWidget.toggleSelected( false );
+                       }
+
+                       // Select new one
+                       this.selected = itemName;
+                       if ( this.selected ) {
+                               filterWidget = this.getItemWidget( this.selected );
+                               filterWidget.toggleSelected( true );
+                       }
+               }
+       };
+
+       /**
+        * Reset selection and remove selected states from all items
+        */
+       mw.rcfilters.ui.FiltersListWidget.prototype.resetSelection = function () {
+               if ( this.selected !== null ) {
+                       this.selected = null;
+                       this.getItems().forEach( function ( groupWidget ) {
+                               groupWidget.getItems().forEach( function ( filterItemWidget ) {
+                                       filterItemWidget.toggleSelected( false );
+                               } );
+                       } );
+               }
+       };
+
        /**
         * Switch between showing the 'no results' message for filtering results or the result list.
         *
         *  arranged by their group names
         */
        mw.rcfilters.ui.FiltersListWidget.prototype.filter = function ( groupItems ) {
-               var i, j, groupName, itemWidgets,
+               var i, j, groupName, itemWidgets, topItem, isVisible,
                        groupWidgets = this.getItems(),
                        hasItemWithName = function ( itemArr, name ) {
                                return !!itemArr.filter( function ( item ) {
                                } ).length;
                        };
 
+               this.resetSelection();
+
                if ( $.isEmptyObject( groupItems ) ) {
                        // No results. Hide everything, show only 'no results'
                        // message
                        // We have items to show
                        itemWidgets = groupWidgets[ i ].getItems();
                        for ( j = 0; j < itemWidgets.length; j++ ) {
+                               isVisible = hasItemWithName( groupItems[ groupName ], itemWidgets[ j ].getName() );
                                // Only show items that are in the filtered list
-                               itemWidgets[ j ].toggle(
-                                       hasItemWithName( groupItems[ groupName ], itemWidgets[ j ].getName() )
-                               );
+                               itemWidgets[ j ].toggle( isVisible );
+
+                               if ( !topItem && isVisible ) {
+                                       topItem = itemWidgets[ j ];
+                               }
                        }
                }
+
+               // Select the first item
+               if ( topItem ) {
+                       this.select( topItem.getName() );
+               }
        };
 }( mediaWiki, jQuery ) );
index 2513b07..e914bbe 100644 (file)
 ( function ( mw ) {
        /**
         * Wrapper for the RC form with hide/show links
+        * Must be constructed after the model is initialized.
         *
         * @extends OO.ui.Widget
         *
         * @constructor
-        * @param {mw.rcfilters.dm.ChangesListViewModel} model Changes list view model
+        * @param {mw.rcfilters.dm.FiltersViewModel} filtersModel Changes list view model
+        * @param {mw.rcfilters.dm.ChangesListViewModel} changeListModel Changes list view model
+        * @param {mw.rcfilters.Controller} controller RCfilters controller
         * @param {jQuery} $formRoot Root element of the form to attach to
         * @param {Object} config Configuration object
         */
-       mw.rcfilters.ui.FormWrapperWidget = function MwRcfiltersUiFormWrapperWidget( model, $formRoot, config ) {
+       mw.rcfilters.ui.FormWrapperWidget = function MwRcfiltersUiFormWrapperWidget( filtersModel, changeListModel, controller, $formRoot, config ) {
                config = config || {};
 
                // Parent
                mw.rcfilters.ui.FormWrapperWidget.parent.call( this, $.extend( {}, config, {
                        $element: $formRoot
                } ) );
+               // Mixin constructors
+               OO.ui.mixin.PendingElement.call( this, config );
 
-               this.model = model;
-               this.$submitButton = this.$element.find( 'input[type=submit]' );
+               this.changeListModel = changeListModel;
+               this.filtersModel = filtersModel;
+               this.controller = controller;
+               this.$submitButton = this.$element.find( 'form input[type=submit]' );
+
+               this.$element
+                       .on( 'click', 'a[data-params]', this.onLinkClick.bind( this ) );
+
+               this.$element
+                       .on( 'submit', 'form', this.onFormSubmit.bind( this ) );
 
                // Events
-               this.model.connect( this, {
-                       invalidate: 'onModelInvalidate',
-                       update: 'onModelUpdate'
+               this.changeListModel.connect( this, {
+                       invalidate: 'onChangesModelInvalidate',
+                       update: 'onChangesModelUpdate'
                } );
+
+               // Initialize
+               this.cleanUpFieldset();
+               this.$element
+                       .addClass( 'mw-rcfilters-ui-FormWrapperWidget' );
        };
 
        /* Initialization */
 
        OO.inheritClass( mw.rcfilters.ui.FormWrapperWidget, OO.ui.Widget );
+       OO.mixinClass( mw.rcfilters.ui.FormWrapperWidget, OO.ui.mixin.PendingElement );
+
+       /**
+        * Respond to link click
+        *
+        * @param {jQuery.Event} e Event
+        * @return {boolean} false
+        */
+       mw.rcfilters.ui.FormWrapperWidget.prototype.onLinkClick = function ( e ) {
+               this.controller.updateChangesList( $( e.target ).data( 'params' ) );
+               return false;
+       };
+
+       /**
+        * Respond to form submit event
+        *
+        * @param {jQuery.Event} e Event
+        * @return {boolean} false
+        */
+       mw.rcfilters.ui.FormWrapperWidget.prototype.onFormSubmit = function ( e ) {
+               var data = {};
+
+               // Collect all data from form
+               $( e.target ).find( 'input:not([type="hidden"],[type="submit"]), select' ).each( function () {
+                       if ( !$( this ).is( ':checkbox' ) || $( this ).is( ':checked' ) ) {
+                               data[ $( this ).prop( 'name' ) ] = $( this ).val();
+                       }
+               } );
+
+               this.controller.updateChangesList( data );
+               return false;
+       };
 
        /**
         * Respond to model invalidate
         */
-       mw.rcfilters.ui.FormWrapperWidget.prototype.onModelInvalidate = function () {
+       mw.rcfilters.ui.FormWrapperWidget.prototype.onChangesModelInvalidate = function () {
+               this.pushPending();
                this.$submitButton.prop( 'disabled', true );
        };
 
        /**
-        * Respond to model update
+        * Respond to model update, replace the show/hide links with the ones from the
+        * server so they feature the correct state.
+        *
+        * @param {jQuery|string} $changesList Updated changes list
+        * @param {jQuery} $fieldset Updated fieldset
         */
-       mw.rcfilters.ui.FormWrapperWidget.prototype.onModelUpdate = function () {
+       mw.rcfilters.ui.FormWrapperWidget.prototype.onChangesModelUpdate = function ( $changesList, $fieldset ) {
                this.$submitButton.prop( 'disabled', false );
+
+               // Replace the entire fieldset
+               this.$element.empty().append( $fieldset.contents() );
+
+               this.cleanUpFieldset();
+
+               this.popPending();
+       };
+
+       /**
+        * Clean up the old-style show/hide that we have implemented in the filter list
+        */
+       mw.rcfilters.ui.FormWrapperWidget.prototype.cleanUpFieldset = function () {
+               var widget = this;
+
+               // HACK: Remove old-style filter links for filters handled by the widget
+               // Ideally the widget would handle all filters and we'd just remove .rcshowhide entirely
+               this.$element.find( '.rcshowhide' ).children().each( function () {
+                       // HACK: Interpret the class name to get the filter name
+                       // This should really be set as a data attribute
+                       var i,
+                               name = null,
+                               // Some of the older browsers we support don't have .classList,
+                               // so we have to interpret the class attribute manually.
+                               classes = this.getAttribute( 'class' ).split( ' ' );
+                       for ( i = 0; i < classes.length; i++ ) {
+                               if ( classes[ i ].substr( 0, 'rcshow'.length ) === 'rcshow' ) {
+                                       name = classes[ i ].substr( 'rcshow'.length );
+                                       break;
+                               }
+                       }
+                       if ( name === null ) {
+                               return;
+                       }
+                       if ( name === 'hidemine' ) {
+                               // HACK: the span for hidemyself is called hidemine
+                               name = 'hidemyself';
+                       }
+
+                       // This span corresponds to a filter that's in our model, so remove it
+                       if ( widget.filtersModel.getItemByName( name ) ) {
+                               // HACK: Remove the text node after the span.
+                               // If there isn't one, we're at the end, so remove the text node before the span.
+                               // This would be unnecessary if we added separators with CSS.
+                               if ( this.nextSibling && this.nextSibling.nodeType === Node.TEXT_NODE ) {
+                                       this.parentNode.removeChild( this.nextSibling );
+                               } else if ( this.previousSibling && this.previousSibling.nodeType === Node.TEXT_NODE ) {
+                                       this.parentNode.removeChild( this.previousSibling );
+                               }
+                               // Remove the span itself
+                               this.parentNode.removeChild( this );
+                       }
+               } );
        };
 }( mediaWiki ) );
index 823ce05..b392259 100644 (file)
@@ -19,7 +19,7 @@
        padding-right: 15px;
 }
 
-.mw-body a.external[href^="mailto:"],
+.mw-body a.external[href^='mailto:'],
 .link-mailto {
        background: url( images/mail.png ) center right no-repeat;
        /* @embed */
@@ -27,7 +27,7 @@
        padding-right: 15px;
 }
 
-.mw-body a.external[href^="ftp://"],
+.mw-body a.external[href^='ftp://'],
 .link-ftp {
        background: url( images/ftp-ltr.png ) center right no-repeat;
        /* @embed */
@@ -35,8 +35,8 @@
        padding-right: 15px;
 }
 
-.mw-body a.external[href^="irc://"],
-.mw-body a.external[href^="ircs://"],
+.mw-body a.external[href^='irc://'],
+.mw-body a.external[href^='ircs://'],
 .link-irc {
        background: url( images/chat-ltr.png ) center right no-repeat;
        /* @embed */
        padding-right: 15px;
 }
 
-.mw-body a.external[href$=".ogg"],
-.mw-body a.external[href$=".OGG"],
-.mw-body a.external[href$=".mid"],
-.mw-body a.external[href$=".MID"],
-.mw-body a.external[href$=".midi"],
-.mw-body a.external[href$=".MIDI"],
-.mw-body a.external[href$=".mp3"],
-.mw-body a.external[href$=".MP3"],
-.mw-body a.external[href$=".wav"],
-.mw-body a.external[href$=".WAV"],
-.mw-body a.external[href$=".wma"],
-.mw-body a.external[href$=".WMA"],
+.mw-body a.external[href$='.ogg'],
+.mw-body a.external[href$='.OGG'],
+.mw-body a.external[href$='.mid'],
+.mw-body a.external[href$='.MID'],
+.mw-body a.external[href$='.midi'],
+.mw-body a.external[href$='.MIDI'],
+.mw-body a.external[href$='.mp3'],
+.mw-body a.external[href$='.MP3'],
+.mw-body a.external[href$='.wav'],
+.mw-body a.external[href$='.WAV'],
+.mw-body a.external[href$='.wma'],
+.mw-body a.external[href$='.WMA'],
 .link-audio {
        background: url( images/audio-ltr.png ) center right no-repeat;
        /* @embed */
        padding-right: 15px;
 }
 
-.mw-body a.external[href$=".ogm"],
-.mw-body a.external[href$=".OGM"],
-.mw-body a.external[href$=".avi"],
-.mw-body a.external[href$=".AVI"],
-.mw-body a.external[href$=".mpeg"],
-.mw-body a.external[href$=".MPEG"],
-.mw-body a.external[href$=".mpg"],
-.mw-body a.external[href$=".MPG"],
+.mw-body a.external[href$='.ogm'],
+.mw-body a.external[href$='.OGM'],
+.mw-body a.external[href$='.avi'],
+.mw-body a.external[href$='.AVI'],
+.mw-body a.external[href$='.mpeg'],
+.mw-body a.external[href$='.MPEG'],
+.mw-body a.external[href$='.mpg'],
+.mw-body a.external[href$='.MPG'],
 .link-video {
        background: url( images/video.png ) center right no-repeat;
        /* @embed */
        padding-right: 15px;
 }
 
-.mw-body a.external[href$=".pdf"],
-.mw-body a.external[href$=".PDF"],
-.mw-body a.external[href*=".pdf#"],
-.mw-body a.external[href*=".PDF#"],
-.mw-body a.external[href*=".pdf?"],
-.mw-body a.external[href*=".PDF?"],
+.mw-body a.external[href$='.pdf'],
+.mw-body a.external[href$='.PDF'],
+.mw-body a.external[href*='.pdf#'],
+.mw-body a.external[href*='.PDF#'],
+.mw-body a.external[href*='.pdf?'],
+.mw-body a.external[href*='.PDF?'],
 .link-document {
        background: url( images/document-ltr.png ) center right no-repeat;
        /* @embed */
index b4fe934..b3d1613 100644 (file)
  * automatically when content is modified.
  */
 .mw-body-content {
-       counter-reset: mw-NumberedExtLink;
+       counter-reset: mw-numbered-ext-link;
 }
 
-.mw-body-content a[rel~="mw:ExtLink"]:empty:after {
-       content: "[" counter( mw-NumberedExtLink ) "]";
-       counter-increment: mw-NumberedExtLink;
+.mw-body-content a[rel~='mw:ExtLink']:empty:after {
+       content: '[' counter( mw-numbered-ext-link ) ']';
+       counter-increment: mw-numbered-ext-link;
 }
 
 /**
@@ -88,8 +88,8 @@ figure[typeof*='mw:Image'] {
                display: table-caption;
                caption-side: bottom;
                /* In mw-core the font-size is duplicated, 94% in thumbiner
-                  and again 94% in thumbcaption. 88% for font size of the
-                  caption results in the same behavior. */
+                * and again 94% in thumbcaption. 88% for font size of the
+                * caption results in the same behavior. */
                font-size: 88%;
                line-height: 1.4em;
                text-align: left;
@@ -133,7 +133,7 @@ figure[typeof~='mw:Image/Frame'] > *:first-child > img,
 }
 
 /* Hide the caption for frameless and plain floated images */
-figure[typeof~="mw:Image/Frameless"] > figcaption,
-figure[typeof~="mw:Image"] > figcaption {
+figure[typeof~='mw:Image/Frameless'] > figcaption,
+figure[typeof~='mw:Image'] > figcaption {
        display: none;
 }
index c989c83..97659ed 100644 (file)
 
                                if ( page.tokenWidget ) {
                                        k = page.apiModule + page.tokenWidget.paramInfo.name;
-                                       tokenWait[ k ] = page.tokenWidget.fetchToken()
+                                       tokenWait[ k ] = page.tokenWidget.fetchToken();
+                                       tokenWait[ k ]
                                                .done( success.bind( page.tokenWidget, k ) )
                                                .fail( failure.bind( page.tokenWidget, k ) );
                                }
 
                Util.fetchModuleInfo( this.apiModule )
                        .done( function ( pi ) {
-                               var prefix, i, j, dl, widget, $widgetLabel, widgetField, helpField, tmp, flag, count,
+                               var prefix, i, j, descriptionContainer, widget, $widgetLabel, widgetField, helpField, tmp, flag, count,
                                        items = [],
                                        deprecatedItems = [],
                                        buttons = [],
 
                                if ( pi.helpurls.length ) {
                                        buttons.push( new OO.ui.PopupButtonWidget( {
+                                               $overlay: $( '#mw-apisandbox-ui' ),
                                                label: mw.message( 'apisandbox-helpurls' ).text(),
                                                icon: 'help',
                                                popup: {
 
                                if ( pi.examples.length ) {
                                        buttons.push( new OO.ui.PopupButtonWidget( {
+                                               $overlay: $( '#mw-apisandbox-ui' ),
                                                label: mw.message( 'apisandbox-examples' ).text(),
                                                icon: 'code',
                                                popup: {
                                                        that.tokenWidget = widget;
                                                }
 
-                                               dl = $( '<dl>' );
-                                               dl.append( $( '<dd>', {
+                                               descriptionContainer = $( '<div>' );
+                                               descriptionContainer.append( $( '<div>', {
                                                        addClass: 'description',
                                                        append: Util.parseHTML( pi.parameters[ i ].description )
                                                } ) );
                                                if ( pi.parameters[ i ].info && pi.parameters[ i ].info.length ) {
                                                        for ( j = 0; j < pi.parameters[ i ].info.length; j++ ) {
-                                                               dl.append( $( '<dd>', {
+                                                               descriptionContainer.append( $( '<div>', {
                                                                        addClass: 'info',
                                                                        append: Util.parseHTML( pi.parameters[ i ].info[ j ] )
                                                                } ) );
 
                                                        case 'limit':
                                                                if ( pi.parameters[ i ].highmax !== undefined ) {
-                                                                       dl.append( $( '<dd>', {
+                                                                       descriptionContainer.append( $( '<div>', {
                                                                                addClass: 'info',
                                                                                append: [
                                                                                        Util.parseMsg(
                                                                                ]
                                                                        } ) );
                                                                } else {
-                                                                       dl.append( $( '<dd>', {
+                                                                       descriptionContainer.append( $( '<div>', {
                                                                                addClass: 'info',
                                                                                append: [
                                                                                        Util.parseMsg( 'api-help-param-limit', pi.parameters[ i ].max ),
                                                                        tmp += 'max';
                                                                }
                                                                if ( tmp !== '' ) {
-                                                                       dl.append( $( '<dd>', {
+                                                                       descriptionContainer.append( $( '<div>', {
                                                                                addClass: 'info',
                                                                                append: Util.parseMsg(
                                                                                        'api-help-param-integer-' + tmp,
                                                                );
                                                        }
                                                        if ( tmp.length ) {
-                                                               dl.append( $( '<dd>', {
+                                                               descriptionContainer.append( $( '<div>', {
                                                                        addClass: 'info',
                                                                        append: Util.parseHTML( tmp.join( ' ' ) )
                                                                } ) );
                                                        } ), {
                                                                align: 'inline',
                                                                classes: [ 'mw-apisandbox-help-field' ],
-                                                               label: dl
+                                                               label: descriptionContainer
                                                        }
                                                );
 
index a30a15d..ae557b4 100644 (file)
@@ -2,7 +2,7 @@
  * Styling for Special:Block
  */
 
-label[for="mw-input-wpConfirm"] {
+label[for='mw-input-wpConfirm'] {
        font-weight: bold;
 }
 
index 163e85d..0fa6610 100644 (file)
@@ -3,7 +3,7 @@
  */
 ( function ( mw, $ ) {
        $( function () {
-               var $preftoc, $preferences, $fieldsets, labelFunc,
+               var $preftoc, $preferences, $fieldsets, labelFunc, previousTab,
                        $tzSelect, $tzTextbox, $localtimeHolder, servertime, allowCloseWindow,
                        convertmessagebox = require( 'mediawiki.notification.convertmessagebox' );
 
                        updateTimezoneSelection();
                }
 
-               // Preserve the tab after saving the preferences
-               // Not using cookies, because their deletion results are inconsistent.
-               // Not using jStorage due to its enormous size (for this feature)
-               if ( window.sessionStorage ) {
-                       if ( sessionStorage.getItem( 'mediawikiPreferencesTab' ) !== null ) {
-                               switchPrefTab( sessionStorage.getItem( 'mediawikiPreferencesTab' ), 'noHash' );
-                       }
+               // 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
-                       sessionStorage.removeItem( 'mediawikiPreferencesTab' );
-
-                       $( '#mw-prefs-form' ).submit( function () {
-                               var storageData = $( $preftoc ).find( 'li.selected a' ).attr( 'id' ).replace( 'preftab-', '' );
-                               sessionStorage.setItem( 'mediawikiPreferencesTab', storageData );
-                       } );
+                       mw.storage.session.remove( previousTab );
                }
 
+               $( '#mw-prefs-form' ).on( 'submit', function () {
+                       var value = $( $preftoc ).find( 'li.selected a' ).attr( 'id' ).replace( 'preftab-', '' );
+                       mw.storage.session.set( 'mwpreferences-prevTab', value );
+               } );
+
                // Check if all of the form values are unchanged
                function isPrefsChanged() {
                        var inputs = $( '#mw-prefs-form :input[name]' ),
index 8d63902..5504883 100644 (file)
@@ -32,7 +32,7 @@
        visibility: hidden;
        display: block;
        font-size: 0;
-       content: " ";
+       content: ' ';
        clear: both;
        height: 0;
 }
@@ -84,7 +84,7 @@ to resemble a traditional dictionary definition */
        visibility: hidden;
        display: block;
        font-size: 0;
-       content: " ";
+       content: ' ';
        clear: both;
        height: 0;
 }
@@ -199,6 +199,7 @@ span the interwiki results across the bottom of the page.
 }
 
 /* mobile */
+/* stylelint-disable declaration-no-important */
 @media only screen and ( max-width: 768px ) {
        #mw-interwiki-results {
                width: 100%;
@@ -222,3 +223,4 @@ span the interwiki results across the bottom of the page.
                max-width: none !important;
        }
 }
+/* stylelint-enable declaration-no-important */
index d65b284..93ea294 100644 (file)
@@ -1,42 +1,42 @@
-@import "mediawiki.mixins";
+@import 'mediawiki.mixins';
 
 #mw-editbutton-bold {
-       .background-image("images/@{button-bold}");
+       .background-image('images/@{button-bold}');
 }
 
 #mw-editbutton-italic {
-       .background-image("images/@{button-italic}");
+       .background-image('images/@{button-italic}');
 }
 
 #mw-editbutton-link {
-       .background-image("images/@{button-link}");
+       .background-image('images/@{button-link}');
 }
 
 #mw-editbutton-extlink {
-       .background-image("images/@{button-extlink}");
+       .background-image('images/@{button-extlink}');
 }
 
 #mw-editbutton-headline {
-       .background-image("images/@{button-headline}");
+       .background-image('images/@{button-headline}');
 }
 
 #mw-editbutton-image {
-       .background-image("images/@{button-image}");
+       .background-image('images/@{button-image}');
 }
 
 #mw-editbutton-media {
-       .background-image("images/@{button-media}");
+       .background-image('images/@{button-media}');
 }
 
 #mw-editbutton-nowiki {
-       .background-image("images/@{button-nowiki}");
+       .background-image('images/@{button-nowiki}');
 }
 
 // Who decided to make only this single one different than the name of the data item?
 #mw-editbutton-signature {
-       .background-image("images/@{button-sig}");
+       .background-image('images/@{button-sig}');
 }
 
 #mw-editbutton-hr {
-       .background-image("images/@{button-hr}");
+       .background-image('images/@{button-hr}');
 }
index 6397c73..8e97c3e 100644 (file)
@@ -1,6 +1,6 @@
-@import "mediawiki.mixins";
-@import "mediawiki.ui/variables";
-@import "mediawiki.ui/mixins";
+@import 'mediawiki.mixins';
+@import 'mediawiki.ui/variables';
+@import 'mediawiki.ui/mixins';
 
 // Helpers
 .mixin-mw-ui-anchor-styles( @mainColor ) {
index 5dc025f..abe7c46 100644 (file)
@@ -1,6 +1,6 @@
-@import "mediawiki.mixins";
-@import "mediawiki.ui/variables";
-@import "mediawiki.ui/mixins";
+@import 'mediawiki.mixins';
+@import 'mediawiki.ui/variables';
+@import 'mediawiki.ui/mixins';
 
 // Buttons
 //
@@ -33,7 +33,8 @@
        display: inline-block;
        min-width: 4em;
        max-width: 28.75em; // equivalent to 460px, @see T95367
-       padding: 0.5em 1em;
+       padding: 0.546875em 1em;
+       line-height: 1.286;
        margin: 0;
        border-radius: @borderRadius;
        .box-sizing( border-box );
        }
 }
 
+input.mw-ui-button,
+button.mw-ui-button {
+       // Buttons in Firefox have extra height
+       &::-moz-focus-inner {
+               margin-top: -1px;
+               margin-bottom: -1px;
+       }
+}
+
 a.mw-ui-button {
        text-decoration: none;
 
@@ -219,12 +229,6 @@ a.mw-ui-button {
        &:focus {
                text-decoration: none;
        }
-
-       // a-tags behave different to inputs if the line-height attribute is inherited
-       // from another element (e.g. mw-body-content). They appear bigger as input
-       // tags. See Bug T116427. To fix that, apply the correct line-height (used
-       // for inputs) to a-tags, too.
-       line-height: normal;
 }
 
 // Button groups
index f983087..2ca20a5 100644 (file)
@@ -1,5 +1,5 @@
-@import "mediawiki.mixins";
-@import "mediawiki.ui/variables";
+@import 'mediawiki.mixins';
+@import 'mediawiki.ui/variables';
 
 // Checkbox
 //
                vertical-align: middle;
        }
 
-       input[type="checkbox"] {
+       input[type='checkbox'] {
                // we hide the input element as instead we will style the label that follows
                // we use opacity so that VoiceOver software can still identify it
                opacity: 0;
-               // Render "on top of" the label, so that it's still clickable (T98905)
+               // Render *on top of* the label, so that it's still clickable (T98905)
                z-index: 1;
                position: relative;
                // ensure the invisible checkbox takes up the required width
@@ -68,7 +68,7 @@
                }
 
                // the pseudo before element of the label after the checkbox now looks like a checkbox
-               & + label::before {
+               & + label:before {
                        content: '';
                        background-color: #fff;
                        .background-image-svg( 'images/checked.svg', 'images/checked.png' );
                }
 
                // when the input is checked, style the label pseudo before element that followed as a checked checkbox
-               &:checked + label::before {
+               &:checked + label:before {
                        .background-size( 100%, 100% );
                }
 
-               &:active + label::before {
+               &:active + label:before {
                        background-color: @colorGray13;
                        border-color: @colorGray13;
                }
 
-               &:focus + label::before {
+               &:focus + label:before {
                        border-width: 2px;
                }
 
-               &:focus:hover + label::before,
-               &:hover + label::before {
+               &:focus:hover + label:before,
+               &:hover + label:before {
                        border-bottom-width: 3px;
                }
 
                // disabled checkboxes have a gray background
-               &:disabled + label::before {
+               &:disabled + label:before {
                        cursor: default;
                        background-color: @colorGray14;
                        border-color: @colorGray14;
                }
 
                // disabled and checked checkboxes have a white circle
-               &:disabled:checked + label::before {
+               &:disabled:checked + label:before {
                        .background-image-svg( 'images/checked_disabled.svg', 'images/checked_disabled.png' );
                }
        }
index 2327efc..d3c76d0 100644 (file)
@@ -1,8 +1,8 @@
 // Form elements and layouts
 
-@import "mediawiki.mixins";
-@import "mediawiki.ui/variables";
-@import "mediawiki.ui/mixins";
+@import 'mediawiki.mixins';
+@import 'mediawiki.ui/variables';
+@import 'mediawiki.ui/mixins';
 
 // --------------------------------------------------------------------------
 // Layouts
@@ -66,7 +66,7 @@
        }
 
        // Override input styling just for checkboxes and radio inputs.
-       input[type="radio"] {
+       input[type='radio'] {
                display: inline;
                .box-sizing( content-box );
                width: auto;
index efb04ae..f169d1b 100644 (file)
@@ -1,5 +1,5 @@
-@import "mediawiki.mixins";
-@import "mediawiki.ui/variables";
+@import 'mediawiki.mixins';
+@import 'mediawiki.ui/variables';
 
 // Mixins
 .mixin-mw-ui-icon-bgimage( @iconSvg, @iconPng ) {
index 21f5254..cc9c65a 100644 (file)
@@ -1,8 +1,8 @@
 // Inputs
 
-@import "mediawiki.mixins";
-@import "mediawiki.ui/variables";
-@import "mediawiki.ui/mixins";
+@import 'mediawiki.mixins';
+@import 'mediawiki.ui/variables';
+@import 'mediawiki.ui/mixins';
 
 // Text inputs
 //
        width: 100%;
        border: 1px solid @colorFieldBorder;
        border-radius: @borderRadius;
-       padding: 0.3em 0.3em 0.3em 0.6em;
+       padding: 0.625em 0.546875em 0.546875em;
        // necessary for smooth transition
        box-shadow: inset 0 0 0 0.1em #fff;
        font-family: inherit;
        font-size: inherit;
-       line-height: inherit;
+       line-height: 1.172em;
        vertical-align: middle;
 
        // Normalize & style placeholder text, see T139034
@@ -73,7 +73,7 @@
        }
 
        // Normalize styling for `<input type="search">`
-       &[type="search"] {
+       &[type='search'] {
                // Correct the odd appearance in Chrome and Safari 5
                -webkit-appearance: textfield;
 
@@ -103,7 +103,7 @@ textarea.mw-ui-input {
 // <button class="mw-ui-button mw-ui-progressive">Submit</button>
 //
 // Styleguide 1.2.
-input[type="number"],
+input[type='number'],
 .mw-ui-input-inline {
        display: inline-block;
        width: auto;
@@ -143,4 +143,5 @@ input.mw-ui-input-large {
        font-size: 1.75em;
        font-weight: bold;
        line-height: 1.25em;
+       padding: 0.3673em 0.3265em 0.3265em;
 }
index 7538ff4..7cb2849 100644 (file)
@@ -1,5 +1,5 @@
-@import "mediawiki.mixins";
-@import "mediawiki.ui/variables";
+@import 'mediawiki.mixins';
+@import 'mediawiki.ui/variables';
 
 // Radio
 //
@@ -48,7 +48,7 @@
                vertical-align: middle;
        }
 
-       input[type="radio"] {
+       input[type='radio'] {
                // we hide the input element as instead we will style the label that follows
                // we use opacity so that VoiceOver software can still identify it
                opacity: 0;
@@ -60,7 +60,7 @@
                margin-right: 0.4em;
 
                // the pseudo before element of the label after the radio now looks like a radio
-               & + label::before {
+               & + label:before {
                        content: '';
                        background-color: #fff;
                        .background-image-svg( 'images/radio_checked.svg', 'images/radio_checked.png' );
                }
 
                // when the input is checked, style the label pseudo before element that followed as a checked radio
-               &:checked + label::before {
+               &:checked + label:before {
                        .background-size( 100%, 100% );
                }
 
-               &:active + label::before {
+               &:active + label:before {
                        background-color: @colorGray13;
                        border-color: @colorGray13;
                }
 
-               &:focus + label::before {
+               &:focus + label:before {
                        border-width: 2px;
                }
 
-               &:focus:hover + label::before,
-               &:hover + label::before {
+               &:focus:hover + label:before,
+               &:hover + label:before {
                        border-bottom-width: 3px;
                }
 
                // disabled radios have a gray background
-               &:disabled + label::before {
+               &:disabled + label:before {
                        background-color: @colorGray14;
                        border-color: @colorGray14;
                        cursor: default;
                }
 
                // disabled and checked radios have a white circle
-               &:disabled:checked + label::before {
+               &:disabled:checked + label:before {
                        .background-image-svg( 'images/radio_disabled.svg', 'images/radio_disabled.png' );
                }
        }
index c0684d9..a07aa68 100644 (file)
@@ -1,6 +1,6 @@
-@import "mediawiki.mixins";
-@import "mediawiki.ui/variables";
-@import "mediawiki.ui/mixins";
+@import 'mediawiki.mixins';
+@import 'mediawiki.ui/variables';
+@import 'mediawiki.ui/mixins';
 
 /*
 Text & Anchors
index c9d6208..0589d39 100644 (file)
@@ -1,5 +1,5 @@
 /**
  * Provide Agora appearance for mw-ui-* classes.
  */
-@import "components/forms";
-@import "components/utilities";
+@import 'components/forms';
+@import 'components/utilities';
index b5b9cbe..093c58b 100644 (file)
@@ -1,5 +1,5 @@
 /* stylelint-disable no-duplicate-selectors */
-@import "mediawiki.widgets.datetime.definitions";
+@import 'mediawiki.widgets.datetime.definitions';
 
 .mw-widgets-datetime-calendarWidget {
        display: inline-block;
index 1c6c490..f205da3 100644 (file)
@@ -1,5 +1,5 @@
 /* stylelint-disable no-duplicate-selectors */
-@import "mediawiki.widgets.datetime.definitions";
+@import 'mediawiki.widgets.datetime.definitions';
 
 .mw-widgets-datetime-dateTimeInputWidget {
        display: inline-block;
index bdade36..fa45d5a 100644 (file)
@@ -25,7 +25,7 @@
 }
 
 .oo-ui-transition( @value1, @value2: X, ... ) {
-       @value: ~`"@{arguments}".replace(/[\[\]]|\,\sX/g, '')`; // stylelint-disable-line function-comma-space-after, function-parentheses-space-inside, function-whitespace-after
+       @value: ~`'@{arguments}'.replace(/[\[\]]|\,\sX/g, '')`; // stylelint-disable-line function-comma-space-after, function-parentheses-space-inside, function-whitespace-after, value-keyword-case
        -webkit-transition: @value;
        -moz-transition: @value;
        transition: @value;
index b929a5a..395f80b 100644 (file)
@@ -68,8 +68,8 @@
        }
 
        .mw-widget-calendarWidget-body:not( .mw-widget-calendarWidget-old-body ):first-child {
-               margin-top: -@calendarHeight;
-               margin-left: -@calendarWidth;
+               margin-top: -@calendarHeight; /* stylelint-disable-line value-keyword-case */
+               margin-left: -@calendarWidth; /* stylelint-disable-line value-keyword-case */
        }
 
        .mw-widget-calendarWidget-body:not( .mw-widget-calendarWidget-old-body ):last-child {
@@ -83,8 +83,8 @@
        height: @calendarHeight;
 
        .mw-widget-calendarWidget-body:first-child {
-               margin-top: 0 !important;
-               margin-left: 0 !important;
+               margin-top: 0 !important; /* stylelint-disable-line declaration-no-important */
+               margin-left: 0 !important; /* stylelint-disable-line declaration-no-important */
                .transition( margin-left 500ms );
        }
 }
@@ -94,8 +94,8 @@
        height: @calendarHeight;
 
        .mw-widget-calendarWidget-body:first-child {
-               margin-left: -@calendarWidth !important;
-               margin-top: 0 !important;
+               margin-left: -@calendarWidth !important; /* stylelint-disable-line value-keyword-case, declaration-no-important */
+               margin-top: 0 !important; /* stylelint-disable-line declaration-no-important */
                .transition( margin-left 500ms );
        }
 }
        }
 
        .mw-widget-calendarWidget-body:first-child {
-               margin-left: 0 !important;
-               margin-top: 0 !important;
+               margin-left: 0 !important; /* stylelint-disable-line declaration-no-important */
+               margin-top: 0 !important; /* stylelint-disable-line declaration-no-important */
                .transition( margin-top 500ms );
        }
 }
        }
 
        .mw-widget-calendarWidget-body:first-child {
-               margin-left: 0 !important;
-               margin-top: -@calendarHeight !important;
+               margin-left: 0 !important; /* stylelint-disable-line declaration-no-important */
+               margin-top: -@calendarHeight !important; /* stylelint-disable-line value-keyword-case, declaration-no-important */
                .transition( margin-top 500ms );
        }
 }
index a53e863..a36b379 100644 (file)
@@ -26,7 +26,7 @@ table.mw-htmlform-nolabel td.mw-label {
 }
 
 tr.mw-htmlform-vertical-label td.mw-label {
-       text-align: left !important;
+       text-align: left !important; /* stylelint-disable-line declaration-no-important */
 }
 
 .mw-icon-question {
index af9eb36..f93df3c 100644 (file)
@@ -115,6 +115,6 @@ td.diff-deletedline .diffchange {
 .diff-otitle,
 .diff-ntitle,
 .diff-lineno {
-       direction: ltr !important;
+       direction: ltr !important; /* stylelint-disable-line declaration-no-important */
        unicode-bidi: embed;
 }
index 89efae3..2c3e137 100644 (file)
@@ -1,4 +1,4 @@
-@import "mediawiki.ui/variables";
+@import 'mediawiki.ui/variables';
 
 .mediawiki-filewarning {
        visibility: hidden;
index dd6bf74..4eed90a 100644 (file)
@@ -1,4 +1,4 @@
-@import "mediawiki.mixins";
+@import 'mediawiki.mixins';
 
 #mw-indicator-mw-helplink a {
        .background-image-svg('images/help.svg', 'images/help.png');
index 5a37f45..9c7064f 100644 (file)
 }
 /* Generate interpuncts */
 .hlist dt:after {
-       content: ":";
+       content: ':';
 }
 .hlist dd:after,
 .hlist li:after {
-       content: " ·";
+       content: ' ·';
        font-weight: bold;
 }
 .hlist dd:last-child:after,
@@ -57,7 +57,7 @@
 .hlist li dd:first-child:before,
 .hlist li dt:first-child:before,
 .hlist li li:first-child:before {
-       content: "(";
+       content: '(';
        font-weight: normal;
 }
 .hlist dd dd:last-child:after,
@@ -69,7 +69,7 @@
 .hlist li dd:last-child:after,
 .hlist li dt:last-child:after,
 .hlist li li:last-child:after {
-       content: ")";
+       content: ')';
        font-weight: normal;
 }
 /* For IE8 */
@@ -82,7 +82,7 @@
 .hlist li dd.hlist-last-child:after,
 .hlist li dt.hlist-last-child:after,
 .hlist li li.hlist-last-child:after {
-       content: ")";
+       content: ')';
        font-weight: normal;
 }
 /* Put ordinals in front of ordered list items */
        counter-increment: list-item;
 }
 .hlist ol > li:before {
-       content: counter( list-item ) " ";
+       content: counter( list-item ) ' ';
 }
 .hlist dd ol > li:first-child:before,
 .hlist dt ol > li:first-child:before,
 .hlist li ol > li:first-child:before {
-       content: "(" counter( list-item ) " ";
+       content: '(' counter( list-item ) ' ';
 }
index 49f0f70..c692538 100644 (file)
@@ -1,6 +1,6 @@
 /* General-purpose icons via CSS. Classes here should be named "mw-icon-*". */
 
-@import "mediawiki.mixins";
+@import 'mediawiki.mixins';
 
 /* For the collapsed and expanded arrows, we also provide selectors to make it
  * easy to use them with jquery.makeCollapsible. */
index fdaa989..5c2f83f 100644 (file)
                 */
                getModuleSize: function ( moduleName ) {
                        var module = mw.loader.moduleRegistry[ moduleName ],
-                               payload = 0;
+                               args, i, size;
 
-                       if ( mw.loader.getState( moduleName ) !== 'ready' ) {
+                       if ( module.state !== 'ready' ) {
                                return null;
                        }
 
                        if ( !module.style && !module.script ) {
-                               return null;
+                               return 0;
                        }
 
-                       // Tally CSS
-                       if ( module.style && $.isArray( module.style.css ) ) {
-                               $.each( module.style.css, function ( i, stylesheet ) {
-                                       payload += $.byteLength( stylesheet );
-                               } );
+                       function getFunctionBody( func ) {
+                               return String( func )
+                                       // To ensure a deterministic result, replace the start of the function
+                                       // declaration with a fixed string. For example, in Chrome 55, it seems
+                                       // V8 seemingly-at-random decides to sometimes put a line break between
+                                       // the opening brace and first statement of the function body. T159751.
+                                       .replace( /^\s*function\s*\([^)]*\)\s*{\s*/, 'function(){' )
+                                       .replace( /\s*}\s*$/, '}' );
+                       }
+
+                       // Based on the load.php response for this module.
+                       // For example: `mw.loader.implement("example", function(){}, {"css":[".x{color:red}"]});`
+                       // @see mw.loader.store.set().
+                       args = [
+                               moduleName,
+                               module.script,
+                               module.style,
+                               module.messages,
+                               module.templates
+                       ];
+                       // Trim trailing null or empty object, as load.php would have done.
+                       // @see ResourceLoader::makeLoaderImplementScript and ResourceLoader::trimArray.
+                       i = args.length;
+                       while ( i-- ) {
+                               if ( args[ i ] === null || ( $.isPlainObject( args[ i ] ) && $.isEmptyObject( args[ i ] ) ) ) {
+                                       args.splice( i, 1 );
+                               } else {
+                                       break;
+                               }
                        }
 
-                       // Tally JavaScript
-                       if ( $.isFunction( module.script ) ) {
-                               payload += $.byteLength( module.script.toString() );
+                       size = 0;
+                       for ( i = 0; i < args.length; i++ ) {
+                               if ( typeof args[ i ] === 'function' ) {
+                                       size += $.byteLength( getFunctionBody( args[ i ] ) );
+                               } else {
+                                       size += $.byteLength( JSON.stringify( args[ i ] ) );
+                               }
                        }
 
-                       return payload;
+                       return size;
                },
 
                /**
index 7872818..33f146b 100644 (file)
@@ -52,6 +52,7 @@
                /* eslint-enable no-bitwise */
        }
 
+       // <https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Set>
        StringSet = window.Set || ( function () {
                /**
                 * @private
@@ -64,7 +65,7 @@
                        this.set[ value ] = true;
                };
                StringSet.prototype.has = function ( value ) {
-                       return this.set.hasOwnProperty( value );
+                       return hasOwn.call( this.set, value );
                };
                return StringSet;
        }() );
@@ -82,9 +83,8 @@
         *  copied in one direction only. Changes to globals do not reflect in the map.
         */
        function Map( global ) {
-               this.internalValues = {};
+               this.values = {};
                if ( global === true ) {
-
                        // Override #set to also set the global variable
                        this.set = function ( selection, value ) {
                                var s;
                                return false;
                        };
                }
-
-               // Deprecated since MediaWiki 1.28
-               log.deprecate(
-                       this,
-                       'values',
-                       this.internalValues,
-                       'mw.Map#values is deprecated. Use mw.Map#get() instead.',
-                       'Map-values'
-               );
        }
 
        /**
         * @param {Mixed} value
         */
        function setGlobalMapValue( map, key, value ) {
-               map.internalValues[ key ] = value;
+               map.values[ key ] = value;
                log.deprecate(
                                window,
                                key,
                 *
                 * @param {string|Array} [selection] Key or array of keys to retrieve values for.
                 * @param {Mixed} [fallback=null] Value for keys that don't exist.
-                * @return {Mixed|Object| null} If selection was a string, returns the value,
+                * @return {Mixed|Object|null} If selection was a string, returns the value,
                 *  If selection was an array, returns an object of key/values.
-                *  If no selection is passed, the internal container is returned. (Beware that,
-                *  as is the default in JavaScript, the object is returned by reference.)
+                *  If no selection is passed, a new object with all key/values is returned.
                 */
                get: function ( selection, fallback ) {
                        var results, i;
-                       // If we only do this in the `return` block, it'll fail for the
-                       // call to get() from the mutli-selection block.
                        fallback = arguments.length > 1 ? fallback : null;
 
                        if ( $.isArray( selection ) ) {
-                               selection = slice.call( selection );
                                results = {};
                                for ( i = 0; i < selection.length; i++ ) {
-                                       results[ selection[ i ] ] = this.get( selection[ i ], fallback );
+                                       if ( typeof selection[ i ] === 'string' ) {
+                                               results[ selection[ i ] ] = hasOwn.call( this.values, selection[ i ] ) ?
+                                                       this.values[ selection[ i ] ] :
+                                                       fallback;
+                                       }
                                }
                                return results;
                        }
 
                        if ( typeof selection === 'string' ) {
-                               if ( !hasOwn.call( this.internalValues, selection ) ) {
-                                       return fallback;
-                               }
-                               return this.internalValues[ selection ];
+                               return hasOwn.call( this.values, selection ) ?
+                                       this.values[ selection ] :
+                                       fallback;
                        }
 
                        if ( selection === undefined ) {
-                               return this.internalValues;
+                               results = {};
+                               for ( i in this.values ) {
+                                       results[ i ] = this.values[ i ];
+                               }
+                               return results;
                        }
 
                        // Invalid selection key
-                       return null;
+                       return fallback;
                },
 
                /**
 
                        if ( $.isPlainObject( selection ) ) {
                                for ( s in selection ) {
-                                       this.internalValues[ s ] = selection[ s ];
+                                       this.values[ s ] = selection[ s ];
                                }
                                return true;
                        }
                        if ( typeof selection === 'string' && arguments.length > 1 ) {
-                               this.internalValues[ selection ] = value;
+                               this.values[ selection ] = value;
                                return true;
                        }
                        return false;
                 * @return {boolean} True if the key(s) exist
                 */
                exists: function ( selection ) {
-                       var s;
-
+                       var i;
                        if ( $.isArray( selection ) ) {
-                               for ( s = 0; s < selection.length; s++ ) {
-                                       if ( typeof selection[ s ] !== 'string' || !hasOwn.call( this.internalValues, selection[ s ] ) ) {
+                               for ( i = 0; i < selection.length; i++ ) {
+                                       if ( typeof selection[ i ] !== 'string' || !hasOwn.call( this.values, selection[ i ] ) ) {
                                                return false;
                                        }
                                }
                                return true;
                        }
-                       return typeof selection === 'string' && hasOwn.call( this.internalValues, selection );
+                       return typeof selection === 'string' && hasOwn.call( this.values, selection );
                }
        };
 
index 822c814..216cd5a 100644 (file)
@@ -3,7 +3,7 @@
  * in MediaWiki (used e.g. on Special:ListFiles).
  */
 
-@import "mediawiki.mixins";
+@import 'mediawiki.mixins';
 
 .TablePager {
        min-width: 80%;
index d414232..6a6aa15 100644 (file)
         *  immediate execution after this amount of time (in milliseconds) if it didn't run
         *  by that time.
         */
-       mw.requestIdleCallback = mw.requestIdleCallbackInternal;
-       /*
-       // XXX: Polyfill disabled due to https://bugs.chromium.org/p/chromium/issues/detail?id=647870
-       mw.requestIdleCallback = window.requestIdleCallback
+       mw.requestIdleCallback = window.requestIdleCallback ?
                // Bind because it throws TypeError if context is not window
-               ? window.requestIdleCallback.bind( window )
-               : mw.requestIdleCallbackInternal;
-       */
+               window.requestIdleCallback.bind( window ) :
+               mw.requestIdleCallbackInternal;
+       // Note: Polyfill was previously disabled due to
+       // https://bugs.chromium.org/p/chromium/issues/detail?id=647870
+       // See also <http://codepen.io/Krinkle/full/XNGEvv>
 }( mediaWiki ) );
index 2e09392..95c77f8 100644 (file)
        };
 
        /**
-         * Set a value in device storage.
-         *
-         * @param {string} key Key name to store under
-         * @param {string} value Value to be stored
-         * @return {boolean} Whether the save succeeded or not
-         */
+        * Set a value in device storage.
+        *
+        * @param {string} key Key name to store under
+        * @param {string} value Value to be stored
+        * @return {boolean} Whether the save succeeded or not
+        */
        SafeStorage.prototype.set = function ( key, value ) {
                try {
                        this.store.setItem( key, value );
        };
 
        /**
-         * Remove a value from device storage.
-         *
-         * @param {string} key Key of item to remove
-         * @return {boolean} Whether the save succeeded or not
-         */
+        * Remove a value from device storage.
+        *
+        * @param {string} key Key of item to remove
+        * @return {boolean} Whether the save succeeded or not
+        */
        SafeStorage.prototype.remove = function ( key ) {
                try {
                        this.store.removeItem( key );
index c4c91f9..d1fa84a 100644 (file)
                },
 
                /**
-                * Get an automatically generated random ID (stored in a session cookie)
+                * Get an automatically generated random ID (persisted in sessionStorage)
                 *
-                * This ID is ephemeral for everyone, staying in their browser only until they close
-                * their browser.
+                * This ID is ephemeral for everyone, staying in their browser only until they
+                * close their browsing session.
                 *
                 * @return {string} Random session ID
                 */
                sessionId: function () {
-                       var sessionId = mw.cookie.get( 'mwuser-sessionId' );
-                       if ( sessionId === null ) {
+                       var sessionId = mw.storage.session.get( 'mwuser-sessionId' );
+                       if ( !sessionId ) {
                                sessionId = mw.user.generateRandomSessionId();
-                               mw.cookie.set( 'mwuser-sessionId', sessionId, { expires: null } );
+                               mw.storage.session.set( 'mwuser-sessionId', sessionId );
                        }
                        return sessionId;
                },
index 3cb8e9d..6e9ff0e 100644 (file)
@@ -89,7 +89,7 @@
 
        /**
         * @property {jQuery} $container If the gallery contained in an element that is
-        *      not the main content element, then it stores that element.
+        *   not the main content element, then it stores that element.
         */
 
        /**
 
        /**
         * @property {number} imageHeight Height of the image based on viewport size
-        *      the URLs in the required size.
+        *   the URLs in the required size.
         */
 
        /* Setup */
diff --git a/resources/src/polyfill-nodeTypes.js b/resources/src/polyfill-nodeTypes.js
deleted file mode 100644 (file)
index c8acc86..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Adds window.Node with node types according to:
- * https://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-1950641247
- */
-
-window.Node = window.Node || {
-       ELEMENT_NODE: 1,
-       ATTRIBUTE_NODE: 2,
-       TEXT_NODE: 3,
-       CDATA_SECTION_NODE: 4,
-       ENTITY_REFERENCE_NODE: 5,
-       ENTITY_NODE: 6,
-       PROCESSING_INSTRUCTION_NODE: 7,
-       COMMENT_NODE: 8,
-       DOCUMENT_NODE: 9,
-       DOCUMENT_TYPE_NODE: 10,
-       DOCUMENT_FRAGMENT_NODE: 11,
-       NOTATION_NODE: 12
-};
index 14a2d76..c13279e 100644 (file)
@@ -40,7 +40,7 @@ end
 
 Then(/^feedback should be (.+)$/) do |feedback|
   on(LoginPage) do |page|
-    page.feedback_element.when_present.click
+    page.feedback_element.click
     expect(page.feedback).to match Regexp.escape(feedback)
   end
 end
@@ -58,7 +58,7 @@ Then(/^Password element should be there$/) do
 end
 
 Then(/^there should be a link to (.+)$/) do |text|
-  expect(on(LoginPage).username_displayed_element.when_present.text).to eq text
+  expect(on(LoginPage).username_displayed_element.text).to eq text
 end
 
 Then(/^Username element should be there$/) do
index 8ffdaf1..b58f7a4 100644 (file)
@@ -1,5 +1,5 @@
 When(/^I click Appearance$/) do
-  visit(PreferencesPage).appearance_link_element.when_present.click
+  visit(PreferencesPage).appearance_link_element.click
 end
 
 When(/^I navigate to Preferences$/) do
index f691ffd..96dc491 100644 (file)
@@ -1,43 +1,43 @@
 When(/^I click Editing$/) do
-  visit(PreferencesPage).editing_link_element.when_present.click
+  visit(PreferencesPage).editing_link_element.click
 end
 
 Then(/^I can select edit area font style$/) do
-  expect(on(PreferencesEditingPage).edit_area_font_style_select_element.when_present).to exist
+  expect(on(PreferencesEditingPage).edit_area_font_style_select_element).to exist
 end
 
 Then(/^I can select live preview$/) do
-  expect(on(PreferencesEditingPage).live_preview_check_element.when_present).to exist
+  expect(on(PreferencesEditingPage).live_preview_check_element).to exist
 end
 
 Then(/^I can select section editing by double clicking$/) do
-  expect(on(PreferencesEditingPage).edit_section_double_click_check_element.when_present).to exist
+  expect(on(PreferencesEditingPage).edit_section_double_click_check_element).to exist
 end
 
 Then(/^I can select section editing by right clicking$/) do
-  expect(on(PreferencesEditingPage).edit_section_right_click_check_element.when_present).to exist
+  expect(on(PreferencesEditingPage).edit_section_right_click_check_element).to exist
 end
 
 Then(/^I can select section editing via edit links$/) do
-  expect(on(PreferencesEditingPage).edit_section_edit_link_element.when_present).to exist
+  expect(on(PreferencesEditingPage).edit_section_edit_link_element).to exist
 end
 
 Then(/^I can select show edit toolbar$/) do
-  expect(on(PreferencesEditingPage).show_edit_toolbar_check_element.when_present).to exist
+  expect(on(PreferencesEditingPage).show_edit_toolbar_check_element).to exist
 end
 
 Then(/^I can select show preview before edit box$/) do
-  expect(on(PreferencesEditingPage).preview_on_top_check_element.when_present).to exist
+  expect(on(PreferencesEditingPage).preview_on_top_check_element).to exist
 end
 
 Then(/^I can select show preview on first edit$/) do
-  expect(on(PreferencesEditingPage).preview_on_first_check_element.when_present).to exist
+  expect(on(PreferencesEditingPage).preview_on_first_check_element).to exist
 end
 
 Then(/^I can select to prompt me when entering a blank edit summary$/) do
-  expect(on(PreferencesEditingPage).forced_edit_summary_check_element.when_present).to exist
+  expect(on(PreferencesEditingPage).forced_edit_summary_check_element).to exist
 end
 
 Then(/^I can select to warn me when I leave an edit page with unsaved changes$/) do
-  expect(on(PreferencesEditingPage).unsaved_changes_check_element.when_present).to exist
+  expect(on(PreferencesEditingPage).unsaved_changes_check_element).to exist
 end
index 5660d49..6d28ce5 100644 (file)
@@ -1,5 +1,5 @@
 When(/^I click User profile$/) do
-  visit(PreferencesPage).user_profile_link_element.when_present.click
+  visit(PreferencesPage).user_profile_link_element.click
 end
 
 Then(/^I can change my gender$/) do
index c119b38..32fc2bb 100644 (file)
@@ -3,28 +3,7 @@ require 'page-object'
 class LoginPage
   include PageObject
 
-  page_url 'Special:UserLogin'
-
   element(:error_message, css: 'div#userloginForm div.error')
-  div(:feedback, class: 'errorbox')
-  button(:login, id: 'wpLoginAttempt')
-  li(:logout, id: 'pt-logout')
-  text_field(:password, id: 'wpPassword1')
   element(:password_error, css: 'input#wpPassword1:required:invalid')
-  a(:password_strength, text: 'password strength')
-  a(:phishing, text: 'phishing')
-  text_field(:username, id: 'wpName1')
-  a(:username_displayed, title: /Your user page/)
   element(:username_error, css: 'input#wpName1:required:invalid')
-
-  def logged_in_as_element
-    @browser.div(id: 'mw-content-text').p.b
-  end
-
-  def login_with(username, password, wait_for_logout_element = true)
-    username_element.when_present.send_keys(username)
-    password_element.when_present.send_keys(password)
-    login_element.when_present.click
-    logout_element.when_present(10) if wait_for_logout_element
-  end
 end
index 7edde2a..35c2480 100644 (file)
@@ -974,10 +974,9 @@ class ParserTestRunner {
                        'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ),
                        'wgLanguageCode' => $langCode,
                        'wgRawHtml' => self::getOptionValue( 'wgRawHtml', $opts, false ),
-                       'wgNamespacesWithSubpages' => [
-                               0 => isset( $opts['subpage'] ),
-                               2 => isset( $opts['subpage'] ),
-                       ],
+                       'wgNamespacesWithSubpages' => array_fill_keys(
+                               MWNamespace::getValidNamespaces(), isset( $opts['subpage'] )
+                       ),
                        'wgMaxTocLevel' => $maxtoclevel,
                        'wgAllowExternalImages' => self::getOptionValue( 'wgAllowExternalImages', $opts, true ),
                        'wgThumbLimits' => [ self::getOptionValue( 'thumbsize', $opts, 180 ) ],
index a48087e..50d1bc9 100644 (file)
Binary files a/tests/parser/extraParserTests.txt and b/tests/parser/extraParserTests.txt differ
index 074fab0..106ab68 100644 (file)
@@ -86,9 +86,12 @@ if ( defined( 'MW_CONFIG_CALLBACK' ) ) {
 }
 
 if ( $maintenance->getDbType() === Maintenance::DB_NONE ) {
-       if ( $wgLocalisationCacheConf['storeClass'] === false
-                && ( $wgLocalisationCacheConf['store'] == 'db'
-                         || ( $wgLocalisationCacheConf['store'] == 'detect' && !$wgCacheDirectory ) )
+       if (
+               $wgLocalisationCacheConf['storeClass'] === false
+               && (
+                       $wgLocalisationCacheConf['store'] == 'db'
+                       || ( $wgLocalisationCacheConf['store'] == 'detect' && !$wgCacheDirectory )
+               )
        ) {
                $wgLocalisationCacheConf['storeClass'] = 'LCStoreNull';
        }
index 092d57b..5977652 100644 (file)
@@ -161,7 +161,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
        public function testExists() {
                // Remove the following lines when you implement this test.
                $this->markTestIncomplete(
-                 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
+                       'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
                );
        }
        */
@@ -223,7 +223,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
        public function testGetCanonicalNamespaces() {
                // Remove the following lines when you implement this test.
                $this->markTestIncomplete(
-                 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
+                       'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
                );
        }
        */
@@ -234,7 +234,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
                public function testGetCanonicalName() {
                        // Remove the following lines when you implement this test.
                        $this->markTestIncomplete(
-                         'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
+                               'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
                        );
                }
        */
@@ -245,7 +245,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
        public function testGetCanonicalIndex() {
                // Remove the following lines when you implement this test.
                $this->markTestIncomplete(
-                 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
+                       'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
                );
        }
        */
@@ -257,7 +257,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
        public function testGetValidNamespaces() {
                // Remove the following lines when you implement this test.
                $this->markTestIncomplete(
-                 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
+                       'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
                );
        }
        */
index 2694b85..424218e 100644 (file)
@@ -315,14 +315,14 @@ class MessageTest extends MediaWikiLangTestCase {
                return [
                        [ '<span>foo</span>', 'parse', '<span>foo</span>', '<span>foo</span>' ],
                        [ '<span>foo</span>', 'escaped', '&lt;span&gt;foo&lt;/span&gt;',
-                         '<span>foo</span>' ],
+                               '<span>foo</span>' ],
                        [ '<span>foo</span>', 'plain', '<span>foo</span>', '<span>foo</span>' ],
                        [ '<script>alert(1)</script>', 'parse', '&lt;script&gt;alert(1)&lt;/script&gt;',
                                '&lt;script&gt;alert(1)&lt;/script&gt;' ],
                        [ '<script>alert(1)</script>', 'escaped', '&lt;script&gt;alert(1)&lt;/script&gt;',
                                '&lt;script&gt;alert(1)&lt;/script&gt;' ],
                        [ '<script>alert(1)</script>', 'plain', '<script>alert(1)</script>',
-                         '&lt;script&gt;alert(1)&lt;/script&gt;' ],
+                               '&lt;script&gt;alert(1)&lt;/script&gt;' ],
                ];
        }
 
index ae66253..a3d1dda 100644 (file)
@@ -434,8 +434,13 @@ class ContentHandlerTest extends MediaWikiTestCase {
                $page = new WikiPage( $title );
 
                $this->setTemporaryHook( 'SearchDataForIndex',
-                       function ( &$fields, ContentHandler $handler, WikiPage $page, ParserOutput $output,
-                                          SearchEngine $engine ) {
+                       function (
+                               &$fields,
+                               ContentHandler $handler,
+                               WikiPage $page,
+                               ParserOutput $output,
+                               SearchEngine $engine
+                       ) {
                                $fields['testDataField'] = 'test content';
                        } );
 
index 4b857ce..8b285cb 100644 (file)
@@ -157,12 +157,12 @@ class LBFactoryTest extends MediaWikiTestCase {
                                ],
                        ],
                        'serverTemplate' => [
-                               'dbname'          => $wgDBname,
-                               'user'            => $wgDBuser,
-                               'password'        => $wgDBpassword,
-                               'type'            => $wgDBtype,
+                               'dbname'      => $wgDBname,
+                               'user'        => $wgDBuser,
+                               'password'    => $wgDBpassword,
+                               'type'        => $wgDBtype,
                                'dbDirectory' => $wgSQLiteDataDir,
-                               'flags'           => DBO_DEFAULT
+                               'flags'       => DBO_DEFAULT
                        ],
                        'hostsByName' => [
                                'test-db1'  => $wgDBserver,
index 4227693..d7ad1d1 100644 (file)
@@ -1,6 +1,40 @@
 <?php
 
 class DeferredUpdatesTest extends MediaWikiTestCase {
+
+       /**
+        * @covers DeferredUpdates::getPendingUpdates
+        */
+       public function testGetPendingUpdates() {
+               # Prevent updates from running
+               $this->setMwGlobals( 'wgCommandLineMode', false );
+
+               $pre = DeferredUpdates::PRESEND;
+               $post = DeferredUpdates::POSTSEND;
+               $all = DeferredUpdates::ALL;
+
+               $update = $this->getMockBuilder( 'DeferrableUpdate' )
+                             ->getMock();
+               $update->expects( $this->never() )
+                       ->method( 'doUpdate' );
+
+               DeferredUpdates::addUpdate( $update, $pre );
+               $this->assertCount( 1, DeferredUpdates::getPendingUpdates( $pre ) );
+               $this->assertCount( 0, DeferredUpdates::getPendingUpdates( $post ) );
+               $this->assertCount( 1, DeferredUpdates::getPendingUpdates( $all ) );
+               $this->assertCount( 1, DeferredUpdates::getPendingUpdates() );
+               DeferredUpdates::clearPendingUpdates();
+               $this->assertCount( 0, DeferredUpdates::getPendingUpdates() );
+
+               DeferredUpdates::addUpdate( $update, $post );
+               $this->assertCount( 0, DeferredUpdates::getPendingUpdates( $pre ) );
+               $this->assertCount( 1, DeferredUpdates::getPendingUpdates( $post ) );
+               $this->assertCount( 1, DeferredUpdates::getPendingUpdates( $all ) );
+               $this->assertCount( 1, DeferredUpdates::getPendingUpdates() );
+               DeferredUpdates::clearPendingUpdates();
+               $this->assertCount( 0, DeferredUpdates::getPendingUpdates() );
+       }
+
        public function testDoUpdatesWeb() {
                $this->setMwGlobals( 'wgCommandLineMode', false );
 
index a598d13..036baa8 100644 (file)
@@ -483,7 +483,7 @@ class HttpTest extends MediaWikiTestCase {
         * Added this test based on an issue experienced with HHVM 3.3.0-dev
         * where it did not define a cURL constant.
         *
-        * @T72570
+        * T72570
         * @dataProvider provideCurlConstants
         */
        public function testCurlConstants( $value ) {
diff --git a/tests/phpunit/includes/libs/time/ConvertibleTimestampTest.php b/tests/phpunit/includes/libs/time/ConvertibleTimestampTest.php
deleted file mode 100644 (file)
index d48caf3..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-<?php
-
-/**
- * Tests timestamp parsing and output.
- */
-class ConvertibleTimestampTest extends PHPUnit_Framework_TestCase {
-       /**
-        * @covers ConvertibleTimestamp::__construct
-        */
-       public function testConstructWithNoTimestamp() {
-               $timestamp = new ConvertibleTimestamp();
-               $this->assertInternalType( 'string', $timestamp->getTimestamp() );
-               $this->assertNotEmpty( $timestamp->getTimestamp() );
-               $this->assertNotEquals( false, strtotime( $timestamp->getTimestamp( TS_MW ) ) );
-       }
-
-       /**
-        * @covers ConvertibleTimestamp::__toString
-        */
-       public function testToString() {
-               $timestamp = new ConvertibleTimestamp( '1406833268' ); // Equivalent to 20140731190108
-               $this->assertEquals( '1406833268', $timestamp->__toString() );
-       }
-
-       public static function provideValidTimestampDifferences() {
-               return [
-                       [ '1406833268', '1406833269', '00 00 00 01' ],
-                       [ '1406833268', '1406833329', '00 00 01 01' ],
-                       [ '1406833268', '1406836929', '00 01 01 01' ],
-                       [ '1406833268', '1406923329', '01 01 01 01' ],
-               ];
-       }
-
-       /**
-        * @dataProvider provideValidTimestampDifferences
-        * @covers ConvertibleTimestamp::diff
-        */
-       public function testDiff( $timestamp1, $timestamp2, $expected ) {
-               $timestamp1 = new ConvertibleTimestamp( $timestamp1 );
-               $timestamp2 = new ConvertibleTimestamp( $timestamp2 );
-               $diff = $timestamp1->diff( $timestamp2 );
-               $this->assertEquals( $expected, $diff->format( '%D %H %I %S' ) );
-       }
-
-       /**
-        * Test parsing of valid timestamps and outputing to MW format.
-        * @dataProvider provideValidTimestamps
-        * @covers ConvertibleTimestamp::getTimestamp
-        */
-       public function testValidParse( $format, $original, $expected ) {
-               $timestamp = new ConvertibleTimestamp( $original );
-               $this->assertEquals( $expected, $timestamp->getTimestamp( TS_MW ) );
-       }
-
-       /**
-        * Test outputting valid timestamps to different formats.
-        * @dataProvider provideValidTimestamps
-        * @covers ConvertibleTimestamp::getTimestamp
-        */
-       public function testValidOutput( $format, $expected, $original ) {
-               $timestamp = new ConvertibleTimestamp( $original );
-               $this->assertEquals( $expected, (string)$timestamp->getTimestamp( $format ) );
-       }
-
-       /**
-        * Test an invalid timestamp.
-        * @expectedException TimestampException
-        * @covers ConvertibleTimestamp
-        */
-       public function testInvalidParse() {
-               new ConvertibleTimestamp( "This is not a timestamp." );
-       }
-
-       /**
-        * @dataProvider provideValidTimestamps
-        * @covers ConvertibleTimestamp::convert
-        */
-       public function testConvert( $format, $expected, $original ) {
-               $this->assertSame( $expected, ConvertibleTimestamp::convert( $format, $original ) );
-       }
-
-       /**
-        * Format an invalid timestamp.
-        * @covers ConvertibleTimestamp::convert
-        */
-       public function testConvertInvalid() {
-               $this->assertSame( false, ConvertibleTimestamp::convert( 'Not a timestamp', 0 ) );
-       }
-
-       /**
-        * Test an out of range timestamp
-        * @dataProvider provideOutOfRangeTimestamps
-        * @expectedException TimestampException
-        * @covers       ConvertibleTimestamp
-        */
-       public function testOutOfRangeTimestamps( $format, $input ) {
-               $timestamp = new ConvertibleTimestamp( $input );
-               $timestamp->getTimestamp( $format );
-       }
-
-       /**
-        * Test requesting an invalid output format.
-        * @expectedException TimestampException
-        * @covers ConvertibleTimestamp::getTimestamp
-        */
-       public function testInvalidOutput() {
-               $timestamp = new ConvertibleTimestamp( '1343761268' );
-               $timestamp->getTimestamp( 98 );
-       }
-
-       /**
-        * Returns a list of valid timestamps in the format:
-        * [ type, timestamp_of_type, timestamp_in_MW ]
-        */
-       public static function provideValidTimestamps() {
-               return [
-                       // Various formats
-                       [ TS_UNIX, '1343761268', '20120731190108' ],
-                       [ TS_MW, '20120731190108', '20120731190108' ],
-                       [ TS_DB, '2012-07-31 19:01:08', '20120731190108' ],
-                       [ TS_ISO_8601, '2012-07-31T19:01:08Z', '20120731190108' ],
-                       [ TS_ISO_8601_BASIC, '20120731T190108Z', '20120731190108' ],
-                       [ TS_EXIF, '2012:07:31 19:01:08', '20120731190108' ],
-                       [ TS_RFC2822, 'Tue, 31 Jul 2012 19:01:08 GMT', '20120731190108' ],
-                       [ TS_ORACLE, '31-07-2012 19:01:08.000000', '20120731190108' ],
-                       [ TS_POSTGRES, '2012-07-31 19:01:08 GMT', '20120731190108' ],
-                       // Some extremes and weird values
-                       [ TS_ISO_8601, '9999-12-31T23:59:59Z', '99991231235959' ],
-                       [ TS_UNIX, '-62135596801', '00001231235959' ]
-               ];
-       }
-
-       /**
-        * Returns a list of out of range timestamps in the format:
-        * [ type, timestamp_of_type ]
-        */
-       public static function provideOutOfRangeTimestamps() {
-               return [
-                       // Various formats
-                       [ TS_MW, '-62167219201' ], // -0001-12-31T23:59:59Z
-                       [ TS_MW, '253402300800' ], // 10000-01-01T00:00:00Z
-               ];
-       }
-}
index ebeb109..f722fe1 100644 (file)
@@ -27,7 +27,7 @@ class RESTBagOStuffTest extends MediaWikiTestCase {
                $this->client->expects( $this->once() )->method( 'run' )->with( [
                        'method' => 'GET',
                        'url' => 'http://test/rest/42xyz42'
-                   // list( $rcode, $rdesc, $rhdrs, $rbody, $rerr )
+                       // list( $rcode, $rdesc, $rhdrs, $rbody, $rerr )
                ] )->willReturn( [ 200, 'OK', [], 's:8:"somedata";', 0 ] );
                $result = $this->bag->get( '42xyz42' );
                $this->assertEquals( 'somedata', $result );
@@ -69,7 +69,7 @@ class RESTBagOStuffTest extends MediaWikiTestCase {
                $this->client->expects( $this->once() )->method( 'run' )->with( [
                        'method' => 'PUT',
                        'url' => 'http://test/rest/42xyz42',
-                   'body' => 's:8:"postdata";'
+                       'body' => 's:8:"postdata";'
                        // list( $rcode, $rdesc, $rhdrs, $rbody, $rerr )
                ] )->willReturn( [ 200, 'OK', [], 'Done', 0 ] );
                $result = $this->bag->set( '42xyz42', 'postdata' );
index 5e00384..ae58d1c 100644 (file)
@@ -2,8 +2,8 @@
 
 /**
  * @group Database
+ * @covers Parser
  */
-
 class ParserMethodsTest extends MediaWikiLangTestCase {
 
        public static function providePreSaveTransform() {
@@ -19,7 +19,6 @@ class ParserMethodsTest extends MediaWikiLangTestCase {
 
        /**
         * @dataProvider providePreSaveTransform
-        * @covers Parser::preSaveTransform
         */
        public function testPreSaveTransform( $text, $expected ) {
                global $wgParser;
@@ -63,7 +62,6 @@ class ParserMethodsTest extends MediaWikiLangTestCase {
 
        /**
         * @dataProvider provideStripOuterParagraph
-        * @covers Parser::stripOuterParagraph
         */
        public function testStripOuterParagraph( $text, $expected ) {
                $this->assertEquals( $expected, Parser::stripOuterParagraph( $text ) );
@@ -73,7 +71,6 @@ class ParserMethodsTest extends MediaWikiLangTestCase {
         * @expectedException MWException
         * @expectedExceptionMessage Parser state cleared while parsing.
         *  Did you call Parser::parse recursively?
-        * @covers Parser::lock
         */
        public function testRecursiveParse() {
                global $wgParser;
@@ -90,9 +87,6 @@ class ParserMethodsTest extends MediaWikiLangTestCase {
                return 'bar';
        }
 
-       /**
-        * @covers Parser::callParserFunction
-        */
        public function testCallParserFunction() {
                global $wgParser;
 
@@ -111,7 +105,7 @@ class ParserMethodsTest extends MediaWikiLangTestCase {
        }
 
        /**
-        * @covers Parser::parse
+        * @covers Parser
         * @covers ParserOutput::getSections
         */
        public function testGetSections() {
@@ -155,8 +149,6 @@ class ParserMethodsTest extends MediaWikiLangTestCase {
 
        /**
         * @dataProvider provideNormalizeLinkUrl
-        * @covers Parser::normalizeLinkUrl
-        * @covers Parser::normalizeUrlComponent
         */
        public function testNormalizeLinkUrl( $explanation, $url, $expected ) {
                $this->assertEquals( $expected, Parser::normalizeLinkUrl( $url ), $explanation );
index 414ab8f..7707395 100644 (file)
@@ -2,6 +2,30 @@
 /**
  * Basic tests for Parser::getPreloadText
  * @author Antoine Musso
+ *
+ * @covers Parser
+ * @covers StripState
+ *
+ * @covers Preprocessor_DOM
+ * @covers PPDStack
+ * @covers PPDStackElement
+ * @covers PPDPart
+ * @covers PPFrame_DOM
+ * @covers PPTemplateFrame_DOM
+ * @covers PPCustomFrame_DOM
+ * @covers PPNode_DOM
+ *
+ * @covers Preprocessor_Hash
+ * @covers PPDStack_Hash
+ * @covers PPDStackElement_Hash
+ * @covers PPDPart_Hash
+ * @covers PPFrame_Hash
+ * @covers PPTemplateFrame_Hash
+ * @covers PPCustomFrame_Hash
+ * @covers PPNode_Hash_Tree
+ * @covers PPNode_Hash_Text
+ * @covers PPNode_Hash_Array
+ * @covers PPNode_Hash_Attr
  */
 class ParserPreloadTest extends MediaWikiTestCase {
        /**
@@ -37,16 +61,10 @@ class ParserPreloadTest extends MediaWikiTestCase {
                unset( $this->title );
        }
 
-       /**
-        * @covers Parser::getPreloadText
-        */
        public function testPreloadSimpleText() {
                $this->assertPreloaded( 'simple', 'simple' );
        }
 
-       /**
-        * @covers Parser::getPreloadText
-        */
        public function testPreloadedPreIsUnstripped() {
                $this->assertPreloaded(
                        '<pre>monospaced</pre>',
@@ -55,9 +73,6 @@ class ParserPreloadTest extends MediaWikiTestCase {
                );
        }
 
-       /**
-        * @covers Parser::getPreloadText
-        */
        public function testPreloadedNowikiIsUnstripped() {
                $this->assertPreloaded(
                        '<nowiki>[[Dummy title]]</nowiki>',
index 2a4a4ec..12936ee 100644 (file)
@@ -3,6 +3,30 @@
 /**
  * @group Database
  * @group Parser
+ *
+ * @covers Parser
+ * @covers StripState
+ *
+ * @covers Preprocessor_DOM
+ * @covers PPDStack
+ * @covers PPDStackElement
+ * @covers PPDPart
+ * @covers PPFrame_DOM
+ * @covers PPTemplateFrame_DOM
+ * @covers PPCustomFrame_DOM
+ * @covers PPNode_DOM
+ *
+ * @covers Preprocessor_Hash
+ * @covers PPDStack_Hash
+ * @covers PPDStackElement_Hash
+ * @covers PPDPart_Hash
+ * @covers PPFrame_Hash
+ * @covers PPTemplateFrame_Hash
+ * @covers PPCustomFrame_Hash
+ * @covers PPNode_Hash_Tree
+ * @covers PPNode_Hash_Text
+ * @covers PPNode_Hash_Array
+ * @covers PPNode_Hash_Attr
  */
 class TagHookTest extends MediaWikiTestCase {
        public static function provideValidNames() {
@@ -21,7 +45,6 @@ class TagHookTest extends MediaWikiTestCase {
 
        /**
         * @dataProvider provideValidNames
-        * @covers Parser::setHook
         */
        public function testTagHooks( $tag ) {
                global $wgParserConf, $wgContLang;
@@ -41,7 +64,6 @@ class TagHookTest extends MediaWikiTestCase {
        /**
         * @dataProvider provideBadNames
         * @expectedException MWException
-        * @covers Parser::setHook
         */
        public function testBadTagHooks( $tag ) {
                global $wgParserConf, $wgContLang;
@@ -58,7 +80,6 @@ class TagHookTest extends MediaWikiTestCase {
 
        /**
         * @dataProvider provideValidNames
-        * @covers Parser::setFunctionTagHook
         */
        public function testFunctionTagHooks( $tag ) {
                global $wgParserConf, $wgContLang;
@@ -78,7 +99,6 @@ class TagHookTest extends MediaWikiTestCase {
        /**
         * @dataProvider provideBadNames
         * @expectedException MWException
-        * @covers Parser::setFunctionTagHook
         */
        public function testBadFunctionTagHooks( $tag ) {
                global $wgParserConf, $wgContLang;
index ec046a7..9c10e49 100644 (file)
@@ -10,7 +10,7 @@ class SearchIndexFieldTest extends MediaWikiTestCase {
                return [
                        [ 0, 'test', 0, 'test', true ],
                        [ SearchIndexField::INDEX_TYPE_NESTED, 'test',
-                         SearchIndexField::INDEX_TYPE_NESTED, 'test', false ],
+                               SearchIndexField::INDEX_TYPE_NESTED, 'test', false ],
                        [ 0, 'test', 0, 'test2', true ],
                        [ 0, 'test', 1, 'test', false ],
                ];
index d93181c..8a4f662 100644 (file)
@@ -13,7 +13,12 @@ class BalancerTest extends MediaWikiTestCase {
        }
 
        /**
-        * @covers MediaWiki\Tidy\Balancer::balance
+        * @covers MediaWiki\Tidy\Balancer
+        * @covers MediaWiki\Tidy\BalanceSets
+        * @covers MediaWiki\Tidy\BalanceElement
+        * @covers MediaWiki\Tidy\BalanceStack
+        * @covers MediaWiki\Tidy\BalanceMarker
+        * @covers MediaWiki\Tidy\BalanceActiveFormattingElements
         * @dataProvider provideBalancerTests
         */
        public function testBalancer( $description, $input, $expected, $useTidy ) {
index 60d4e99..8b54b72 100644 (file)
@@ -45,7 +45,7 @@ class UIDGeneratorTest extends PHPUnit_Framework_TestCase {
                                $last_timestamp_bin,
                                $timestamp_bin,
                                "timestamp ($timestamp_bin) of current ID ($id_bin) >= timestamp ($last_timestamp_bin) " .
-                                 "of prior one ($lastId_bin)" );
+                                       "of prior one ($lastId_bin)" );
 
                        $hostbits_bin = substr( $id_bin, -$hostbits );
                        $last_hostbits_bin = substr( $lastId_bin, -$hostbits );
@@ -55,7 +55,7 @@ class UIDGeneratorTest extends PHPUnit_Framework_TestCase {
                                        $hostbits_bin,
                                        $last_hostbits_bin,
                                        "Host ID ($hostbits_bin) of current ID ($id_bin) is same as host ID ($last_hostbits_bin) " .
-                                         "of prior one ($lastId_bin)." );
+                                               "of prior one ($lastId_bin)." );
                        }
 
                        $lastId = $id;
index 11a25c4..7babcac 100644 (file)
@@ -35,8 +35,7 @@
                        <directory>structure</directory>
                        <file>suites/LessTestSuite.php</file>
                </testsuite>
-               <!-- As there is a class Maintenance, we cannot use the
-                    name "maintenance" directly -->
+               <!-- As there is a class Maintenance, we cannot use the name "maintenance" directly -->
                <testsuite name="maintenance_suite">
                        <directory>maintenance</directory>
                </testsuite>
index 1278ecb..6468646 100644 (file)
@@ -32,7 +32,6 @@ return [
                        'mediawiki.page.ready',
                        'mediawiki.page.startup',
                        'test.sinonjs',
-                       'dom-level2-shim',
                ],
                'position' => 'top',
                'targets' => [ 'desktop', 'mobile' ],
@@ -76,6 +75,7 @@ return [
                        'tests/qunit/suites/resources/mediawiki/mediawiki.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.html.test.js',
+                       'tests/qunit/suites/resources/mediawiki/mediawiki.inspect.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.toc.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.track.test.js',
@@ -94,6 +94,7 @@ return [
                        'tests/qunit/suites/resources/mediawiki.api/mediawiki.ForeignApi.test.js',
                        'tests/qunit/suites/resources/mediawiki.special/mediawiki.special.recentchanges.test.js',
                        'tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js',
+                       'tests/qunit/suites/resources/mediawiki.rcfilters/dm.FilterItem.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.language.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.cldr.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.cookie.test.js',
@@ -142,6 +143,7 @@ return [
                        'mediawiki.cldr',
                        'mediawiki.cookie',
                        'mediawiki.experiments',
+                       'mediawiki.inspect',
                        'test.mediawiki.qunit.testrunner',
                ],
        ]
diff --git a/tests/qunit/suites/resources/mediawiki.rcfilters/dm.FilterItem.test.js b/tests/qunit/suites/resources/mediawiki.rcfilters/dm.FilterItem.test.js
new file mode 100644 (file)
index 0000000..25ea988
--- /dev/null
@@ -0,0 +1,179 @@
+( function ( mw ) {
+       QUnit.module( 'mediawiki.rcfilters - FilterItem' );
+
+       QUnit.test( 'Initializing filter item', function ( assert ) {
+               var item,
+                       group1 = new mw.rcfilters.dm.FilterGroup( 'group1' );
+
+               item = new mw.rcfilters.dm.FilterItem( 'filter1', group1 );
+               assert.equal(
+                       item.getName(),
+                       'filter1',
+                       'Filter name is retained.'
+               );
+               assert.equal(
+                       item.getGroupName(),
+                       'group1',
+                       'Group name is retained.'
+               );
+
+               item = new mw.rcfilters.dm.FilterItem(
+                       'filter1',
+                       group1,
+                       {
+                               label: 'test label',
+                               description: 'test description'
+                       }
+               );
+               assert.equal(
+                       item.getLabel(),
+                       'test label',
+                       'Label information is retained.'
+               );
+               assert.equal(
+                       item.getLabel(),
+                       'test label',
+                       'Description information is retained.'
+               );
+
+               item = new mw.rcfilters.dm.FilterItem(
+                       'filter1',
+                       group1,
+                       {
+                               selected: true
+                       }
+               );
+               assert.equal(
+                       item.isSelected(),
+                       true,
+                       'Item can be selected in the config.'
+               );
+               item.toggleSelected( true );
+               assert.equal(
+                       item.isSelected(),
+                       true,
+                       'Item can toggle its selected state.'
+               );
+
+               // Subsets
+               item = new mw.rcfilters.dm.FilterItem(
+                       'filter1',
+                       group1,
+                       {
+                               subset: [ 'sub1', 'sub2', 'sub3' ]
+                       }
+               );
+               assert.deepEqual(
+                       item.getSubset(),
+                       [ 'sub1', 'sub2', 'sub3' ],
+                       'Subset information is retained.'
+               );
+               assert.equal(
+                       item.existsInSubset( 'sub1' ),
+                       true,
+                       'Specific item exists in subset.'
+               );
+               assert.equal(
+                       item.existsInSubset( 'sub10' ),
+                       false,
+                       'Specific item does not exists in subset.'
+               );
+               assert.equal(
+                       item.isIncluded(),
+                       false,
+                       'Initial state of "included" is false.'
+               );
+
+               item.toggleIncluded( true );
+               assert.equal(
+                       item.isIncluded(),
+                       true,
+                       'Item toggles its included state.'
+               );
+
+               // Conflicts
+               item = new mw.rcfilters.dm.FilterItem(
+                       'filter1',
+                       group1,
+                       {
+                               conflicts: [ 'conflict1', 'conflict2', 'conflict3' ]
+                       }
+               );
+               assert.deepEqual(
+                       item.getConflicts(),
+                       [ 'conflict1', 'conflict2', 'conflict3' ],
+                       'Conflict information is retained.'
+               );
+               assert.equal(
+                       // TODO: Consider allowing for either a FilterItem or a filter name
+                       // in this method, so it is consistent with the subset one
+                       item.existsInConflicts( new mw.rcfilters.dm.FilterItem( 'conflict1', group1 ) ),
+                       true,
+                       'Specific item exists in conflicts.'
+               );
+               assert.equal(
+                       item.existsInConflicts( new mw.rcfilters.dm.FilterItem( 'conflict10', group1 ) ),
+                       false,
+                       'Specific item does not exists in conflicts.'
+               );
+               assert.equal(
+                       item.isConflicted(),
+                       false,
+                       'Initial state of "conflicted" is false.'
+               );
+
+               item.toggleConflicted( true );
+               assert.equal(
+                       item.isConflicted(),
+                       true,
+                       'Item toggles its conflicted state.'
+               );
+
+               // Fully covered
+               item = new mw.rcfilters.dm.FilterItem( 'filter1', group1 );
+               assert.equal(
+                       item.isFullyCovered(),
+                       false,
+                       'Initial state of "full coverage" is false.'
+               );
+               item.toggleFullyCovered( true );
+               assert.equal(
+                       item.isFullyCovered(),
+                       true,
+                       'Item toggles its fully coverage state.'
+               );
+
+       } );
+
+       QUnit.test( 'Emitting events', function ( assert ) {
+               var group1 = new mw.rcfilters.dm.FilterGroup( 'group1' ),
+                       item = new mw.rcfilters.dm.FilterItem( 'filter1', group1 ),
+                       events = [];
+
+               // Listen to update events
+               item.on( 'update', function () {
+                       events.push( item.getState() );
+               } );
+
+               // Do stuff
+               item.toggleSelected( true ); // { selected: true, included: false, conflicted: false, fullyCovered: false }
+               item.toggleSelected( true ); // No event (duplicate state)
+               item.toggleIncluded( true ); // { selected: true, included: true, conflicted: false, fullyCovered: false }
+               item.toggleConflicted( true ); // { selected: true, included: true, conflicted: true, fullyCovered: false }
+               item.toggleFullyCovered( true ); // { selected: true, included: true, conflicted: true, fullyCovered: true }
+               item.toggleSelected(); // { selected: false, included: true, conflicted: true, fullyCovered: true }
+
+               // Check emitted events
+               assert.deepEqual(
+                       events,
+                       [
+                               { selected: true, included: false, conflicted: false, fullyCovered: false },
+                               { selected: true, included: true, conflicted: false, fullyCovered: false },
+                               { selected: true, included: true, conflicted: true, fullyCovered: false },
+                               { selected: true, included: true, conflicted: true, fullyCovered: true },
+                               { selected: false, included: true, conflicted: true, fullyCovered: true }
+                       ],
+                       'Events emitted successfully.'
+               );
+       } );
+}( mediaWiki ) );
diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.inspect.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.inspect.test.js
new file mode 100644 (file)
index 0000000..1f7a5ec
--- /dev/null
@@ -0,0 +1,74 @@
+( function ( mw ) {
+
+       QUnit.module( 'mediawiki.inspect' );
+
+       QUnit.test( '.getModuleSize() - scripts', function ( assert ) {
+               mw.loader.implement(
+                       'test.inspect.script',
+                       function () { 'example'; }
+               );
+
+               return mw.loader.using( 'test.inspect.script' ).then( function () {
+                       assert.equal(
+                               mw.inspect.getModuleSize( 'test.inspect.script' ),
+                               // name, script function
+                               43,
+                               'test.inspect.script'
+                       );
+               } );
+       } );
+
+       QUnit.test( '.getModuleSize() - scripts, styles', function ( assert ) {
+               mw.loader.implement(
+                       'test.inspect.both',
+                       function () { 'example'; },
+                       { css: [ '.example {}' ] }
+               );
+
+               return mw.loader.using( 'test.inspect.both' ).then( function () {
+                       assert.equal(
+                               mw.inspect.getModuleSize( 'test.inspect.both' ),
+                               // name, script function, styles object
+                               64,
+                               'test.inspect.both'
+                       );
+               } );
+       } );
+
+       QUnit.test( '.getModuleSize() - scripts, messages', function ( assert ) {
+               mw.loader.implement(
+                       'test.inspect.scriptmsg',
+                       function () { 'example'; },
+                       {},
+                       { example: 'Hello world.' }
+               );
+
+               return mw.loader.using( 'test.inspect.scriptmsg' ).then( function () {
+                       assert.equal(
+                               mw.inspect.getModuleSize( 'test.inspect.scriptmsg' ),
+                               // name, script function, empty styles object, messages object
+                               74,
+                               'test.inspect.scriptmsg'
+                       );
+               } );
+       } );
+
+       QUnit.test( '.getModuleSize() - scripts, styles, messages, templates', function ( assert ) {
+               mw.loader.implement(
+                       'test.inspect.all',
+                       function () { 'example'; },
+                       { css: [ '.example {}' ] },
+                       { example: 'Hello world.' },
+                       { 'example.html': '<p>Hello world.<p>' }
+               );
+
+               return mw.loader.using( 'test.inspect.all' ).then( function () {
+                       assert.equal(
+                               mw.inspect.getModuleSize( 'test.inspect.all' ),
+                               // name, script function, styles object, messages object, templates object
+                               126,
+                               'test.inspect.all'
+                       );
+               } );
+       } );
+}( mediaWiki ) );
index d3e73ae..119222a 100644 (file)
                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.get( funky ), null, 'Map.get ruturns null if selection was invalid (Function)' );
-               assert.strictEqual( conf.get( nummy ), null, 'Map.get ruturns null if selection was invalid (Number)' );
-
                conf.set( String( nummy ), 'I used to be a number' );
 
+               assert.strictEqual( conf.get( funky ), null, 'Map.get returns null if selection was invalid (Function)' );
+               assert.strictEqual( conf.get( nummy ), null, 'Map.get returns null if selection was invalid (Number)' );
+               assert.propEqual( conf.get( [ nummy ] ), {}, 'Map.get returns null if selection was invalid (multiple)' );
+               assert.strictEqual( conf.get( nummy, false ), false, 'Map.get returns custom fallback for invalid selection' );
+
                assert.strictEqual( conf.exists( 'doesNotExist' ), false, 'Map.exists where property does not exist' );
                assert.strictEqual( conf.exists( 'undef' ), true, 'Map.exists where value is `undefined`' );
-               assert.strictEqual( conf.exists( nummy ), false, 'Map.exists where key is invalid but looks like an existing key' );
+               assert.strictEqual( conf.exists( [ 'undef', 'example' ] ), true, 'Map.exists with multiple keys (all existing)' );
+               assert.strictEqual( conf.exists( [ 'example', 'doesNotExist' ] ), false, 'Map.exists with multiple keys (some non-existing)' );
+               assert.strictEqual( conf.exists( [] ), true, 'Map.exists with no keys' );
+               assert.strictEqual( conf.exists( nummy ), false, 'Map.exists with invalid key that looks like an existing key' );
+               assert.strictEqual( conf.exists( [ nummy ] ), false, 'Map.exists with invalid key that looks like an existing key' );
 
                // Multiple values at once
+               conf = new mw.Map();
                someValues = {
                        foo: 'bar',
                        lorem: 'ipsum',
                        notExist: null
                }, 'Map.get return includes keys that were not found as null values' );
 
-               // Interacting with globals and accessing the values object
-               this.suppressWarnings();
-               assert.strictEqual( conf.get(), conf.values, 'Map.get returns the entire values object by reference (if called without arguments)' );
-               this.restoreWarnings();
+               assert.propEqual( conf.values, someValues, 'Map.values is an internal object with all values (exposed for convenience)' );
+               assert.propEqual( conf.get(), someValues, 'Map.get() returns an object with all values' );
 
+               // Interacting with globals
                conf.set( 'globalMapChecker', 'Hi' );
 
                assert.ok( ( 'globalMapChecker' in window ) === false, 'Map does not its store values in the window object by default' );
index 7f6efa0..bc12642 100644 (file)
 
                result2 = mw.user.generateRandomSessionId();
                assert.notEqual( result, result2, 'different when called multiple times' );
+       } );
 
+       QUnit.test( 'sessionId', function ( assert ) {
+               var result = mw.user.sessionId(),
+                       result2 = mw.user.sessionId();
+               assert.equal( typeof result, 'string', 'type' );
+               assert.equal( $.trim( result ), result, 'no leading or trailing whitespace' );
+               assert.equal( result2, result, 'retained' );
        } );
 }( mediaWiki, jQuery ) );
index c38b89c..de201b9 100644 (file)
--- a/thumb.php
+++ b/thumb.php
@@ -272,7 +272,7 @@ function wfStreamThumb( array $params ) {
        // For 404 handled thumbnails, we only use the base name of the URI
        // for the thumb params and the parent directory for the source file name.
        // Check that the zone relative path matches up so squid caches won't pick
-       // up thumbs that would not be purged on source file deletion (bug 34231).
+       // up thumbs that would not be purged on source file deletion (T36231).
        if ( $rel404 !== null ) { // thumbnail was handled via 404
                if ( rawurldecode( $rel404 ) === $img->getThumbRel( $thumbName ) ) {
                        // Request for the canonical thumbnail name